orgmode inline image scrolling

这都2018年了,什么时候能把这个问题给解决了?

orgmode 有行内图片时滚动的时候真是一塌糊涂啊,图片一下消失,一下蹦出来,完全违反直觉啊。 用 mac port 的朋友说说你们是不是没有这个问题?

这个可以说是目前我使用 orgmode 时候最痛苦的一点了,其它的痛点都或多或少的解决了。唯独这个,不知道有生之年能不能解决了。

据说 ein 的行内图片使用 slice-image 把这个问题解决了,orgmode 中要是能解决就好了。

1赞

有一个像素模式什么的可以试试

试了,像素滚动,没有用。因为我用键盘移动的比较多。一个图片占一行,然后图片所在的行消失,整个图片就一下消失。唯一可能的解决办法就是图片占多行,或者用 slice-image

Mac port 版本的也有这个问题~

MacPort 用鼠标滚动没有问题,用键盘反而让我觉得反直觉。

可以写个 mac-mwheel-scroll 的 wrapper 函数,自己造个假的 event 参数传进去试试?

看 stack 上这个回答是不行:

跟滚动的关系都不大,根本原因是每一个图片占一行,如果每个图片根据图片大小占多行应该就没有这个问题了。

我之前脑洞的(部分)解决方案是用一个childframe来显示point上的图片 不过暂时没时间折腾。。

这样只能算是 workaround 吧,不过这样对 orgmode 的改动不大,导出什么的都不受影响。感觉 slice-image 可能会对导出产生影响。

最理想的情况应该是 Orgmode 的开发者或者 emacs 的开发者给出一个原生的解决方案。这个问题不解决 emacs 怎么可能成为理想的富文本编辑器?

诶。。同样是line-based scrolling iterm2就没这问题。。而且最近还支持了GPU rendering (Metal)。。

1赞

听说以后 macOS 要直接把 OpenCL 层去掉了,全要用 Metal

咱们能不能给 emacs 的维护者 Eli 再提一下,我觉得这个是一个非常重要的 feature。

为什么 mac 上这么多好东西,是不是因为很多开发者用 mac?

是指图片超过 window 高度的时候(光标在图片上),还是图片是小半张 window 高度,然后图片突然出现(这时光标不在图片上)?

感觉这个应该和 Org-mode 无关吧。

还有我想问一下行内图片是和同一行的文字都是居中对齐么,图片高度很大时会不会很丑?还是说一般行内大图片是独立成行的?

肯定会很丑,所以我都是采用图片独立成行的方式

image-modeimage-next-line 这样的命令,或许可以参考一下,原理是 set-window-vscroll

如光标在图片上时,向下滚动 n 行(应该先用 (/ (line-pixel-height) (default-line-height)) 做判断):

(set-window-vscroll nil (max 0 (+ (window-vscroll) n)))

感觉 next-line 涉及到的参数略多,不太容易改。

我用的 spacemacs,在 next-line 上再加上 org,evil 两层,感觉不太好办

这个思路确实不错,pdf-tools 里也确实能够滚动图片,但是放到 org 里实现起来可能不太容易。

应该是 emacs 的问题,但是 Eli 认为图片滚动没有问题,这我就不能理解了。也许他指的是 image-mode 的滚动?图文混排这种滚动还没有人提起过?

https://lists.gnu.org/archive/html/help-gnu-emacs/2014-02/msg00270.html

next-line 会调用函数 line-move,这个函数会强制 set-window-vscroll 设为 0,相当于白改了。而且最后一段也用到了 set-window-vscroll,用于 previous-line 时显示图片的尾部一行,但是条件有点苛刻。这些都要魔改掉,感觉不太清真,而且这函数里面的变量有点杂 :worried:

你发的这篇我再仔细研究一下

1赞

可能是指超高图片的滚动,auto-window-vscroll 为默认值时比较平滑?重现的步骤:

  1. runemacs -Q 并处理好 Org-mode 的加载
  2. 打开一个包含超高图片(图片高度大于 window 高度)的 org 文档
  3. M-xtoggle-truncate-linesRET,貌似 visual-line-mode 表现更好
  4. M-xorg-display-inline-imagesRET
  5. 频率不太高地 C-n next-line

遇到超高图片时,会进入图片,并设置为半屏,可以慢慢向上滚动。要等图片尾部到半屏时,才能跳出。但碰到中等图片(略小于 window 高度)还是会乱跳,大部分时候会跳到第一行,有时候跳到中间。

半屏的原因是 scroll-up-aggressively 值为 nil,0.5 屏,可以设置为 0.0。但是这么设置之后无法退出超高图片,我这里需要按住C-n不放,一段时间后才能让光标退出来,玄学特性?

(setq-default scroll-down-aggressively 0.0
              scroll-up-aggressively 0.0)

imagemagick 能不能解决中等图片乱跳的问题?你在 Linux 下用过么?效果是啥样的?

还有想问一下这几个变量的值你是怎么设置的(不同搭配好像有截然不同的效果):

  • scroll-margin 默认为 0
  • scroll-conservatively 默认为 0,这个感觉影响最大,文档也没怎么看懂
  • scroll-down-aggressivelyscroll-up-aggressively 默认都为 nil
  • scroll-step 默认为 0,好像没什么作用?
  • auto-window-vscroll 默认为 t,这个应该不会改吧

新发现: global-disable-point-adjustmentdisable-point-adjustment,但感觉没什么作用。

另外问一下你开 visual-line-mode 么?之前都用 toggle-truncate-lines

滚动相关的参数我设置如下

  (setq scroll-step 1
        scroll-margin 0
        scroll-conservatively 10000)

今天看源码想解决一下这个inline image滚动的问题,发现如果scroll-conservatively如果为默认的0,滚动效果不错,但是这样影响其他时候滚动的效果,所以我不想赋为0。在line-move中有scroll-conservatively的判断,如果修改为下面的代码,就会调用到line-move-partial,这样滚动图片效果就不错

(defun line-move (arg &optional noerror _to-end try-vscroll)
  (if noninteractive
      (line-move-1 arg noerror)
    (unless (and auto-window-vscroll try-vscroll
                 ;; ...
                 ;; 注释这一行
                 ;; (zerop scroll-conservatively)
                 ;; ...
                 (line-move-partial arg noerror))
      ;; .....
      )))

效果不错,也不需要修改scroll-conservatively,但是到了图片将要全部显示的时候,还是会突然跳到屏幕中间,还需要再修改一下line-move-partial函数

(defun line-move-partial (arg noerror &optional _to-end)
  ;; ...
  (when (or (null lh)
            ;; 注释下面这一行
            ;; (>= rbot dlh)
            ;; 添加这两行
            (> (+ rowh rbot) dlh)
            (> this-height dlh)

            (<= ypos (- dlh))
            (null this-lh)
            (<= this-ypos (- dlh)))
    ;; ...
    ))

这样修改之后,图片从窗口下边出来的过程就不会跳,图片从窗口下边消失的过程本来也不会跳,从窗口上边出来和消失还没有想好怎么解决

大家可以试一下这个