在插入模式下遍历文本


321

插入模式下在Vim,除了使用箭头键之外,是否有任何其他方式可以遍历文本来移动某些字符?

如果我按hjkl在插入模式下,实际的字符显示在屏幕上,而不是在文本上移动。

目前,我这样做的方法是必须诉诸Ctrl+ [Esc)然后遍历文本。但显然那没有效果。


顺便提一句:如果将转义映射到更紧密的组合键(例如imap jk <Esc>),这也很有用,这样您就不必中断动量并跨键盘来按下键。
tsujin '17

3
我喜欢(<ESC>)映射到kj而不是jk; 我的同伴朋友迪克斯特拉要怪!
Beco博士

7
我有jkkj,所以我就像用两个手指按下一个大按钮一样,并且恢复正常后的顺序也没关系。
Edu Ruiz

Answers:


647

您似乎滥用了vim,但这可能是由于对它不甚了解。

正确的方法Esc,转到要进行小的校正的位置,将其修复,然后返回并继续进行编辑。这是有效的,因为Vim的动作要比平常的角色前进/后退/上/下动作更多。了解更多这些知识之后,这将变得更有成效。

这里有几个用例:

  • 您不小心输入了“ accifantly”。没问题,序列EscFfrdA将纠正错误并带您回到编辑位置。该Ff移动会将光标向后移动到第一个遇到的“ f”字符。与Ctrl+ 比较DeldEnd在休闲编辑器中几乎执行相同的操作,但是需要更多的击键操作,并使您的手移出键盘的字母数字区域。
  • 您不小心键入了“您不小心键入了”,但想将其更正为“您故意键入了”。然后,Esc2bcw将清除您要修正的单词并使您进入插入模式,因此您可以立即重新输入该单词。要返回到编辑状态,只需按A而不是End,因此您无需动手就可以到达End按键。
  • 您不小心键入了“鼠标”而不是“鼠标”。没问题-好的old Ctrl+ w会删除前一个单词而不会离开插入模式。而且,擦除一个小字比修复其中的错误要快得多。我已经习惯了,当我键入此消息时关闭了浏览器页面...!
  • 重复计数在很大程度上没有得到充分利用。进行移动之前,您可以输入数字。并且移动将重复此次数。例如,15h将光标4j 移回15个字符,并将光标下移4行。开始使用它们,您很快就会习惯。如果您从光标后面错了十个字符,就会发现按键10次要比迭代移动光标慢得多。因此,您可以改而快速地键入键12h(粗略地猜测,您需要向后移动几个字符),并立即向前两次ll以快速纠正错误。

但是,如果您仍然想在不离开插入模式的情况下进行小的文本遍历,请遵循rson建议并使用Ctrl+ O。以我上面提到的第一个示例为例,Ctrl+ OFf会将您移至上一个“ f”字符,并使您进入插入模式。


33
+1出色的回答,并感谢您提供的所有示例!
Andreas Grech

78
还值得注意的是,您可以使用Ctrl+o普通模式发出单个命令。有时这可以使您到达想要的位置,尤其是与t / T和f / F运动命令结合使用时。
兰迪·莫里斯

6
“您似乎滥用了vim,但是您可能对此不太熟悉。” 居高临下。没有?
David Rivers

17
这是对如何正确使用Vim的深刻见解。但是,我发现按“ Esc”会很麻烦,因此我认为值得指出的是,您可以将一个更易于访问的键映射到该函数,例如“ imap jj <esc>”。
2012年

25
要解决一个错字,你应该离开插入模式。Vim功能强大,因为您可以创建原子的,可重复的动作。插入一个错字并加以修复会创建两个单独的动作。纠正错字的正确方法是在不离开插入模式的情况下进行操作。如果那意味着使用箭头键导航到那里,那很好。Vim确实有一些键绑定可以在插入模式下导航。检查:h ins-special-keysctrl-h::退格,ctrl-w:删除单词,ctrl-u:删除到行首,alt-b:返回单词。
everett1992

151

而在插入模式,使用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

这些将消除许多浪费的切换回正常模式的麻烦。


13
谢谢。这应该被认为是正确的答案。它实际上是有帮助的。
Atcold

1
在我的Mac上,它是小写字母o而不是大写字母O。这与“标准vim”不同吗?我看到很多地方他们似乎都说大写(除非那只是草率的写作)。你可否确认?
Floris

好的,非常有用。但是,我很难找到一个有趣的组合,这是删除行。在意外插入行的情况下要做的事情被低估了。
patrik '18 -4-4

5
@Floris Vim不能区分ctrl组合的大小写字母。这就是为什么无法映射ctrl + shift +某物的原因。
Mahmoud Al-Qudsi '18

92

插入方式

运动

j

尽管Pavel Shved 说了什么-习惯于Escaping插入模式可能更可取-这是在插入模式下快速导航的一组示例映射:

" 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在“普通”模式下键入“ start”来打开它)。


任何正常模式下的动作

由于Alt默认情况下未将修饰键映射到(重要的内容),因此您可以以相同的方式将其他(或全部)功能从“普通”模式拉到“插入”模式。例如:
Alt+ 移到当前单词的开头b

inoremap <A-b> <C-o>b
inoremap <A-w> <C-o>w


Alt在插入模式下的其他用法)

值得一提的是,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)

(没有明显的内置热键可在插入模式下移动。)

参考: :help insert-index


命令行模式

这组映射,使上部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


@YugalJindle:谢谢!:)我现在添加了有关调整命令行模式的信息。(此方法与“插入”模式有些不同。)
Aaron Thoma 2014年

@Zen:“ winkey”是什么意思?我没有在答案中引用Windows键。你是说Alt钥匙吗?
亚伦·托马

Shift-向左/向右移动整个单词!!我怎么不知道呢。谢谢。
Floris

实际上在终端模式下,alt会在您的命令之前自动发送esc .......
Fuseteam '19

26

如果您是vim纯粹主义者,请跳过阅读此答案。OTOH,如果您是vim的新手,并且正在寻找数百条vim教程和博客中找不到的有用提示,请继续阅读... :-)

几种非正统(vim)方式

现在是2014年,作为最近回到vim我身边的人,我可以提供一些可能相反的观点和技巧。

使用shift + left或shift + right遍历单词

尽管重复在vim中是一个强大的概念,但我(个人)感到奇怪,使用重复会迫使我计数(行,字符,单词等)或进行猜测。我的大脑通常像“我希望光标在那里 ”而不是“我想要光标_5_words_to_the_left_”一样工作。能够快速移动光标,并以这种方式直观地观察插入点的位置,这使我可以专心于正在编辑的内容,而不必计算要到达所需编辑位置的跳数。

打开鼠标模式,然后使用鼠标滚轮并单击

...浏览大量文本。

大多数(所有)现代计算机都具有与键盘紧密集成的触摸板(例如MacBook)。工业设计师花了很多年的时间来优化这些设计,以使不得不将手从键盘上移开的旧问题不再是一个真正的问题。好的,这是如果您习惯了鼠标并且不喜欢切换,但是对于vim新手(例如可能通过搜索找到此帖子的人)来说,这应该不是什么大问题。

作为奖励,单击+拖动使您进入可视模式

启用鼠标后,单击和拖动具有切换到可视模式并标记要拉动的区域的效果。

并使用滚轮

使用鼠标(滚轮)滚动并单击以定位光标(duh)即可。有关更多信息,请参见http://usevim.com/2012/05/16/mouse/

所以...

这些就是我所说的更现代的(使用鼠标,滚轮等)在vim中导航的方式,同样有效,具体取决于您对输入的偏好。

高温超导


6
@MilesRout是的,我有免责声明。但实际上,我认为有很大一部分vim用户的大脑工作与我的相同。那就是...我的大脑通常像“我希望光标在那里”而不是“我想要光标5_words_to_the_left ”那样工作。传统的vim方式对那些人来说效果不佳。我喜欢vim,因为a)它随处可见,并且b)具有强大的功能。但是,我不认为需要遵循所有默认机制。
Shyam Habarakada 2014年

4
@MilesRout在vim中围绕这种事情有很多宗教信仰,所以我不会在此与您辩论。重复计数方法对我无济于事,被接受的答案也称其为未充分使用的东西。我只能猜测为什么会这样。使用w,b等导航到附近的地方都是很好的选择,但更进一步,鼠标滚轮对我来说要好得多。干杯。
Shyam Habarakada 2014年

4
+1。我不明白这一点。有免责声明。如果喜欢,请接受;如果不喜欢,请跳过。
fangmobile.com 2015年

这是一个非常有用的答案
Slava 2015年

1
作为最近刚搬到VIM的人,我发现这个答案的前提是绝对正确的,能够立即告诉将光标定位在给定位置所需的重复次数的功能可能会也可能不会附带经验。现在,就像@ShyamHabarakada一样,我的大脑无法正常工作。不管这有多么不合常规,我个人都会将fn + hjkl重新映射到箭头键以进行很小的移动。对于大动作,我通常会估算一些重复次数,然后对这些重复次数进行微调。对我来说,那是我所能尽快得到的。
Jacoscaz 2015年

14

Vim社区中的许多人都认为您不应以“插入”模式导航,这不是Vim的方式。从标准编辑器过渡到Vim时,我认为这是一种错误的认识。

当您使用Vim的工具来创建原子的,可重复的动作或发现时,Vim最为强大。

如果要解决在同一插入会话中犯的错误,可以在“插入”模式下导航您不应在修改的文本范围之外导航。

如果您在输入文本时犯了一个错误,并退出了“插入”模式以解决该问题,则您将无法重复执行预期的操作,请.重复进行更正。

Vim确实支持许多插入模式导航键。显然,有箭头键,“主页”和“结束”,但还有许多其他快捷键。请参阅:h ins-special-keys


4

在GVim中,您可以使用鼠标。但是说实话,使用箭头键有什么问题?它们在键盘上是有原因的。


9
但这并不适合vim用户。vim的主要优势之一是,您可以做各种事情而无需花费时间将手从键盘上移开。特别是hjkl的动作。
亚伦·托马

1
我同意@ammoQ。使用箭头键没有问题。如果使用箭头键可以提高工作效率,请选择它。
Eunwoo Song

荣誉:使用vi时,我使用hjkl的次数要多于箭头键,但是对我来说,在模式之间进行切换已成为一种潜意识的动作。
Erich Kitzmueller

4

为了在插入模式下获得更好的导航,为什么不映射一些键?

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>

切换到正常模式并返回一个字


2

我相信HomeEnd(和PageUp/ PageDn)在插入模式下也可以正常工作,但是除此之外,我不认为还有其他用于文本遍历的标准键。


但是可能没有任何方法可以仅使用字母键遍历文本吗?
Andreas Grech

5
当然可以,如果您不想输入某些字母...;)
霍布斯

@hobbs ctrl + hjkl怎么样?那应该是有道理的
user405205​​4

1

抱歉,但是vim不能那样工作。

您应该切换到“普通”模式,导航,然后返回以再次插入。


1

您可以创建在插​​入模式下工作的映射。做到这一点的方法是通过inoremap。注意命令开头的“ i”(noremap对于避免键映射冲突很有用)。对于“正常”模式,推论为“ n”。您可以推测vim认为是“正常”;)

但是,您确实想使用“正常”模式浏览文本。Vim在这种情况下超级出色,所有功能都可以从正常模式获得。Vim已经提供了从普通模式转换为插入模式的简便方法(例如,i,I,a,A,o,O)。诀窍是使其易于进入正常模式。这样做的方法是将转义重新映射到更方便的键。但是,您需要一种不会与常规键入冲突的内容。我用:

inoremap jj <Esc>

由于jj(即2 j很快被一个接一个地键入)似乎没有出现在我的词汇表中。其他人将重新映射到舒适的地方。

我做的另一个重要更改是切换键盘上的CAPSLOCK和CONTROL键(使用主机的键盘配置),因为我几乎从不使用CAPSLOCK,并且它在我想要的位置有那么大,漂亮的按钮。(这对于Emacs用户是常见的。缺点是当您发现自己处于“未固定”键盘上时!Aaarggh!)

重新映射CAPSLOCK后,可以轻松使用以下插入模式重新映射:

请记住,有些键已经在插入模式下映射(默认情况下,backward-kill-word是Cw(Control-w),您可能已经有了想要的绑定。也就是说,我更喜欢Ch,所以在我的.vimrc文件中:

inoremap <C-h> <C-w>

但是,您可能希望在正常模式下出现相同的肌肉记忆痉挛,因此我还将Ch映射为:

nnoremap <C-h> db

(d)缩小(b)击键用相同的和弦完成相同的操作。这种快速编辑是我发现在实际操作中对错别字有用的一种。但是,请坚持使用普通模式来移动文本,而不仅仅是杀死前一个单词。一旦您习惯了更改模式的习惯(当然使用重映射),它将比重新映射插入模式更加有效。


很好的逃脱重映射-我认为除了音译阿拉伯语外,它几乎可以用于任何其他用途!
jjt

0

您可以用来imap将插入模式下的任何键映射到光标键之一。像这样:

imap h <Left>

现在h就像在正常模式下一样移动光标。(以这种方式映射h显然是一个错误的选择)

话虽如此,我认为使用VIM在文本中四处移动的标准方式并不“有效”。在普通模式下有很多非常强大的方式遍历文本(例如使用w和b或/和?或f和F等)


1
我并不是说在vim中浏览文本的标准方法没有效果;我说的是不得不退出插入模式以退回几个字符然后又不得不再次插入来,这有点“烦人”。但是话又说回来,也许这是因为我还不太习惯vim :)
Andreas Grech

这是我一直在寻找的解决方案。我使用imap <Ch> <Left>(我知道它会删除一个字符,但是我有退格键),这就是我所需要的,谢谢。
user405205​​4

0

对于一些经常使用的动作和动作,我定义了以下映射。与CTRL + O组合相比,这节省了按键操作,并且由于我经常需要它们,因此从长远来看,它们会有所回报。

inoremap <A-$> <C-o>$
inoremap <A-^> <C-o>^
inoremap <A-h> <Left>
inoremap <A-l> <Right>
inoremap <A-O> <C-O>O
inoremap <A-o> <C-o>o
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.