vi/vim:如何滚动屏幕的三分之一高度

3
据我了解,ctrl-dctrl-u按照scroll选项所设置的行数滚动窗口,默认情况下为窗口高度的一半。是否可以将其更改为滚动窗口高度的三分之一?

哦,让这在更短的时间内发生也是很棒的。 - alxndr
3个回答

3
< p > < code >scroll 的默认值是动态的,在一个窗口中可能是12,在另一个窗口中可能是21,但比例50%是硬编码的。据我所知,用于动态计算scroll的该比例无法修改。

您可以通过类似以下代码轻松更改scroll的值:

execute "set scroll=" . winheight('.') / 3

现在你需要找到如何、何时以及在哪里使用这个代码片段。autocmd 是一个不错的选择,但我们应该使用什么事件呢?WinEnter/WinLeaveCursorMove?还是其他事件?
也许一个简单的映射可以覆盖默认行为?像这样:
nnoremap <C-d> :execute "normal! " . winheight('.') / 3 . "^D"<CR>
" type <C-v> then <C-d> to produce ^D

1
在命令行中,向上滚动的等效命令是什么?^U不起作用,它会在我的命令行中产生一个:" - Bananach
我有同样的问题:^U无法工作,它在我的命令行中产生了一个:" - mroavi
我已经将这个功能添加到NeoVim的Lua API中,代码如下: vim.api.nvim_set_keymap('n', '<C-d>', vim.api.nvim_replace_termcodes([[(winheight(0)/3).'<C-d>']], true, false, false), {noremap = true, expr = true, desc = '跳转到窗口高度的三分之一处'}) https://github.com/alxndr/dotfiles/blob/1e15f771a9/nvim/lua/mappings.lua#L80 - alxndr

2

使用以下ex命令。它使用变量lines来显示窗口中显示了多少行,并计算第三行。

:execute "set scroll=" .&lines / 3

编辑: 当窗口大小改变时,滚动值不会改变,因此请在您的vimrc中添加以下自动命令来修复它:

:au VimResized * execute "set scroll=" . &lines / 3

3
@Alexander,“&lines”代表的是Vim整个窗口的高度,而不是当前窗口的高度。请使用“winheight('.')”获取当前窗口的高度。 - romainl

1
解决方法是在您的~/.vimrc中正确设置scroll值。然而,使用set scroll=n的问题是,每当当前窗口大小发生变化时,例如使用:h scroll打开内置帮助或使用q/浏览搜索历史时,该值会被重置为0
为了在所有窗口和窗口大小更改后保留scroll设置,您可以将以下vimscript代码添加到您的~/.vimrc中:
set scroll=float2nr(winheight('.') / 3)
function! PreserveScroll(timer)
  set scroll=float2nr(winheight('.') / 3)
endfunction
augroup vimrc-preserve-scroll
  autocmd!
  autocmd VimResized * set scroll=float2nr(winheight('.') / 3)
  autocmd WinEnter   * set scroll=float2nr(winheight('.') / 3)
  autocmd WinLeave   * call timer_start(300, "PreserveScroll", {"repeat": 3})
augroup END

显然,设置一个计时器并不是最好的解决方案,但不幸的是,我没有找到更好的方法来在返回窗口后执行"set scroll=n",例如在关闭帮助窗口后。
下面是同一段vimscript代码的稍微改进版本,从保持scroll值的计算在一个地方的意义上来说。
function! PreserveScroll(timer = v:null)
  set scroll=float2nr(winheight('.') / 3)
endfunction
augroup vimrc-preserve-scroll
  autocmd!
  autocmd VimResized * call PreserveScroll() 
  autocmd WinEnter   * call PreserveScroll()
  autocmd WinLeave   * call timer_start(300, "PreserveScroll", {"repeat": 3})
augroup END
call PreserveScroll()

这个版本比之前的版本稍微少了一点效率,因为它消耗了一些额外的 CPU 循环,但这是完全可以接受的。:)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接