在 Vim 的插入模式中,除使用箭头键外,是否有其他方式可以移动一些字符向前或向后遍历文本?
如果我在插入模式下按下 h、j、k 和 l 键,则屏幕上会打印出相应的字符,而不是在文本中移动。
目前我使用的方法是使用 Ctrl + [(Esc),然后再遍历文本;但显然这样不够高效。
在插入模式下使用 h j k l 键来遍历编辑器,似乎是有道理的,但这并不是 Vim 的预期用法! Vim 提供了许多命令,可以使编辑更快速,更容易。
正确的方法是按下 Esc,转到要进行小修正的位置,进行修正,然后返回并继续编辑。这很有效,因为 Vim 比普通字符向前/向后/向上/向下移动的能力更强。学习更多这些能力之后,你会发现效率更高。
以下是一些用例:
但是,如果您仍然想在不离开插入模式的情况下进行小文本遍历,请遵循rson的建议并使用Ctrl+O。以我上面提到的第一个示例为例,Ctrl+OFf将使您移动到先前的“f”字符并保持插入模式。
Ctrl+o
发出一个单独的命令。在与 t/T 和 f/F 移动命令结合使用时,这有时可以帮助您到达目标位置。 - Randy Morris:h ins-special-keys
。ctrl-h
:退格,ctrl-w
:删除单词,ctrl-u
:删除到行首,alt-b
:返回上一个单词。 - everett1992在插入模式下,使用CtrlO可以暂时回到正常模式执行一个命令:
CTRL-O h move cursor left
CTRL-O l move cursor right
CTRL-O j move cursor down
CTRL-O k move cursor up
这可能是实现您想要的最简单的方法,而且容易记住。
在插入模式下,其他非常有用的控制键:
CTRL-W delete word to the left of cursor
CTRL-O D delete everything to the right of cursor
CTRL-U delete everything to the left of cursor
CTRL-H backspace/delete
CTRL-J insert newline (easier than reaching for the return key)
CTRL-T indent current line
CTRL-D un-indent current line
这些将消除许多不必要的切换回普通模式。
尽管 Pavel Shved 说 - 可能更明智的是习惯于退出插入模式 - 这里是一个示例映射集,用于在插入模式下快速导航:
" provide hjkl movements in Insert mode via the <Alt> modifier key
inoremap <A-h> <C-o>h
inoremap <A-j> <C-o>j
inoremap <A-k> <C-o>k
inoremap <A-l> <C-o>l
这将使得在插入模式下按下Alt+h向左移动一个字符,Alt+j向下移动,以此类推,与正常模式下的hjkl相似。
您必须将该代码复制到您的vimrc文件中,以便每次启动vim时加载它(您可以在正常模式下键入:new $myvimrc
打开它)。
由于默认情况下未映射Alt修饰键(映射到某些重要操作),您可以以相同的方式将其他(或所有)正常模式功能转移到插入模式。例如:
使用Alt+b移动到当前单词的开头:
inoremap <A-b> <C-o>b
inoremap <A-w> <C-o>w
值得一提的是,Alt 键可能有比复制普通模式行为更好的用途:例如,以下是从相邻行复制当前列到该行末尾部分的映射:
" Insert the rest of the line below the cursor.
" Mnemonic: Elevate characters from below line
inoremap <A-e>
\<Esc>
\jl
\y$
\hk
\p
\a
" Insert the rest of the line above the cursor.
" Mnemonic: Y depicts a funnel, through which the above line's characters pour onto the current line.
inoremap <A-y>
\<Esc>
\kl
\y$
\hj
\p
\a
我使用\
换行符和缩进来增加清晰度。命令被解释为单行代码。
CTRL-H delete the character in front of the cursor (same as <Backspace>)
CTRL-W delete the word in front of the cursor
CTRL-U delete all characters in front of the cursor (influenced by the 'backspace' option)
(在插入模式中没有显著的内置热键用于移动。)
这组映射使得在命令行中可以使用上方的Alt+hjkl进行移动:
" provide hjkl movements in Command-line mode via the <Alt> modifier key
cnoremap <A-h> <Left>
cnoremap <A-j> <Down>
cnoremap <A-k> <Up>
cnoremap <A-l> <Right>
或者,这些映射可以一次性将插入模式和命令行模式中的移动都添加进去:
" provide hjkl movements in Insert mode and Command-line mode via the <Alt> modifier key
noremap! <A-h> <Left>
noremap! <A-j> <Down>
noremap! <A-k> <Up>
noremap! <A-l> <Right>
将普通模式命令转换为命令行模式的映射命令与插入模式映射命令略有不同(因为命令行模式缺少插入模式的Ctrl+O):
" Normal mode command(s) go… --v <-- here
cnoremap <expr> <A-h> &cedit. 'h' .'<C-c>'
cnoremap <expr> <A-j> &cedit. 'j' .'<C-c>'
cnoremap <expr> <A-k> &cedit. 'k' .'<C-c>'
cnoremap <expr> <A-l> &cedit. 'l' .'<C-c>'
cnoremap <expr> <A-b> &cedit. 'b' .'<C-c>'
cnoremap <expr> <A-w> &cedit. 'w' .'<C-c>'
CTRL-B cursor to beginning of command-line
CTRL-E cursor to end of command-line
CTRL-F opens the command-line window (unless a different key is specified in 'cedit')
CTRL-H delete the character in front of the cursor (same as <Backspace>)
CTRL-W delete the word in front of the cursor
CTRL-U delete all characters in front of the cursor
CTRL-P recall previous command-line from history (that matches pattern in front of the cursor)
CTRL-N recall next command-line from history (that matches pattern in front of the cursor)
<Up> recall previous command-line from history (that matches pattern in front of the cursor)
<Down> recall next command-line from history (that matches pattern in front of the cursor)
<S-Up> recall previous command-line from history
<S-Down> recall next command-line from history
<PageUp> recall previous command-line from history
<PageDown> recall next command-line from history
<S-Left> cursor one word left
<C-Left> cursor one word left
<S-Right> cursor one word right
<C-Right> cursor one word right
<LeftMouse> cursor at mouse click
参考资料: :help ex-edit-index
如果你是一个 vim 纯粹主义者,请跳过阅读此答案。但如果你是新手,想要一些在众多的 vim 教程和博客中找不到的有用提示,那就请继续往下看... :-)
现在是2014年,作为一个最近重新使用 vim
的人,我可以提供一些潜在的反对意见和技巧。
虽然在 vim 中重复是一个强大的概念,但我(个人而言)发现使用它会迫使我计算(行数、字符数、单词数等)或猜测。我的大脑通常会想“我想把光标放在这里”,而不是“我想把光标移动_5个单词_”。能够快速移动光标,并通过视觉观察插入点的位置,使我能够将注意力集中在正在编辑的内容上,而不必计算我需要移动多少次才能到达需要编辑的位置。
…来浏览大量文本。
大多数(甚至全部)现代计算机都有一个与键盘紧密结合的触摸板(例如 MacBook)。工业设计师花费了很多时间来优化这些设计,以便不必将手移开键盘。好吧,如果你习惯使用鼠标并且不喜欢切换,那么可能还是会有这个问题,但对于任何新手(比如通过搜索找到本帖子的人),这应该不是什么大问题。
启用鼠标后,单击和拖动会切换到可视模式并标记一个区域进行复制。
这些是我称之为更现代化的(使用鼠标、滚轮等)在vim中导航的方法,根据您喜好的输入方式同样有效。
希望对您有所帮助。
许多Vim社区的人认为你不应该在插入模式下导航,因为这不是Vim的方式。我认为这是一种错误的情绪,当从标准编辑器转换到Vim时学习而来。
当您使用其工具创建原子、可重复的动作或查找时,Vim最强大。
如果您正在修复同一插入会话中的错误,则可以在插入模式下导航。但是,您不应该导航到修改的文本范围之外。
如果在输入文本时出现错误并退出插入模式进行更正,则无法重复预期的操作,.
将重复更正。
Vim支持许多插入模式导航键。显然有箭头键、Home和End,但还有许多其他快捷键。请参阅:h ins-special-keys
。
imap <C-b> <Left>
imap <C-f> <Right>
imap <C-e> <End>
imap <C-a> <Home>
" <C-a> is used to repeat last entered text. Override it, if its not needed
如果你能解决在终端中Meta键的问题,你就可以更好地模拟emacs模式。正常模式下的导航要好得多,但对于较短的移动操作,保持插入模式会更有帮助。
对于较长跳转,我喜欢以下默认的翻译:
<Meta-b> maps to <Esc><C-left>
这将切换到普通模式并返回一个单词
我相信在插入模式下,Home、End(和PageUp/PageDn)也可以正常使用,但除此之外,我不认为还有其他标准键用于文本遍历。
inoremap jj <Esc>
既然“jj”(连续快速按下两个j)似乎不在我的词汇表中,其他人会将其映射到他们习惯的位置。
我做的另一个重要更改是通过使用主机计算机的键盘配置将大写锁定和控制键互换位置(这对Emacs用户很常见)。因为我几乎从不使用大写锁定键,并且它正好在我想要的位置上有一个大而美丽的按钮。(缺点是当你发现自己在一个未修复的键盘上时!啊啊啊!)
一旦重新映射了大写锁定键,您就可以舒适地使用以下插入模式的重新映射:
请记住,某些键已经在插入模式中映射(默认情况下,回删一个单词是C-w(Control-w)),您可能已经拥有所需的绑定。尽管如此,我仍然喜欢C-h,在我的.vimrc文件中添加了以下内容:
inoremap <C-h> <C-w>
但是,您可能希望在正常模式下拥有相同的肌肉记忆痉挛,因此我还将C-h映射为:
nnoremap <C-h> db
(d)向后删除与同一键位组合的(b)相同。这种快速编辑在处理打字错误时非常有用。但是,移动文本和除了删除前一个单词之外的任何操作都要使用正常模式。一旦你养成了切换模式的习惯(当然使用重新映射),它将比重新映射插入模式更加高效。
抱歉,但vim不是那样工作的。
您应该切换到“正常”模式,导航,然后再次返回插入模式。
imap jk <Esc>
)也会很有帮助,这样你就不用打断势头并越过键盘去按下该键了。 - tsujin<ESC>
键映射为kj
,而不是jk
;我的好友 Dijkstra 应该为此负责! - DrBecojk
和kj
,所以我用两个手指按它就像按一个大按钮一样,而且顺序并不重要,这样我就回到正常状态了。 - Edu Ruiz