像素滚动的过渡动画

最近更新了 Emacs 29,用上了 pixel-scroll-precision-mode。 我对这个模式有个疑问:用键盘滚动时,可以有类似与鼠标滚轮和触控板一样的过渡动画吗?

pixel-scroll-precision-scroll-uppixel-scroll-precision-scroll-down 确实可以像素级滚动,比如说向下滚半行,但是执行相应命令后,页面直接滚到相应位置,不像滚轮和触控板那样有中间过渡(即我标题里说的动画)。鼠标滚轮绑定到 pixel-scroll-precision,这个函数接收一个 event 作为参数,总不能为了这个过渡效果手动构造一个 event 吧 :joy: 。那么,还有其它更容易更直接的实现方法吗?

目前试着实现了像素翻页,感觉效果还可以:

(pixel-scroll-precision-mode 1)
(setq pixel-scroll-precision-interpolate-page t)
(defalias 'scroll-up-command 'pixel-scroll-interpolate-down)
(defalias 'scroll-down-command 'pixel-scroll-interpolate-up)

编辑1:确实写反了,已修改

编辑2: 由于 scroll 和 pixel-scroll-interpolate 两个函数的参数不一样,在其它函数调用 scroll-xx-command 时如果带了参数的话会报错。参看#4 #5

7 个赞

效果确实不错。之前没有注意到 pixel-scroll-interpolate-xxx 这两个函数,哈哈哈。

不过这两个函数的对应关系似乎应该是反的:

(defalias 'scroll-up-command 'pixel-scroll-interpolate-down)
(defalias 'scroll-down-command 'pixel-scroll-interpolate-up)

scroll-up-command 是将页面向上移动, 而 pixel-scroll-interpolate-up 是把可视范围向上移动, 两者应该是相反的动作。

效果很好。不过,有个小问题:scroll-other-windowscroll-other-window-down 两个函数不能正常工作了,会提示错误:scroll-other-window: Wrong number of arguments: (0 . 0), 1

以前都不知道有这个功能,之前用 alias 也只是图方便,没想到会影响到其它地方。 可以干脆将 C-vM-v 这两个翻页键绑定到 pixel-scroll-interpolate 上,或者用更 hack 的方法(编辑抄了 #6 的代码):

(pixel-scroll-precision-mode 1)
(setq pixel-scroll-precision-interpolate-page t)
(defun +pixel-scroll-interpolate-down (&optional lines)
  (interactive)
  (if lines
      (pixel-scroll-precision-interpolate (* -1 lines (pixel-line-height)))
    (pixel-scroll-interpolate-down)))

(defun +pixel-scroll-interpolate-up (&optional lines)
  (interactive)
  (if lines
      (pixel-scroll-precision-interpolate (* lines (pixel-line-height))))
  (pixel-scroll-interpolate-up))

(defalias 'scroll-up-command '+pixel-scroll-interpolate-down)
(defalias 'scroll-down-command '+pixel-scroll-interpolate-up)
9 个赞

原版的 scroll-up-commandscroll-downcommand 是有一个可选参数表示要滚动几行的,直接 alias 就没这个可选参数了。我写了一个简单的包装,试了一下应该能用:

(defun +my-scroll-up (&optional lines)
  (interactive)
  (if lines
      (pixel-scroll-precision-interpolate (* -1 lines (pixel-line-height)))
    (pixel-scroll-interpolate-up)))

(defun +my-scroll-down (&optional lines)
  (interactive)
  (if lines
      (pixel-scroll-precision-interpolate (* lines (pixel-line-height))))
  (pixel-scroll-interpolate-down))

话说本站的代码块里 Elisp 的名字是什么呀?我试了 elisp 和 emacs-lisp 都没有高亮

2 个赞

高亮我用的是 lisp

我感觉这楼应该设置成解决方案