在 Vim 中进行平滑滚动的最佳方法是啥?

Posted

技术标签:

【中文标题】在 Vim 中进行平滑滚动的最佳方法是啥?【英文标题】:What is the best way to do smooth scrolling in Vim?在 Vim 中进行平滑滚动的最佳方法是什么? 【发布时间】:2011-05-03 03:42:08 【问题描述】:

Vim 中主要的滚动命令有:

    Ctrl-BCtrl-F,以及 PageUpPageDown 滚动整页 Ctrl-UCtrl-D默认滚动半页 Ctrl-YCtrl-E 滚动一行

我每次都失去前两者的视觉上下文,所以我养成了敲后者的坏习惯(Ctrl-YCtrl kbd>-E) 重复。

由于目前没有第一方支持平滑滚动,最不令人反感的解决方法/插件是什么?

我会根据任务同时使用 Vim 和 GVim,如果没有一个非常好的 hack 对两者都适用,我很乐意单独定制它们。鼠标滚轮在 GVim 中运行良好,但我正在寻找基于键盘的解决方案。

【问题讨论】:

[Ctrl + U] 无效,[Ctrl + u] 有效,您使用的是哪个版本的 vi(m)? 【参考方案1】:

更新:我现在已将这段代码(根据:help write-plugin 的指导方针进行了一些重构)推送到Github repo。

使用键盘

这是我在.vimrc 中的内容:

function SmoothScroll(up)
    if a:up
        let scrollaction="^Y"
    else
        let scrollaction="^E"
    endif
    exec "normal " . scrollaction
    redraw
    let counter=1
    while counter<&scroll
        let counter+=1
        sleep 10m
        redraw
        exec "normal " . scrollaction
    endwhile
endfunction

nnoremap <C-U> :call SmoothScroll(1)<Enter>
nnoremap <C-D> :call SmoothScroll(0)<Enter>
inoremap <C-U> <Esc>:call SmoothScroll(1)<Enter>i
inoremap <C-D> <Esc>:call SmoothScroll(0)<Enter>i

特点:

滚动到 Vim scroll 选项的底部。 可自定义的滚动速度(调整sleep 命令的时间参数;我使用十毫秒)。 注意:就像放慢视频的帧率一样,如果你将平滑滚动的速度减慢太多,它将是生涩的滚动,而不是平滑的滚动。但无论哪种方式最适合您。 在正常或插入模式下工作。

注意:各位复制粘贴的,请记住^ 字符表示控制字符;复制粘贴会产生无效结果,必须手动输入!

^Y - CTRL-V 然后 CTRL-Y ^E - CTRL-V 然后 CTRL-E

但是,&lt;C-U&gt;&lt;Enter&gt; 样式语法按字面意思键入这些字符; map 命令智能地将它们转换为控制字符。

使用鼠标

问题提到在 GVim 中使用鼠标滚动效果很好,但需要键盘解决方案。这对我来说意味着,如果鼠标解决方案在常规终端 Vim 中工作,提问者可能会对它感兴趣。

对我来说,打开鼠标支持可以平滑滚动鼠标滚轮。另外,对我来说,当我环顾四周时(即在正常模式下),平滑滚动最重要,而不是在我编辑时(在插入模式下),如果我不主动编辑,我的手需要留在键盘始终被移除,因此效果很好。

不过,在this question 的基础上,似乎有些人除了简单地打开鼠标之外还需要进行更多手动设置(我只使用set mouse=n):


我的.vimrc 有以下几行

 set mouse=a
 map <ScrollWheelUp> <C-Y>
 map <ScrollWheelDown> <C-E>

【讨论】:

这很好用......并且不像其他答案那样依赖于机器的速度。干杯! 警告:我发现你不应该按 Ctrl-D 等,直到上一个滚动完成或行为很奇怪.我之前没有遇到过这个问题,所以不知道是我刚才没有注意到,还是我正在使用的当前机器上的 Vim 配置特有的。如果有人知道如何在 Vim (!!) 中处理多线程,请随时加入。 我想到的一个可能的改进是将相同的平滑滚动应用于 zz、z-、z 命令 这是个好主意。我想你可以用同样的方式重新映射它们。 关于“记住 ^ 字符表示控制字符”的小评论:您可以将 'let scrollaction="^Y"' 替换为 'let scrollaction="\"',这样您不必使用 来生成键绑定,它使复制粘贴成为可能:)【参考方案2】:

vim 的tips.txt 中有一个简单的重映射技巧:

Smooth scrolling                    *scroll-smooth*

If you like the scrolling to go a bit smoother, you can use these mappings:

    :map <C-U> <C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y>
    :map <C-D> <C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E>

【讨论】:

为什么这比使用 'scroll' 选项设置更可取(例如,:set scroll=15)?滚动选项似乎更可取,因为您甚至可以创建一个 au 命令,当窗口高度变化时自动更改它。 (我想你也可以用这个映射方法做类似的事情,但是滚动选项可以简化事情。) 实际上,自动设置滚动变量也是我考虑的选项之一。正如您所提到的,它需要适合窗口大小。滚动变量默认为窗口高度的 1/2,但它似乎没有公开更改该分数的方法;您只能根据行数进行更改。您可能还需要为滚动设置一个比平滑滚动更小的值,因为您的眼睛不会有任何中间滚动状态来提高视觉持久性。 为了澄清,c-d 和 c-u 将滚动任何 'scroll' 选项设置为。默认为窗口高度的 1/2,但您可以将其设置为您想要的任何值。如果要根据窗口高度创建一个新值,请使用'winheight("%")' 函数,该函数返回窗口中的行数。因此,例如,命令 ':set scroll = winheight("%")/3' 将使 c-u 和 c-d 滚动 1/3 的窗口高度。 @Drew Wagner 此映射应重写为 noremap &lt;expr&gt; &lt;C-u&gt; repeat("\&lt;C-y&gt;", 20) 以提高可读性。 或者只是:map &lt;C-U&gt; 20&lt;C-Y&gt;【参考方案3】:

无耻插件,不过我这里创建了一个插件,你可以使用它来轻松调整滚动动画的距离、速度和持续时间:https://github.com/terryma/vim-smooth-scroll

【讨论】:

【参考方案4】:

最近的插件

我已经发布了类似here 的内容,但基本上有一个很棒的插件,我们现在可以使用它来滚动,称为terryma/vim-smooth-scroll。它提供了一个非常漂亮和平滑的滚动。


安装非常简单:

1 我使用Vundle,所以我只是将它附加到 .vimrc.bundles 中:

Bundle terryma/vim-smooth-scroll

在今天(2016 年 4 月 29 日)可用的最新版 Vundle 中,您可以将其放入您的 .vimrc

Plugin 'terryma/vim-smooth-scroll'

2 如文档中所述,您可以设置 3 个参数:distancedurationspeed .

我在我的 .vimrc 文件中使用它:

noremap <silent> <c-b> :call smooth_scroll#up(&scroll*2, 10, 4)<CR>
noremap <silent> <c-f> :call smooth_scroll#down(&scroll*2, 10, 4)<CR>

【讨论】:

遗憾的是,这个插件也会移动光标而不是我想要的:像&lt;C-E&gt;&lt;C-Y&gt; 命令一样滚动屏幕。【参考方案5】:

我所做的是将键盘重复设置为非常快,大约 120 个字符/秒,并且延迟很小。 然后我映射到 4j 和 4k 我使用 j 和 k 向上和向下导航源代码,它可以很好地和快速地上下移动光标,非常流畅。 但这是好的部分,这适用于 Linux,而不是 Windows。 多年来,X11 的键盘输入工作方式是,当您按住 j 时,它显然会开始输出 j 个字符。但是,当您继续按住 j 并同时按 ctrl 键时,X11 开始输出 c-j 字符,而无需重新按 j 键。然后当你松开 ctrl 键并继续按 j 时,X11 继续再次输入 j。 所以 j 使光标开始平稳向下移动,并且您可以定期按 ctrl 而不放开 j 来给它一个提升,一个震动。

另外,我做 Devin 做的事,我将 scrolloffset 设置为 5。

最后,我交换了 ctrl 和 cap lock。 ctrl 键的默认位置是完全延迟(无意冒犯)。它使您必须旋转左手。我几乎从不使用大写锁定,所以我交换了它们。然后我的左手粉红手指无需任何瑜伽动作即可到达 ctrl 键。

这些东西多年来一直对我有用。我只使用 vim,从不使用 gvim。

【讨论】:

+1 用于感叹控制键的位置。 IMO macbook 命令键也好不到哪里去。【参考方案6】:

这不是完全平滑的滚动,但它是我在跳转页面时不丢失上下文的处理方式。

设置为=7

'scrolloff' 'so' 数字(默认 0) 全球 Vi 无此功能 在光标上方和下方保留的最小屏幕行数。 这将使一些上下文在您工作的地方可见。如果 您将其设置为一个非常大的值 (999) 光标线将始终为 在窗口的中间(文件的开头或结尾除外,或者 当长线换行时)。 对于水平滚动,请参见“sidescrolloff”。 注意:当设置 'compatible' 时,此选项设置为 0。

【讨论】:

【参考方案7】:

插件cskeeters/vim-smooth-scroll 支持平滑滚动,无需配置。它支持支持ztzzzb的平滑滚动。这是terryma's plugin 的一个分支。一些开放的拉取请求已被应用。

【讨论】:

【参考方案8】:

这结合了许多这些答案,这就是我使用的。

noremap <expr> <C-u> repeat("\<C-y> :sleep 10m<CR>", winheight('%')/2)
noremap <expr> <C-d> repeat("\<C-e> :sleep 10m<CR>", winheight('%')/2)

【讨论】:

【参考方案9】:
N <CR-E>
N <CR-Y>

...其中“N”是您要滚动的单行数。

字面意义上的不流畅,但你保留了键盘。

【讨论】:

【参考方案10】:

这对于铁杆用户来说可能会引起争议,但是...在 Vim 中平滑滚动的最佳方式是...鼠标滚轮。

【讨论】:

【参考方案11】:

我刚刚发现 this plugin 称为“加速平滑滚动”(“用于加速平滑滚动的 Vim 插件(映射到 &lt;C-D&gt;/&lt;C-U&gt;&lt;C-F&gt;/&lt;C-B&gt;)”),例如可以通过 Vundle 将这一行放入你的 .vimrc:

Plugin 'yonchu/accelerated-smooth-scroll'

然后通过重新启动 Vim 并运行 :PluginInstall 命令,然后再次重新启动 Vim 并使用 &lt;C-D&gt; (Ctrl+D) 和 @987654327 @ (Ctrl+O) 命令正常。

遗憾的是,这个插件也会移动光标而不是我想要的:像 &lt;C-E&gt;&lt;C-Y&gt; 命令一样滚动屏幕。

【讨论】:

【参考方案12】:

我稍微修改了@Keith Pinson 的代码,以便 ctrl-f 和 ctrl-b 也可以映射:

function SmoothScroll(scroll_direction, n_scroll)
    let n_scroll = a:n_scroll
    if a:scroll_direction == 1
        let scrollaction=""
    else 
        let scrollaction=""
    endif
    exec "normal " . scrollaction
    redraw
    let counter=1
    while counter<&scroll*n_scroll
        let counter+=1
        sleep 10m " ms per line
        redraw
        exec "normal " . scrollaction
    endwhile
endfunction

" smoothly scroll the screen for some scrolling operations
nnoremap <C-U> :call SmoothScroll(1,1)<cr>
nnoremap <C-D> :call SmoothScroll(2,1)<cr>
nnoremap <C-B> :call SmoothScroll(1,2)<cr>
nnoremap <C-F> :call SmoothScroll(2,2)<cr>

【讨论】:

以上是关于在 Vim 中进行平滑滚动的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中拥有这种复杂的水平和垂直滚动结构的最佳方式是啥? [关闭]

无限滚动到集合视图的最佳实现是啥?就像 Pinterest 在滚动结束时获取数据

Recycler 视图中的自动平滑滚动

vue2.0模拟锚点实现定位平滑滚动

在 Objective-C 中实现这种滚动 UI 的最佳方式是啥?

iOS解决方法:在没有CSS属性的情况下平滑滚动滚动行为:平滑吗?