如何在Vim中移动屏幕而不移动光标?

807

我最近发现了 Vim 的快捷键 Ctrl+ECtrl+Y 可以分别将屏幕上下移动一行,而不会移动光标。

你知道有什么命令可以让光标保持原位,但是将屏幕移动到光标所在的那一行并作为第一行吗?(如果有命令能将屏幕移动到最后一行那就更好了)

我可以通过手动按适当次数的 Ctrl+E(或者 Ctrl+Y)来实现此功能,但希望有一个可以直接完成此操作的命令。

有什么建议吗?

14个回答

1158
  • zz - 将当前行移动到屏幕中央(注意: ZZ 是保存并退出,因此要注意大写锁定键
  • zt - 将当前行移动到屏幕顶部
  • zb - 将当前行移动到屏幕底部

44
赶快把大写锁定键映射为控制键吧! - Aaron
2
查询大写锁定状态非常依赖于环境。我听说在Vimscript中无法完成这项任务,而且现在我已经接受了这一点。如果你想走这条路,可以使用xev -qcat /proc/bus/input/devices查找要查询的设备,以及evtestthd ... --dump /dev/input/event<#>来检查状态等。如果你绝对必须进行系统范围的重新映射,至少交换两个锁定键,如Caps <--> Num - 但问题更多的是忘记它是否打开,因为如果你之前需要它,你会继续使用它,无论使用什么映射。风险在于破坏文件/用户/系统之前的Vim。 - John P
其他 Vim 脚本选项:打开 'confirm' 以确认退出/离开等;对于编写,我相信您需要一个带有 confirm() 的 BufWritePre 自动命令。此外,您可以将大写锁定键映射到 Vim 理解但未映射的键或组合键,然后在插入/替换模式下手动或通过 https://github.com/tpope/vim-capslock 等工具专门模拟大写锁定。您可能不需要在 Vim 之外使用它,但如果需要,请编写 xmodmap 脚本以恢复更改,或查看程序是否支持自己的映射(并做好记录)。 - John P
10
zt / zz / zb - 固定光标并将屏幕移动到顶部/中心/底部(德语:'zentrum') <---> H / M / L - 固定屏幕并将光标移动到高/中/低位置。 - MacMartin
11
如果你的大写锁定键开着的话,我更喜欢使用 z. 而不是 zz,因为在这种情况下,zz 会显得不太友好。 - Anthony Awuley
显示剩余5条评论

818

另外:

  • Ctrl-y 向上移动屏幕一行
  • Ctrl-e 向下移动屏幕一行
  • Ctrl-u 向上移动光标和屏幕的 ½ 个页面
  • Ctrl-d 向下移动光标和屏幕的 ½ 个页面
  • Ctrl-b 向上移动屏幕一个页面,将光标移动到最后一行
  • Ctrl-f 向下移动屏幕一个页面,将光标移动到第一行

Ctrl-yCtrl-e 只有在需要移动时才会改变光标位置。

翻译来自www.lagmonster.org/docs/vi2.html


130
@ulidtko说:“efter”(瑞典语中的“after”)、“yore”(指过去)、“up”、“down”、“back”和“forward”。(单词“back”和“forward”比“up”和“down”要长,因此它们自然而然地将屏幕移动更远;) - Moberg
23
我猜“yester”,也就是昨天,会是一个更好的记忆助手。^^ - Moberg
无论是Ctrl-u还是Ctrl-d都可以移动光标:“_如果可能的话,光标将在文件中向上移动相同数量的行(当行换行时以及到达文件结尾时可能会有所不同)。” - Lexi
3
:help CTRL-E says Mnemonic: Extra lines. - Niko Bellic
我喜欢使用zt + 3Ctrl+y的组合键,这样当前行就会在屏幕顶部,但我仍然可以看到我正在编写的代码的上方范围的一部分。 - aviggiano
显示剩余2条评论

46

Vim要求光标始终在当前屏幕内,但您可以将当前位置设置为书签,滚动屏幕,然后返回到原来的位置。

mg  # This book marks the current position as g (this can be any letter)
<scroll around>
`g  # return to g

1
请注意,如果您只关心跳转到书签行,可以使用“g”。 - Matt Briggs
7
"Vim要求光标始终在当前屏幕中。" Vim用户喜欢吹嘘vim中的一切都可以配置,但这个是无法更改的。当我浏览文件时,我不希望我的光标移动。这对我来说是不能容忍的。" - gadelat
13
我从未遇到过想要把光标放在看不见的地方的情况。当你滚动时,光标会移动,但你可以轻松返回到之前的位置(这样你就能看到你实际上所在的位置,而不只是猜测)。其中一种方法是使用双引号反引号 ` ,另一种非常好的方法是使用“Ctrl-O”,而“反引号、句点”可以将你带回你最后编辑的位置。 - dash-tom-bang
3
@gedalat,在其他编辑器中,当你滚动页面后不知道光标的位置时,不得不使用鼠标点击某个地方才能重新找回光标,这真的很烦人。或者你认为光标在“这里”,开始输入,结果光标突然跳回到之前的位置,此时你无法回到滚动的位置,因为只有光标的位置被记录下来了。让光标跟随你的移动是一件好事情。 - Shahbaz
1
它是可配置的,@gadelat。你只需要映射这个答案(用mg标记位置,滚动一下,用'g跳转到标记处),然后就完成了。现在你可以调用可配置的键来移动光标,感觉就像光标从未离开当前位置一样。大功告成! - DrBeco
即使vim需要将光标放在当前屏幕上,你仍然可以通过折叠上下行而不移动来滚动到文件中的任何位置。(请参见我的有关无需移动插件的答案,该插件利用了这个想法) - snap

31

我很惊讶没有人使用Scrolloff选项来保持光标在页面中间。 可以尝试一下:

:set so=999

这是Vim维基上的第一种推荐方法,效果很好。


14
如果您不想让光标总是在正中间,您可以将其设置为较小的值。例如,:set scrolloff=4 将要求光标始终距离窗口顶部或底部至少 4 行,这样您就始终能获得一些上下文信息。 - Soren Bjornstad
1
这很美丽。 - Yar

24

我曾经使用过以下快捷键(注意:分别按下每个键):

z tz enter --> 将当前行移动到屏幕顶部

z zz . --> 将当前行移动到屏幕中央

z bz - --> 将当前行移动到屏幕底部

如果不明确:

enter 意思是回车或者 Enter 键。

. 意思是点号或者“句号”键 (.)。

- 意思是连字符键 (-)。

值得一提的是,使用 z. 可以避免在大写锁定开启时意外输入 ZZ 导致保存并关闭 Vi 的风险。

更多信息请参考::help scroll-cursor


这些很棒,但对于我的小手指来说,从 zt 有点太过勉强了 ‍♂️。 - ipatch

22

这是我的vimrc解决方案:

"keep cursor in the middle all the time :)
nnoremap k kzz
nnoremap j jzz
nnoremap p pzz
nnoremap P Pzz
nnoremap G Gzz
nnoremap x xzz
inoremap <ESC> <ESC>zz
nnoremap <ENTER> <ENTER>zz
inoremap <ENTER> <ENTER><ESC>zzi
nnoremap o o<ESC>zza
nnoremap O O<ESC>zza
nnoremap a a<ESC>zza

使光标保持在屏幕中央,而屏幕会上下移动。


我认为这个解决方案更符合OP的需求。我尝试了一下,它完美地运行了。 - Gustavo Pinsard
15
把“scrolloff”设置为“lines”值的一半怎么样?请注意不改变原意并使语言流畅易懂,不提供额外信息或解释。 - rld.
1
不幸的是,“nnoremap o o<ESC>zza”会失去自动缩进,但是通过添加和删除临时字符“。”来解决这个问题。“nnoremap o o.<ESC>zzxa”。 - Goblinhack

19

我用来滚屏的口诀是...

除了其他答案中提到的,还要注意 zezs,它们的意思是:将屏幕移动到光标左/右侧(不移动光标)。

+-------------------------------+
^                               |
|c-e (keep cursor)              |
|H(igh)             zt (top)    |
|                   ^           |
|           ze      |      zs   |
|M(iddle)  zh/zH <--zz--> zl/zL |
|                   |           |
|                   v           |
|L(ow)              zb (bottom) |
|c-y (keep cursor)              |
v                               |
+-------------------------------+

还要看一下键盘上 hltb 的位置(在德语键盘上还有 c-ec-y,并且 "y" 键某种方式指向底部),记住屏幕移动时它们的位置。


19

如果你想在使用Ctrl+DCtrl+FCtrl+BCtrl+UGHMLgg时光标停留在同一列,请定义以下选项:

:set nostartofline

3
每次都会忘记/混淆: zt / zz / zb - 将光标固定并将屏幕移至顶部/中心(德语:“zentrum”)/底部 <---> H / M / L - 固定屏幕并将光标移至高/中/低位置。 - MacMartin

8

打开vim并输入以下命令:

:help z

z是vim中的重绘命令,它会根据光标所在位置重新绘制文件。你有以下几个选项:

z+ - 将光标放置于窗口的顶部,并定位到行的第一个非空字符。

z- - 将光标放置于窗口的底部,并定位到行的第一个非空字符。

z. - 将光标放置于窗口的中央,并定位到行的第一个非空字符。

zt - 将光标放置于窗口的顶部

zb - 将光标放置于窗口的底部

zz - 将光标放置于窗口的中央


8

您可以在光标移动命令前面加上一个数字,这将重复执行该命令的次数

10Ctrl+E会执行10次Ctrl+E,而不是一次。


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