在插入模式下遍历文本

而在Vim中的插入模式中,除了使用方向键之外,是否有任何方法可以遍历向前和向后移动一些字符的文本?

如果我在插入模式下按hjkl,实际字符将打印在屏幕上,而不是在文本中移动。

我现在这样做的方式是不得不诉诸Ctrl + (Esc)和遍历文本;但很明显,这是没有成效的。

120503 次浏览

我相信首页结束(和上页/PageDn)在插入模式下也能正常工作,但除此之外,我不相信有任何其他为文本遍历定义的标准键。

抱歉,vim不是这样工作的。

你应该切换到“正常”模式,导航,然后返回插入。

可以使用imap将插入模式中的任意键映射到其中一个游标键。像这样:

imap h <Left>

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

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

虽然你应该能够使用h j k l键在插入模式下遍历编辑器可能是有意义的,但这实际上不是Vim打算使用的方式!Vim提供了许多命令,使编辑而且更容易。

正确的方法Esc,去你想做一个小修正,修复它,回去继续编辑。这是有效的,因为Vim有更多的运动比通常字符向前/向后/向上/向下。当你学到更多的时候,你就会更有效率。

下面是一些用例:

  • 你不小心输入了“acfentaly”。没问题,序列EscFfrd一个将纠正错误,并将您带回您正在编辑的地方。Ff移动将把你的光标向后移动到第一次遇到的"f"的性格。将其与Ctrl+ __abc9__abc10__abc10__abc10__abc10__abc10__abc14__abc4__abc16进行比较,后者在休闲编辑器中几乎具有相同的功能,但需要更多的击键,并使您将手移出键盘的字母数字区域。
  • 你不小心打了“你不小心打了”,但想把它改成“你故意打了”。然后Esc2bcw将删除你想要修复的单词并将你带入插入模式,所以你可以立即重新键入它。要返回编辑,只需按一个而不是结束,所以你不需要移动你的手去触摸结束键。
  • 你不小心输入了“鼠标”;而不是“老鼠”。没问题-好的旧Ctrl+w将在不离开插入模式的情况下删除前一个单词。而且擦除一个小单词要比修复其中的错误快得多。我太习惯了,当我输入这条消息时,我已经关闭了浏览器页面…!
  • 重复计数在很大程度上没有得到充分利用。在做动作之前,你可以输入一个数字;这个动作要重复这么多次。例如,15h将使您的光标向后移动15个字符,而4j将使您的光标向下移动4行。开始使用它们,你很快就会习惯的。如果你在光标后面10个字符处犯了错误,你会发现按键10次比迭代移动光标的方法慢得多。因此,您可以快速地键入键12h(粗略地猜测需要向后移动光标的字符数),并立即向前移动两次,使用ll来快速纠正错误。

但是,如果你仍然想要在不离开插入模式的情况下做小的文本遍历,遵循rson建议并使用Ctrl+O。以我上面提到的第一个例子为例,Ctrl+OFf将把你移动到前面的&;f"字符并使您处于插入模式。

在GVim中,您可以使用鼠标。但说实话,使用方向键有什么错呢?它们在键盘上是有原因的。

插入模式

运动

hjkl

尽管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来打开它)。

任何正常模式移动

因为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

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

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

如果您可以在您的终端中使用元键,那么您可以更好地模拟emacs模式。正常模式中的导航要好得多,但对于较短的移动,它有助于保持在插入模式。

对于较长的跳跃,我更喜欢以下默认翻译:

<Meta-b>    maps to     <Esc><C-left>

这将转换为正常模式并返回一个单词

您可以创建在插入模式下工作的映射。方法是通过inoremap。注意命令开头的“i”(noremap有助于避免键映射冲突)。推论是“n”代表“正常”模式。你可以猜测vim认为什么是“正常的”;)

然而,你真的想在文本中使用“正常”模式导航。Vim在这方面非常出色,所有这些功能都可以从普通模式中获得。Vim已经提供了从普通模式切换到插入模式的简单方法(例如,i, i, a, a, o, o),诀窍是让它更容易进入正常模式。这样做的方法是将escape重新映射到一个更方便的键。但你需要一个不会与你的常规打字冲突的键盘。我使用:

inoremap jj <Esc>

因为jj(两个j一个接一个的快速输入)似乎没有出现在我的词汇表中。其他的会重新映射到舒适的地方。

我做的另一个重要的改变是切换我键盘上的CAPSLOCK和CONTROL键(使用主机的键盘配置),因为我几乎从不使用CAPSLOCK,它有一个大而漂亮的按钮,就在我想要它的地方。(这对于Emacs用户来说很常见。缺点是当你发现自己在一个“不固定”的键盘上时!Aaarggh !)

一旦你重新映射CAPSLOCK,你可以轻松地使用以下插入模式重新映射:

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

inoremap <C-h> <C-w>

但是,你可能想在正常模式下获得同样的肌肉记忆痉挛,所以我也将C-h映射为:

nnoremap <C-h> db

(d)elete (b)ackwards用相同的关键和弦完成了同样的事情。这种快速编辑是我在实践中发现的一种有用的错别字。但是在文本中移动和删除前一个单词以外的任何事情都要使用正常模式。一旦你养成了改变模式的习惯(当然是使用重映射),它将比重映射插入模式更有效。

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

这将消除许多浪费的开关回到正常模式。

Vim社区的许多人认为不应该在插入模式下导航,因为这不是Vim的方式。我认为这是在从标准编辑器过渡到Vim时学到的错误观点。

当您使用Vim的工具创建原子的、可重复的操作或查找时,Vim是最强大的。

如果你正在修复一个错误,在插入模式下导航是可以的。你不应该在你修改的文本范围之外导航。

如果你在输入文本时犯了错误,并退出插入模式来修复它,你将无法重复预期的操作,.将重复更正。

Vim支持许多插入模式导航键。显然有方向键、Home键和结束键,但还有许多其他快捷键。看到:h ins-special-keys

如果你是一个纯粹的vim主义者,跳过阅读这个答案。OTOH,如果你是vim的新手,正在寻找一些有用的技巧,你在数百个vim教程和博客中找不到,请继续阅读…: -)

一些非正统的(vim)方法

现在是2014年,作为一个最近回到vim的人,我可以提供一些潜在的逆向观点和技巧。

使用shift+左或shift+右遍历单词

虽然重复在vim中是一个强大的概念,但我(个人)觉得很奇怪,使用它要么迫使我计数(行、字符、单词等),要么进行猜测。我的大脑通常是这样工作的:“我想要光标在那里”,而不是“我想要光标_5words_to_thet_”。能够快速移动光标,直观地观察插入点的位置,这样可以让我专注于我正在编辑的内容,而不必计算我需要跳多少步才能到达我需要编辑的地方。

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

...在大量文本中导航。

大多数(所有)现代计算机都有一个与键盘紧密集成的触控板(例如macbook)。工业设计师们花费了多年的时间来优化这些设计,因此必须将手从键盘上移开的老问题不再是一个真正的问题。好吧,如果你习惯了鼠标,不喜欢切换,但对于vim的新手(比如那些可能通过搜索找到这篇文章的人),这应该不是什么大问题。

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

在启用鼠标的情况下,单击和拖动可以切换到可视模式,并标记一个区域以进行拉拽。

使用滚轮

使用鼠标(滚轮)来滚动,然后点击来定位光标(废话)。有关此的更多信息,请参见http://usevim.com/2012/05/16/mouse/

所以…

这些是我所说的更现代的(使用鼠标、滚轮等)在vim中导航的方式,根据您的输入偏好同样有效。

HTH

对于一些常用的动作和动作,我定义了以下映射。与CTRL+O组合相比,这节省了一次击键,因为我经常需要它们,它们在长期内是有回报的 运行。< / p >
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

是的,有办法。你可以在<强> Insert模式< / >强中使用gjgk来在一个逻辑行中向上(向后)和向下(向前)移动,该逻辑行环绕着许多可视线。如果你有很长的行和/或窄宽的终端,这是很方便的,可以比箭头键或按ESC来使用其他导航快捷键快得多。还可以使用CTRL-O发出一个普通模式命令。这两种导航动作都不会使您退出插入模式。

敲击ESC(在发明Vi时,它位于终端键盘的home行之外)可能会破坏工作效率。我处理的文本文件有非常长的逻辑行,整个段落的句子都是纯文本。这两个选择对我来说是一个真正的时间节省。如果我需要在段落中寻找一个特定的单词,转义到正常模式仍然很方便,但很多时候我只需要向上或向下移动一条视觉线,然后继续插入。

我实际上编辑了我的. vimrc来映射我几乎无用的ALT键,所以我的左手按下ALT,而我的右手使用方向键。(并且它不会退出插入模式:注意&;i"在每个条目的末尾)。

imap <A-UP> <ESC>gki
imap <A-DOWN> <ESC>gji

我还在. vimrc中添加了行,以便我的方向键在正常模式中工作,在一个逻辑行所包含的许多visual-lines中上下遍历(代码与上面的相同,除了你使用地图nmap而不是imap)并且我使用键盘的其他导航键与alt键,都在插入模式中。

我为我的ALT键添加了额外的导航行,以便与键盘上预先分配的导航键一起使用,以便在插入模式下更快地导航。这些都不会让你退出插入模式:

" <ALT> navigation within insert-mode
imap <A-UP> <ESC>gki
imap <A-DOWN> <ESC>gji
imap <A-LEFT> <ESC>bi
imap <A-RIGHT> <ESC>ea
imap <A-END> <ESC>A
imap <A-PageUp> <ESC>(i
imap <A-PageDown> <ESC>l)i
imap <A-Home> <Esc>I
" so that <ALT> behaves the same in normal mode
nmap <A-UP> gk
nmap <A-DOWN> gj
nmap <A-LEFT> b
nmap <A-RIGHT> le
nmap <A-END> $
nmap <A-PageUp> (
nmap <A-PageDown> )
nmap <A-Home> ^

我的“within"插入模式导航快捷方式使用ALT键PgUp, PgDn, Home &还有末端键,可以更快地跳跃。我使用alt-pgup和alt-pgdn按下句子向前或向后跳转。并且,我使用alt-home和alt-end来跳转到段落的开头和结尾。所有这些都逃不过插入模式。(我想我也可以编程所有预先分配的导航键在插入模式下快速工作,而不用离开它)。如果我想一次移动一个字符,我只需在使用方向键的同时放松ALT键。

所有这些都是对.vimrc的简单修改。你可以发挥创意,做各种各样的事情来改进插入模式中的导航。否则,如果在长行中使用插入模式下的普通ole箭头键,则需要在右手按住方向键的同时,左手拿着一杯咖啡来啜饮。那要花很长时间!

顺便说一下,这个键已经与所有其他正常模式导航命令一起工作了,比如h,j,k,l和w, w, b, b, e和search: /,%等。除了它会自动退出插入模式,而无需按ESC键。因此,使用正常模式导航字符会让你陷入正常模式,直到你努力再按i, i, a, a, o, o, o,我发现这很容易忘记。

由于键盘上预先分配的导航命令:箭头:UP、DOWN、RIGHT、LEFT和PGUP、PGDN、HOME、END并没有对键做任何特殊操作,我发现我不妨将它们映射到.vimrc中,以帮助我在插入模式下导航,同时保持在插入模式下。而且,重申一下,它对我很有帮助,因为我处理的是非常长的文本文档,这些文档有一整段的逻辑线,这些逻辑线跨越了很多视觉线,而方向键和h、j、k、l并不表示视觉线。这在插入模式和正常模式中修复了这个特定的问题。

我把这归功于我在Kim Schulz的HACKING VIM 7.2一书中找到的知识