输入模式

进入输入模式

输入 i .

或输入 a .

这里,输入 i 是在字符前开始插入,输入 a 是在字符后开始插入。直到输入 ESC 退回到命令模式。

删除当前光标字符并进入插入模式(替换字符)

输入 s .

这里注意 是小写的 s ,这个命令和 R 不同, R 是覆盖式的取代并不切换模式, s 则是插入式的取代,相当于输入 x 删除一个字符,再输入 i 进入插入状态。

清空当前行并进入插入状态(替换当前行)

输入 cc .

或输入 S .

这里,第二个是大写 S 。这个命令的效果相当于 dd 删除一行并且在原来行的位置上面插入一个空行,光标放在空行上面再进入插入状态。 这里和 c 相关的操作与和 d 相关的操作类似,不过最后 c 操作会进入插入模式。

清空一个字(替换一个字)并进入插入状态

输入 cw .

这里, cw 替换一个英文字(word),中文不适用。(change)相当于用 dw 删除一个词,然后进入插入状态。

取代至行尾并进入插入状态

输入 C

或输入 c$

这里,注意第一个是大写 C ,第二个是小写 c .这个命令会把当前光标(包含光标下字符)至行尾内容删除在进入插入状态。即相当于 D 之后进入插入状态。

取代至行首并进入插入状态

输入 c0 .

或输入 c^ .

这里,将会把当前光标(不含光标下字符)至行首内容删除。经过实践,发现两者区别是 c0 取代至行最开始无论原来行以什么字符开始,而 c^ 则当原来行以空白开始的时候,不会删除开头的那几个空白。删除之后,两者都自动进入插入状态。

其它

总结一下, 我们可以结合后面这样理解:

  • s 操作类似 x ,不过最后也进入插入模式,一般是单字符的命令
  • c 相关的操作类似 d ,不过最后进入插入模式,一般是多字符的命令(即 cc , dd , cw , dw 等)

删除

删除一个字符

输入 x

注意:结果是光标所处的字符的消失,后面的文字左移动,假如没有任何文字了,喇叭就叫,同时将删除的内容保存到剪切板中。如果x前面有数字N那么就是重复N次。

删除当前行

输入 dd

注意: 可以跟数字,(如: 5dd 将删除 5 行),同时将删除的内容保存到剪切板中。

删除从光标到行尾

输入 D

或输入 d$ .

这样,将当前光标(包含当前光标所在的内容)一直到以后的内容全部删除。

删除到当前词尾

输入 dw .

删除整个单词

输入 daw .

删除当前字符

输入 dl .

删除当前光标至 text 之间的文本:

输入 d/text .

这样, 删除从文本中出现 text 中所指定字样的位置,一直向前直到下一个该字样所出现的位置(但不包括该字样)之间的内容。

其它

总结一下,上面许多例子实际是 d{motion} ,即 d--删除对象 的命令, d 命令的右边要有一定的文字对象,文字对象就是控制光标移动的那些字符。

例如

w  表示到下一个单词首,那么  dw  将删除光标至当前单词尾;
同理, 5w  表示前进 5 个单词,那么  d5w  将删除他们( daw 比较特殊,表示delete a word)。

用"数学语言"描述,上面的删除范围是:[光标起始,光标终点)。也可用 d /text 删除从文本中出现 text 中所指定字样的位置,具体需要实践。 c 也有相应的 c{motion} 不过删除之后紧接着会进入插入模式的。

复制

复制当前行

输入 yy

或输入 Y

注意: 可以跟数字,(如: 5yy 将复制当前和后面的共5 行)到剪切板中。

复制当前光标到词尾

输入 yw .

复制这个单词

输入 yaw .

复制书签 a 和当前光标之间内容

输入 y`a .

这样,可以利用标签进行成块数据复制,需要注意的是,这里 `a 是反引号的,复制的内容包含设置书签时所在光标的字符,但不包含当前光标所在字符。

复制当前光标行和书签 a 所在行之间内容

输入 y'a .

这样包括当前光标行以及书签行在内的两行之间的内容全被复制,这里 ='a= 用的是单引号。

其它

这里的例子与前面的 d--删除对象 是一样的道理,不多说了。

粘贴

粘帖上次删除或复制的内容

输入 p .

注意:按 p 会将最近删除或复制的粘贴(vim中的删除一般就是我们平时所说的“剪切”)。

交换两个字符位置

输入 xp .

这里,实际是先 x 删除字符,再 p 粘贴先前删除的字符。

上下两行调换

输入 ddp .

这里,原理同 xp .

指定范围的编辑

n,m 之间的内容拷贝到k行的下面(空格可省略)

输入 :n,m co k

或输入 :n,m copy k .

只复制不粘贴第 n,m 行之间的内容(空格可省略)

输入 n,m y

剪切 n,m 行之间的内容到剪切板中(空格可省略)

输入 :n,m d

或输入 :n,m delete k

把=n,m= 之间的内容拷贝到 k 行的下面(空格可省略)

输入 :n,m m k .

或输入 n,m mo k .

或输入 :n,m move k .

粘帖到 k 行下

输入 :k pu .

或输入 :k put .

后面可以接寄存器名字。

可视模式

进入可视模式

输入 v

或输入 V

这里,进入可视模式后,如果进行移动操作(例如 hjkl 等),将会高亮显示进入可视模式时的光标所在字符(行)和你移动之后的字符(行)之间的部分表示你选择了这块文本。输入 v 是按字符单位进行选择,输入 V 是按行单位进行选择。选择之后,可以对选中文本进行操作。

选择一块数据

  1. 输入 C-v .
  2. 按方向键选择相应的数据。

这里,按下方向键之后,选择的数据会以列为单位选择,不想 v 是以行为单位了。实践一下就知道我说的是什么意思了。

剪贴可视模式选择的内容到剪贴板

输入 d

拷贝可视模式选择的内容到剪贴板

输入 y

剪贴可视模式选择的内容到剪贴板并且进入插入模式

输入 c

如果你很清楚的知道你想拷贝或者剪切什么,那你根本就不需要进入可视选择模式。这样也会节省时间。

所选内容向右移动 nTab

输入 [n]Shift > .

这里 Tab 次数用 [] 括起来,也可以没有这个 [n] 代表只有一个 Tab.

所选内容向左移动 nTab

输入 [n]Shift < .

这里 Tab 次数用 [] 括起来,表示也可以没有这个 [n] ,即只有一个 Tab .

替换相关

替换当前光标一个字符步骤

  1. 定位到待替换字符 A.
  2. 输入 r .
  3. 输入要替换成的字符 B

这样,字符 A 就变成了字符 B

替换多个字符步骤

  1. 输入 R
  2. 定位到将要被替换的字符 A.
  3. 输入要替换成的字符 B.
  4. 如果继续替换,则再次回到2执行否则输入 [ESC] 完成替换。

这样就完成了多个字符的替换。

在当前行替换全部

输入 :s/old/new/g

这里,可以把当前行的所有字符串 old 替换为 new

在当前行替换第一个

输入 :s/old/new

这里,将只替换当前行第一个匹配的字符串 oldnew

指定范围的替换

输入 :#,#s/old/new/g

这里, #,# 表示表示范围的两个行号,命令会把两个行号之间的所有字符串 old 替换为 new

整个文件的替换

输入 :%s/old/new/g .

这里将把整个文件中的所有字符串 old 替换为 new

忽略大小写的替换

输入 :%s/old/new/gi .

这里加上 i ,替换时忽略大小写即大小写是一样的。

带有确认的替换

输入 :s/old/new/gc .

这里,加 c 仅以当前行范围内替换确认进行举例了,其他范围类似。结果是,在替换字符串 oldnew 之前,将会询问( replace with to (y/n/a/q/l/^E/^Y) )。 输入 y 表示替换当前这个, n 表示这个不要替换, a 表示全部替换, q 表示退出,不替换了, l 表示把当前这个替换后就退出, ^E ([Ctrl]e,好像大小写都可以)表示向下滚动一行, ^Y ([Ctrl]y,好像大小写都可以)表示向上滚动一行。

令游标所在处之大小写互换

输入 ~ .

这里,只适用于英文,当然不要忘记输入的时候按 SHIFT .

为光标下或者光标后面的数字增1

输入 CTRL-a .

这样,当前光标或者光标后面有数字的话,光标就会跳到那个数字的地方,并给那个数字增1。例如有一个 326 那么就会变成 327.

上下两行合并

输入 J .

这里实际就是把当前行的换行符号变成了空格,这样下一行就合并到这行中了。

撤销刚才的操作

输入 u

恢复

输入 CTRL-r

u 相反。

重复上次编辑

输入 .

寄存器

关于寄存器相关的命令帮助

输入 :help redo-register

或寄存器的其它引用方式 :h i_CTRL-R

数字寄存器

vim中最常用到的寄存器,当不指定寄存器时,复制操作的内容被保存到"1,删除操作的内容被压到"2,同时原先"2的内容转到"3,依此类推,原先"8转到"9,原先"9的内容丢失。如果指定操作的寄存器,如 ="ayy= 和 ="bdd= ,则上述的数字寄存器无影响(有些例外情况,详见Vim手册,这里我发现用 ="add= 等删除的时候,"d,"1,""三个寄存器内容就都一样是最近的操作了)。

寄存器""

未命名寄存器""保存最近一次复制或删除操作内容,无论是否指定寄存器。

寄存器".

保存上一次插入的文字,也就是你上次切换到插入状态下(包括临时切换的CTRL-o),输入的文字。

寄存器"%

保存当前文件名,"#保存替换文件名(即上次操作的文件)文件是相对vi当前路径的路径名。

寄存器"_

这是一个特殊的“黑洞”寄存器"_,当指定其进行删除时,包括""在内的任何寄存器都不受影响,当然,你也没法把掉进黑洞的物质p出来。

寄存器"/

vim将最近一次的搜索文字保存在"/中,对应的变量@/决定了 n/N 命令和查找高亮的对象。@/被所有buffer共享,也就是说在一个buffer里进行新的查找,其它buffer的匹配高亮和 n/N 命令也随着更新。

寄存器"=

这个寄存器与众不同,它不存储文本,而是在可以使用寄存器的场合中提供了用表达式求值并取得其结果的途径。简单的说,就是在指定"=时,Vim会提示输入一个表达式,然后将求值结果返回,至于这串文本如何使用,就看在什么地方使用了。

寄存器":

这个寄存器记录最近一次运行的命令行命令,因此 @: 是重复上次的命令行操作(也就是 : 提示的命令而不是 ddyy 等)。值得注意的是, @x 宏运行的是normal命令,而@:运行的是Ex命令。如果某个寄存器"x保存的是Ex命令,你可以用 :@x 来执行。比如在测试vimrc中的某条命令时,先 yy ,然后 :@"= 执行。总之不管什么是normal命令和Ex命令?了,":寄存器里面存的就是命令行:提示下输入的命令,其他寄存器(假设为x)内容如果是 =:set nu 那么可以直接由@x来运行,如果是 set nu ,那么需要用 :@x 来运行。

"*和"+寄存器

两个特殊的“全局性”寄存器:帮助入口 :help clipboard .

在vi中用 :reg 看一下,有没有"+一项,如果没的话,就不支持对"+的访问,需要安装一下vim-gtk(或者vim-full).
$apt-get install vim-gtk

"+寄存器,是一个“全局性”的寄存器,对应于X11的剪切板,当使用vi和其他gui程序进行互相复制粘贴的时候,实际使用的就是"+寄存器(xterm不行,xterm的双击自动复制是用"*寄存器)。

"*寄存器,也是一个“全局性“的寄存器,可以在vi和其他vi程序之间互相访问或者vi和xterm等一些特殊的程序之间互相访问(个别时候没有"+的时候也充当X11剪切板)。

察看当前各个寄存器中的内容用

输入 :display .

或输入 :di .

或输入 :reg .

察看寄存器1的内容

输入 :display 1 .

或输入 :di 1 .

总之,diaplay后面接寄存器的名就可以显示寄存器的内容了。

将当前行放入寄存器a中

输入 ="aY= .

或输入 ="ayy= .

这里,vim 有多个所谓寄存器来寄存剪切的内容,寄存器引用要使用"r(r是寄存器名字).

粘贴寄存器a的内容

输入 "aP .

粘贴寄存器中的内容

输入: <C-r>

或输入: <寄存器名>

这里,寄存器名可以是26个字母或者数字等等,具体应该参见编辑相关里面的寄存器相关操作。例如我在输入模式下想要把寄存器a中的内容粘上去,就输入 <C-r> 再输入 a .

粘贴1号寄存器中的内容(并重复循环粘贴)

输入 "1p .

这里,若 p 命令时指定数字寄存器,则后续的.命令会自动将数字寄存器的编号加一,也就是说执行 "1p 之后,第一个 . 执行的是 "2p ,依次类推,到最后一个之后就会粘贴空的内容了。

粘贴之后光标停留在粘贴出的文字之后

输入 gp .

或输入 gP .

这里结果相当于先 pdw .问题是要重新定位需要删除的部分。与 p/P 功能一样,不过光标停留在粘贴出的文字之后,便于随后的删除。( pP 区别是: P 粘贴之后,光标位置不变,而 p 粘贴之后,光标始终随着刚在被在前面粘贴的字符向前走)

在插入模式或命令行中或搜索时候的 / 等之后插入寄存器"x的内容

输入 CTRL-r x .

这样寄存器"x的内容将插入到相应的位置,x是寄存器名称。

在命令行中直接引用寄存器x内容

输入 :@x .

这样,相当于把寄存器x中的内容输入进去了,x同样是寄存器名称,这里使用@把寄存器当作变量来使用可以用于脚本。

使用"= 寄存器十六进制转十进制

  1. 插入模式下输入 CTRL-r
  2. 输入 =
  3. 输入 0x1234, 这样,回车之后就会自动插入十进制的4660了。

在不同vi程序之间互相复制粘贴

  1. 在vi中输入 v 之后,选择一段文字(或者定位到某一行)。
  2. 在vi中输入 "*y (或者行复制用 "*yy ), 这样就把内容复制到寄存器"*中了。
  3. 在另一个vi输入 "*p , 这样就把刚才vi中复制到"*中的内容粘贴出来了。

使用vi和其他图形程序(例如gedit)之间剪切板互访

  1. 在gedit中用 鼠标选中文本 ,并且 右键->复制
  2. 在vi中输入 "+p 。
  3. 这样就将之前在gedit中复制的文本粘贴到vi中了,注意这里是三个字符 '"','+','p'.
  4. 在vi中输入 v 之后,选择一段文字(或者定位到某一行)。
  5. 在vi中输入 "+y (或者行复制用 "+yy ), 这样就把相应的内容复制到寄存器"+中了。
  6. 在gedit中 右键->粘贴 , 这样就把vi的寄存器"+中的内容粘贴上去了。

设置 "* 寄存器共享且默认

输入 :set clipboard=unnamed .

设置之后,使用vi中的复制命令的时候,会自动把内容也放在 "* 寄存器中。粘贴的时候,也自动使用 "* 寄存器了,而不是默认的数字寄存器。这样多个vi程序之间可以方便地互相复制粘贴了,而不用在加 "* 前缀指定 * 寄存器了。

当然如果另外一个vi程序没有设置这个选项那么它还是要用 "* 前缀的。去掉这个设置好像是 :set clipboard = .

寄存器与宏是紧密相连的宏的相关帮助命令入口

:h q
:h @
:h :@

宏是Vim中非常重要的功能,用来重复执行多个连续操作。当包含移动、查找、插入、修改等不同类型的命令时,宏显得尤其方便,很多时候用 :s:g 难以实现的功能,宏都可以轻松搞定。

q 录制宏实际上是将键盘输入记录到寄存器的过程,而用@运行宏则是将指定寄存器内容作为normal命令执行的过程。 q 命令提供了“所做即所得”,但有时候直接修改寄存器更为方便。比如当你录制完一个非常复杂的宏,但发现有一个小毛病(例如应该是 de 而不是 dw ),不必重新录制一遍,只需要将寄存器的内容p出来修改好再y回去。

宏有一些运用的技巧

  • 容许错误: 录制过程中如果有错不必放弃重来,可以undo或,只要保证这些操作和处理文本无关,寄存器里有些乱七八糟的东西又何妨。
  • 分而治之: 当录制一个很复杂的宏时可以考虑分成几段,比如qa第一步,qb第二步,然后在qc中调用a和b,各个击破简单易行。
  • 重复运行: @@命令可以重复上次的宏调用。
  • 另作它用: q命令是向寄存器里录入命令,你也可以什么都不录!用处例如清除"a最快的方法:qaq。

假设进行的操作为 <某操作> ,使用宏你可以重复多个不同的操作.

使用宏的步骤如下

  • 输入 qa: 这里,开始把一段宏记录入寄存器变量 a ***有26个可用的寄存器供你记录宏。
  • 输入 <某操作>: 这里,象平常一样键入要进行的操作, 只是这些操作都会被Vim记录进前面名为 a 的宏中。
  • 输入 q: 这里再次再下 q 键, 就结束了宏 a 的录制.
  • 输入 @a: 这里,重复执行你刚才记录的那些操作时只要使用 @a 命令,引用那个宏。可以前面加数字前缀表示执行次数。

重定向

信息重定向会把你输入的命令的输出重定向到指定的寄存器或者文件中。帮助入口是 :help redir .

把命令的输出重定向到寄存器中

  • 输入 :redir @a: 这里,指定输出会定向到寄存器a中,当前显示中会看到相应的输出。
  • 输入 <你要输入的一个或者多个命令>: 这里,命令可以是命令状态下的命令如搜索命令 / 等,用 : 引出的命令等,甚至进入插入提示的–INSERT–。
  • 输入 :redir END: 这里,小写的也行。

执行以上三步之后,那些命令的输出了被显示的同时也存在了寄存器"a中。

把命令的输出重定向到文件中

  • 输入 :redir >>file: 这里,指定输出会定向到file中,当前显示中会看到相应的输出。使用 >> 表示追加,使用 > 表示清空并加入。
  • 输入 <你要输入的一个或者多个命令>: 这里,命令可以是命令状态下的命令如搜索命令 / 等,用 : 引出的命令等,甚至进入插入提示的–INSERT–。
  • 输入 :redir END: 这里,小写的也行。

执行以上三步之后,那些命令的输出了被显示的同时也存在了文件file中。