0%

vim(1)

Vim解决问题的方式

.命令

  • 通过.命令重复之前的操作
  • 通过x命令删除当前光标所在字符
  • 通过u命令撤销修改
  • 通过dd命令删除整行
  • >G命令增加从当前行到文档末尾处的缩进层级

不要自我重复

  • A命令可以进入插入模式并把光标移动至行尾(相当于a$)
    如果想在每行末尾添加一个分号可以执行A j . . .
  • C = c$ 删除光标到行尾字符,并进入插入模式
  • s = cl 删除光标所在字符,并进入插入模式
  • S = ^c 删除整行,并进入插入模式
  • I = ^i 将光标移至行首,并计入插入模式
  • o = A<CR> 另起一行(在当前行下方),并进入插入模式
  • O = ko 在当前行上方

以退为进

  • 通过f{char}来快速跳转到特定字符
  • 通过;来重复之前的f命令3

执行、重复、回退

目的 操作 重复 回退
做出一个修改 {edit} . u
在行内查找下一指定字符 f{char}/t{char} ; ,
在行内查找上一指定字符 F{char}/T{char} ; ,
在文档中查找下一处匹配项 /pattern n N
在文档中寻找上一处匹配项 ?pattern n N
执行替换 :s/target/replacement & u
执行一系列修改 qx{changes}q @x u

查找并手动替换

  • 在单词上使用*命令可以查找当前光标下的单词
  • 使用n可以移动到下一个
  • 使用cw可以删除从光标位置到单词结尾间的字符

认识.范式

用一次按键移动,另一次按键执行


普通模式


停顿时请移开画笔

在其他编辑器中大多数时间都处于类似vim的插入模式中,而在vim中大多数时候处于普通模式,作者使用了一个非常好的比喻:用画笔作画就像是插入模式,而作家在思考构图,选择颜色时是不会把画笔停在画布上的。
普通模式很明显与思考的情况很契合,所以使用vim应该适应普通模式带来的变化。


把撤销单元切成块

在其他编辑器中,输入一些词后使用撤销命令,可能会撤销最后输入的词或字符,然而在Vim中,我们自己可以控制撤销的粒度。

u键会触发撤销命令,它会撤销最新的修改。一次修改可以是改变文档内文本的任意操作,其中包括在普通模式、可视模式以及命令行模式中所触发的命令,而且一次修改也包括了在插入模式中输入(或删除)的文本,因此我们也可以说,i{insert some text}<Esc>是一次修改。
所以养成输入完一些内容后退出插入模式也是应该养成的习惯。


构造可重复的修改

如何删除一个单词(当前光标在单词尾部)

  • db删除从光标起始位置到单词开头的内容x删掉剩余的字母
  • b将光标移动到单词开头dw删除从光标到结尾的单词内容
  • daw删除整个单词

用次数做简单的算数运算

很多命令我们都可以通过在命令前面加数字来重复命令
*<C-a><C-x>命令分别对数字执行加和减操作,如果当前光标位置不是数字它会在本行向后查找第一个数字

  • 如果在上面的两个命令前加数字就可以实现增加减少对应数值
  • yyp命令可以复制当前行

    vim遇到0开头的数字会按8进制分析


能重复,就别用次数

通常来说重复能带来更多的复用性和可操作性(方便撤销),但是如果是确定的操作,比如一个数字加减多少或者将两个单词改成其他单词,这种情况下使用次数就要优于重复了。


双剑合璧,天下无敌

操作符 + 动作命令 = 操作

d{motion}命令可以对一个字符(dl)、一个完整单词(daw)或一整个段落(dap)进行操作,它作用的范围由动作命令决定。c{motion}y{motion}以及其他一些命令也类似,它们被统称为操作符(operator)。可以用:h operator命令来查看完整列表,下面是一些比较常见的操作符。

命令 用途
c 修改
d 删除
y 复制到寄存器
g~ 反转大小写
gu 转换为大写
gU 转化为大写

|增加缩进
<|减小缩进
=|自动缩进
!|使用外部程序过滤{motion}所跨越的行

下面是一些比较常见的动作命令

命令 用途
l 一个字符
w 从当前位置到光标末尾
b 从当前位置到单词首部
aw 整个单词
ap 整个段落
$ 到行尾
^ 到行首
it 标签中内容

当一个操作命令被重复两次时会作用于当前行,所以dd是删除当前行,>> 是缩进当前行。gU命令(gu)是特殊情况,你既可以使用gUgU也可以使用gUU

输入操作符后等待接受动作命令的状态可以被称为待决模式,当这个模式被激活时也可以通过<Esc>键退出


插入模式


在插入模式中可即时更正错误

在插入模式下,退格键的作用如你所愿,它删除光标前的字符。另外,还可以用下面这些组合键。

按键操作 用途
<C-h> 删除前一个字符(同退格键)
<C-w> 删除前一个单词
<C-u> 删至行首

返回普通模式

返回普通模式的经典方式是使用<Esc>键,但是它不太好按,作为替代可以使用<c-[>

按键操作 用途
<Esc> 切换到普通模式
<c-[> 切换到普通模式
<c-o> 切换到插入-普通模式

插入普通模式是可以让用户在插入模式中临时切换到普通模式,然后在输入一个命令后回到插入模式
例如zz命令可以重绘屏幕,并把当前行显示到屏幕正中,使用<C-o>zz可以很好的滚动屏幕。


不离开插入模式,粘贴寄存器中的文本

使用yt命令可以将文本复制到寄存器中,通过<C-r>命令可以从相应的寄存器中粘贴文本。
<C-r>命令会粘贴换行和缩进,如果想要粘贴纯文本可以使用<C-p>命令。


随时随地做运算

使用<C-r>=可以访问表达式寄存器,它可以执行vim命令并返回结果,也就是说我们可以通过它来完成计算如6*35然后使用回车让它插入到文档中


插入非常用字符

按键操作 用途
{123} 以十进制字符编码插入字符
u{1234} 以十六进制字符编码插入字符
{nondigit} 按原义插入非数字字符
{char1}{char2} 插入以二合字母{char1}{char2} 表示的字符

用二合字母插入非常用字符

二合字母用起来很方便。在插入模式中,只需输入<C-k>>{char1}{char2}即可。因此,如果想输入以二合字母?I表示的“¿”字符,可以简单地输入<C-k>?I
Vim在选择组成二合字母的两个字符时,尽量使之具有描述性,这样就更容易记住它们,甚至也能猜出其含义。例如,左右书名号《和》分别以二合字母<<及>>表示,普通分数(或常用分数)½、¼和¾则分别以二合字母12、14和34来表示。


用替换模式替换已有文本

使用R命令可以进入替换模式,进入替换模式可以使用输入的字符替换掉已有字符。
在vim中tab的长度是8位,使用R进入的替换模式会把tab当成一个字符,而使用gR可以进入虚拟替换模式,他会像屏幕显示的那样进行替换(前7位为空,第八位为tab)
vim也提供了单次替换模式r{char}gr{char}可以在替换一个字符后回到普通模式


可视模式


深入理解可视模式

某些可视模式命令执行的基本功能与普通模式相同,但操作上有些细微的变化。例如,在这两种模式中,c命令的功能是一样的,都是删除指定的文本并切换到插入模式。不过,要指定其操作的范围,二者的方式却不甚相同。在普通模式中,先触发修改命令,然后使用动作命令指定其作用范围。在可视模式中,要先选中选区,然后再触发修改命令。这种次序颠倒的方式对所有的操作符命令都适用。对大多数人来说,可视模式的做法感觉起来更自然。
在一个典型的文本编辑器环境中,当选中一段文本后,再输入任意可见字符时,这些选中的文本将会被删除。虽然Vim的可视模式未遵从此惯例,但是其选择模式(Select Mode)却按此方式工作。根据Vim的内置文档所述,选择模式“类似于Microsoft Windows的选择模式”。在此模式下,输入的可见字符会使选中的文本被删除,同时Vim会进入插入模式,并插入这个可见字符。


选择高亮区域(三种可视模式)

Vim有3种可视模式。在面向字符的可视模式中,我们能够选择任意的字符范围,不论它是单个字符,还是位于一行内,或是跨若干行的指定字符范围,都没问题。该模式适用于操作单词或短语。如果我们想对整行进行操作,可以改用面向行的可视模式。而面向列块的可视模式则允许对文档中的列块进行操作。

激活可视模式
命令 用途
v 激活面向字符的可视模式
V 激活面向行的可视模式
<C-v> 激活面向列块的可视模式
gv 重选上次的高亮区域
在可视模式间切换
按键操作 用途
<Esc>/<C-[> 回到普通模式
v/V/<C-v> 切换到普通模式(在对应的面向字符可视模式时、面向行的可视模式和面向列块的可视模式中使用时)
v 用途
V 用途
<C-v> 用途
O 用途
切换选区的活动端

高亮选区的范围由其两个端点界定。其中一端固定,另一端可以随光标自由移动,可以用 o 键来切换其活动的端点。在定义选区时,如果定义到一半,才发现选区开始的位置不对,此时用这个键会很方便,不用退出可视模式再从头开始,只需按一下 o ,然后重新调整选区的边界即可。


重复执行面向行的可视命令

在可视模式下执行完一次操作会回到普通模式而.命令可以重复之前执行的命令


只要可能,最好用操作符命令,而不是可视命令

当一条可视模式命令重复执行时,它会影响相同数量的文本
作为一般的原则,在做一系列可重复的修改时,最好首选操作符命令,而不是其对应的可视模式命令


用面向列块的可视模式编辑表格数据

1
2
3
4
Chapter         Page
Normal mode     15
Insert mode     31
Visual mode      44

像这样一个格式我们可以使用如下操作:

  1. 将光标移动到第一行中间
  2. 使用<C-v>3j选中3列
  3. 使用x...删除一个空格并重复三次
  4. 使用gv重复选择刚才的高亮区域
  5. 使用r|将选中的空格替换为|
  6. 使用yyp添加一行
  7. 使用Vr-将添加的行替换为-

修改列文本

vim进入列选择模式可以同时操作很多列,如果使用c进入插入模式也可以同时在多行添加内容,但是在插入模式时变动并不会添加到屏幕上,在退出插入模式后他们才会出现


在长短不一的高亮块后添加文本

为长短不一的高亮块后添加文本可以采用如下方式

  1. 使用<C-v>进入块列可视模式
  2. 使用j选中多行
  3. 使用$选择到行尾
  4. 使用A进入插入模式

如果是想在行首只需用^替换$,用I替换A


命令行模式


认识Vim的命令行模式

命令 用途
:[range]delete [x] 删除指定范围内的行[到寄存器x中]
:[range]yank [x] 复制指定范围的行[到寄存器x中]
:[line]put [x] 在指定行后粘贴寄存器x中的内容
:[range]copy {address} 把指定范围内的行拷贝到{address} 指定的行之下
:[range]move {address} 把指定范围内的行移动到 {address} 指定的行之下
:[range]join 连接指定范围内的行
:[range]normal {commands} 对指定范围内的每一行执行普通模式命令 {commands}
:[range]substitute/{pattern}/{string}/[flags] 把指定范围内出现{pattern}的地方替换为{string}
:[range]global/{pattern}/[cmd] 对指定范围内匹配{pattern}的所有行执行Ex 命令{cmd}
vim命令行模式中的特殊按键

有些命令在插入模式和命令行模式中可以通用。例如,可以用<C-w><C-u>分别删除至上个单词的开头及行首,也可以用<C-v><C-k>来插入键盘上找不到的字符,还可以用<C-r>{register}命令把任意寄存器的内容插入命令行。然而,有些命令行模式中的组合键在插入模式中不存在。


在一行或多个连续行上执行命令

用行号作为地址

如果输入一个数字vim会把它当做行号并移动到指定行,比如删除第三行命令模式是:3d而普通模式是3Gdd

用地址指定一个范围

:2,5这代表2到5行
.可以代表当前行,$代表最后一行,如:.,$代表从当前行到最后一行
%代表当前文件中的所有行

用高亮选区指定范围

可以用高亮选区选定一个范围然后再使用:执行一个命令
在按下:后会显示:'<,'>,符号'<是代表高亮选区首行的位置标记,'>则代表高亮选区的最后一行,这些位置标记即使在退出可视模式后仍然存在。如果尝试在普通模式下直接运行 :'<,'>p,它会始终回显上一次高亮选区选中的内容。

用模式指定范围

可以用模式来指定范围,:/<html>/,/<\/html>/p,这个指令指定的范围是连个html标签中的内容。

用偏移对地址进行修正

假设想对位于<html></html>之间的每一行都运行一条Ex命令,但是不想包括<html></html>标签所在的行,那么可以为之加上偏移。

1
:/<html>/+1,/<\/html>/-1p

这样选中的就是html标签中的内容

总结
符号 地址
1 文件第一行
$ 文件最后一行
0 虚拟行,位于文件第一行上方
. 光标所在行
‘m 包含位置标记m的行
‘< 高亮选区的起始行
‘> 高亮选区的结束行
% 整个文件

使用:t:m命令复制和移动行

命令 用途
:6t. 把第六行复制到当前行下方
:t6 把当前行复制到第六行下方
:t. 为当前行创建一个副本(类似于普通模式的yyp)
:t$ 把当前行复制到文本末尾
:'<,'>t0 把高亮选中的行复制到文章开头

:t.命令会创建一个当前行副本,另外一种做法则是用普通模式的复制和粘贴命令(yyp)来达到同样的效果。这两种复制当前行的技术有个需要关注的差别:yyp会使用寄存器,:t.则不会。因此,当我不想覆盖默认寄存器中的当前内容时,有时会使用:t.来复制行。
先跳到想复制的行上(6G),复制该行(yy),快速跳回原先的位置(<C-o>),然后再用粘贴命令(p)创建一个副本。由此可见,在复制距离较远的行时,:t命令通常更加高效。

:m命令移动行

将某一行移动到行尾可以这么操作:

  1. 高亮选区
  2. :m$

也可以使用dGp

使用@:可以重复上次的ex命令


在指定范围上执行普通模式命令

如果想在一系列连续行上执行一条普通模式命令,可以使用:normal命令。
如果想在所有行后加入分号可以如下操作:

  1. A
  2. jVG
  3. :normal

也可以直接使用:%normal A;命令来完成操作


重复上次的Ex命令

@:命令可以重复上次的Ex命令


自动补全Ex命令

使用<Tab>可以自动补全命令,并且使用<C-d>可以查看可用的补全列表


把当前单词插入命令行

在Vim命令行下,<C-r><C-w>会复制光标下的单词并把他插入到命令行中。
例如我们想把所有的tally换成counter可以这么操作:

  1. 在tally上使用*
  2. 使用cw更改单词为counter
  3. 使用:%s//<C-r><C-w>/g

回溯历史命令

使用<Up><Down>键可以回到更早的历史命令

结识命令行窗口

使用q:可以进入命令行窗口


运行shell命令

在命令行模式给命令加一个!即可运行外部shell命令

在编辑器中无法使用,不过多介绍


批处理运行Ex命令

在编辑器中无法使用,不过多介绍