Vim实用技巧

《Vim使用技巧》笔记

个人笔记

zc折叠代码,zv展开代码

结识.命令

. 命令可以让我们重复上次的修改,它是Vim 中最为强大的多面手。

在普通模式下,x命令会删除当前字符,.命令会重复上次命令,比如上次命令是x,那么.和x的效果是一样的。使用u命令来撤销上次修改,可以多次使用u命令。

>G命令会给当前行后的每行增加一个TAB缩进,在这之后使用.命令会进行重复>G,这样增加了很大的便利性。比如>Gj.j.j.会给每行多加一个缩进,j命令是移到下一行。

.号命令记录的是上次修改的命令。比如j只是移动光标到下一行,不涉及修改,所以不会被记录。
但是注意.号不会记录u命令。

不要自我重复

行尾添加分号,$到行尾,然后a;

a命令是在当前光标之后添加内容,而A命令则是在当前结尾添加内容,其实就是$a的合体。a和A都会导致进入insert模式。

那么如果想要对每行添加;,可以通过A;来添加第一行的分号,然后使用j,再使用.之后就是j.j.j.

以退为进

var tmp = a+b+c+d
要给上述代码中每个+前后添加一个空格,操作方式为首先执行f+,查找当前光标后的第一个+,然后s +,s是删除当前光标下元素并到insert模式,然后+则是自动输入空格+空格,接着使用f+.来重复上述步骤。
可见先删一个元素并不是坏事,而是可以达到重复的效果。

f+是查找命令,使用;会重复上一次查找,所以以上命令又可进一步优化为;.

执行重复,回退

对于修改,可以通过u来进行撤销,而对于f+这种查找,可以使用,,该命令是反向查找上一次f+的字符。

如下表是可重复操作和响应的撤销命令:

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

查找并手动替换

*号可以查找当前光标出的字符串。在查找到后按下n就可以跳到下一个查找项。注意n是文档查找的重复,;是每行查找的重复,.是修改的重复。
cw会删除当前光标指向的单词

那么手动查找替换的命令就是先找到第一个预期的单词,然后*cwn.n.n.n.,在每次n.的时候都可以判断,当前是否要进行替换,如果不需要就可以nn.

.范式

一键查找,一键修改。这就叫装逼的.范式。

撤销单元切成块

u命令是撤销一次修改,比如i<修改>就算是一次修改。

好的方式是,在某一段时间调用一次或者回车命令换成o等。这样就将撤销变成了块状。

构造可重复的修改

如果当前光标指向某个单词的末尾,那么删除整个单词怎么做呢。
第一种方式是db删除光标前的单词,但不会删除当前光标的字符,然后x来删除最后的那个字符
第二种方式是b移动到单词头,然后dw删除整个单词。
第三种方式是daw直接删除,可以将daw理解为delete a word
最好的方式是第三个,因为他是一个命令,可以发挥.号的优势。

用次数做简单的算数运算

yyp用来复制一行

数字会将当前光标处的数字减去该数字,数字则是加上某数字。

能够重复,就别用次数

删除两个单词d2w理解为delete 2 word.还可以是2dw。还有一种是dw.

虽说推荐使用dw.但我觉得可以按照自己意愿来。

到这就应该明白,次数可以用于命令前,表示后边的命令连续执行多次。

天下无敌。。

Vim的操作方式是操作方式 + 动作命令
比如dld就是操作方式,表示删除,l表示动作命令,这个地方为一个字符。同样的还有daw删除一个单词,dap一个段落等。

那么比如现在有一个操作方式的命令gU表示转换为大写,那么gUaw就是将一个单词转换为大写。

注意操作方式只是操作,动作命令才会指定范围。

Vim有一个规则是,当一个操作符命令连续敲击两次的时候,就会作用于当前行,所以dd就是删除当前行。>>就是缩进当前行,gUgU/gUU大写当前行。

Vim中表示操作的命令

命令 用途
c 修改
d 删除
y 复制到寄存器
g~ 反转大小写
gu 转换为小写
gU 转换为大写
> 增加缩进
< 减小缩进
= 自动缩进
! 使用外部程序过滤{motion}所跨越的行

在插入模式中可随时更换错误

插入模式下:删除前一个字符,删除前一个单词,Ctrl+u删除到行首

替换模式

R进入替换模式

可视模式

v进入可视模式,通过iw选取当前单词,c删除当前选取的字符,并进入插入模式。

可视模式有三种

  • v是进入面向字符的可视模式
  • Ctrl-v是面向列块的可视模式
  • V(shift-v)是面向行的可视模式

o 原先高亮不变,该命令会进行就行选区
vit可以方便的选择标签内的内容
U将字母转换为大写
ctrl-v面向列可视模式,然后使用3j连续选择3列,之后使用x...连续给3列绘制空格,之后gv重新上次高亮区域,再之后输入r|可以给3行都添加|符号
Vr-面向行的可视化,并用-替换所有的字符。
ctrl-v面向列可视,然后jje可以下移两个行,e会选择单词尾部,之后通过c删除当前高亮,并进入插入模式,添加字符后,按esc才能看到所有行都被替换了。
Ctrl-v -> jjjj$ -> A;给每行添加;符号,$是将选择区域跳到行尾。

a``iA``I都是将普通模式切换到插入模式,但是a,i是将光标切换到当前字符后或尾,A,I是将光标切换到行尾或行开头。

命令模式

命令 用途
:[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}

如果不注明范围,即ragne的值,则默认是当前行。
p是print的简写,所以:4p:4print命令是一样的,都是打印第4行的内容

range是可以通过行号来指定,如4就表示第四行,而4,6表示4到6行,所以:4,6p就会打印第4行到第6行的内容。为了方便起见{start},{end}表示范围
.代表当前地址$代表文件末尾,所以:.,$p就表示打印当前行到文件末尾的内容。
%代表当前文件中的所有行,所以%p表示打印当前文件中的所有内容,所以到这就可以知道::%s/source/target/g为什么可以进行全局替换,原因就是%表示当前文件的所有行。
同样和p一样的还有d表示delete
2G表示跳到第2行,这个时候运行VG就会选取到文件末尾,然后按:进入命令行模式就会出现代表当前内容的字符'<,'>,输入p就会打印出来。其中'<表示高亮区的首行的位置标记,'>代表高亮区的最后一行。

://,/<\/html>/p表示从标签到结束的内容。
在范围中也可以指定+-操作,比如//+1,/<\/html>/-1p,而通用格式就是{start}+n,{end}-m[action]
那么对当前行后的n行操作,就可以这么写:.,.+np

范围操作表如下:

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

:t:copy的简写模式,:m:move的简写模式
除了。:{start},{end}t.就表示把范围内的内容复制到当前行的后边。注意是复制到当前行的后边。

:normal是对范围内所有的行进行某一操作,比如想在文件中的每一行的末尾添加一个;号,可以执行%normal A;而相对的命令,也可以使用.来表示。
那么对每行输入注释的话就可以用%normal i//命令。
当使用:n来进行快速跳转后,可以使用ctrl+o来快速返回原先的行。

重复命令

@:重复上次命令行中的命令。
. 重复上次正常状态的命令

命令模式自动补全

按tab会进行命令自动补全,但是如果没有相应的命令就会显示一个特殊符号,而使用ctrl+d会将所有的能够补全的命令显示出来。

光标移动到某个单词上,使用*命令就会高亮所有的当前单词,再次按*会跳转到下一个单词处。

在命令模式下,使用ctrl+r``ctrl+w会把当前单词直接复制到命令行上。

q:进入命令行窗口,命令行窗口也是可以编辑的,比如在某行输入A就会跳到当前行的最后并进入编辑模式,使用J就会把下一行的内容移到上一行。
想要退出命令行窗口可以按回车执行某命令,或者使用:q来退出。

在命令行模式下,可以使用ctrl+f切换到命令行窗口。
q/是进入搜索内容的缓冲窗口。

执行shell

在命令模式中也可以执行shell命令,如:!ls执行ls命令,显示当前目录中的文件。注意:ls调用的是vim中的ls命令。

%表示当前文件,比如当前文件为test.py,想要在编辑后执行py程序,就可以直接在命令行中调用:! python %
但是:!这种方式只能执行shell的一次性命令,如果想要执行多次命令,可以使用:shell来启动一个交互的窗口,执行后看起来像是退出,其实只是开启了一个shell,再执行exit就会回到当前编辑的文件中。

ctrl+z可以挂起当前的进程,所以在vim中执行该命令就可退出,执行jobs可以查看当前被挂起的进程,执行fg可以恢复进程。

命令 用途
:shell 启动一个shell
:!{cmd} 在shell中执行cmd
:read !{cmd} 将shell执行的结果输出到当前文件的光标处
:[range]write !{cmd} 将range处的内容作为cmd的输入

:[range]!{filter}使用外部程序过滤range

最后一行如:79,84!sort就会对79~84行进行排序,其实79,84sort也可以实现这样的功能,只不过是!的包装而已,加个!可以使用外部程序。

文件

vim可以打开多个文件,但是当前编辑的只有一个文件,比如vim *.txt可以打开所有txt文件,这些文件都处于内存中,使用:ls可以显示当前打开的所有文件,然后使用:bnext可以跳到下一个文件中,使用ctrl+^可以切换文件。
:bnext到下一个文件中,:bprev到上一个文件中,:bfirst,:blast分别跳到文件列表的开头或结尾。
:buffer {num}可以跳转到数字表示的文件中,buffer {bufname}可以跳转到对应的文件名中。

使用bdelete可以删除当前打开的文件缓冲区。
:args可查看传递给vim的参数列表。其中[]指明了哪个是活动文件(即当前被打开的文件)

窗口

s水平切割窗口(竖向排列)
v垂直切割窗口(横向排列)
w在窗口间循环切换
h切换到左边的窗口
j切换到下边的窗口
k切换到上边的窗口
l切换到右边的窗口

=使所有窗口等高等宽
_最大化窗口高度
|最大化窗口宽度

标签页

:tabe[dit] {path}创建一个标签页,如果有path则打开对应的文件作为新的标签
:lcd {path}设置当前窗口的本地工作目录
:close关闭当前标签页中的窗口
:tabc[lose]关闭当前标签页,不论有多少个窗口
:tabo[nly]关闭其余所有标签页
:tabN[ext] {N}跳到下一个标签页或第N个标签,没有gt命令好用
:tabp跳到上一个标签页
{N}gt跳转到第N个标签页,不带N则跳到下一个
gT跳到上一个标签页
:tabmove {N}移动当前标签页到第N个位置,从0开始,省略N则排到末尾。

打开文件

:pwd和pwd一样
:edit {path}打开路径对应的文件,支持绝对路径和相对路径
:find {file}find只需要文件名,不需要填写路径即可打开对应的文件,其默认搜索方式和环境变量一个道理,可以使用:set path+={path}来设置搜索路径。

使用:edit打开一个不存在的文件的时候,与vim一个道理,但是如果打开一个目录不存在的时候,就不好保存了,但是这个时候可以在vim中调用shell来创建一个目录:!mkdir -p %:h其中%表示当前文件的路径,:h来去除文件名

查看文件目录

:edit .:e.注意edit后边有个.,该命令打开一个新的窗口(之前的窗口退出),显示当前目录。
:E查看目录,并可查看隐藏文件
:Vex水平方向打开一个窗口,显示目录
:Sex垂直方向打开一个窗口,显示目录
可查看当前文件的一些信息

文件内移动

hjkl这些字母是在屏幕中上下移动的,但是有的时候会遇见一行占据多行的现象,而hjkl只能一行一行移动,对于跨行的行是无所适从的,在vim的那本书里面,将其区分为实际行和屏幕行,hjkl就是针对实际行进行的操作。而针对屏幕行的操作为在hjkl前加上g即可,如gj就是在当前屏幕行下移一行。
0移动到实际行的行首,g0移动到屏幕行的行首,^移动到实际行第一个非空白字符处,g^移动到屏幕行的第一个非空白字符处。$移动到实际行的行尾g$移动到屏幕行的行尾。

其实如果平常使用屏幕行多的话,可以通过nnoremap k gk来将对应的命令映射到屏幕行的命令中,这样以后只需要使用hjkl来移动即可。

基于单词的移动

w正向移动到下一个单词的开头
b反向移动到上一单词的开头
e正向移动到下一个单词的结尾
ge反向移动到上一个单词的结尾

基于字符串的移动

字符串和单词有很大区别,字符串之间的间隔为空格,而单词可以用其他特殊符号进行间隔,对于字符串的移动和基于单词移动类似,不过将对应的命令变为大写,W,B,E,gE

查找

f{char}正向移动到下一个char所在处
F{char}反向
t{char}正向移动到下一个char的前一个字符上
T{char}反向
;重复上一次操作,,反转方向并重复上一次操作

可视模式下的操作

使用前先进入v模式


Vim实用技巧_第1张图片
image.png

如果不想在可视模式下操作,还有以下操作方式
c/d/y + 范围
di"表示删除"范围中的内容,ci"表示删除"范围内容并进入插入模式。

范围文本对象

Vim实用技巧_第2张图片
image.png

这里的命令表示范围,可以结合d这个命令进行操作,所以显而易见的daw就表示删除当前单词和单词前的一个空格(如果有空格的时候删除空格),而diw则表示删除单词,不删除任何空格。

d命令和aw``as等命令配合会比较好,c命令和iw等命令配合比较好。

位置标记

使用m{a~Z}可以给当前位置打个标记,标记名就是a~Z中任意指定字符,而跳转到指定字符指定的标记则使用`{a\~Z}

其中大写字母是全局标记,在第一个文件中打标记,第二个文件中可以感知到该标记,而小写字母则是局部标记。

mm给当前位置打标记,后续使用`m来回退到该标记

vim会自动进行标记,使用以下命令来进行跳转:


Vim实用技巧_第3张图片
image.png

括号间跳转

()``{}``[]括号间跳转,使用%即可跳转。
使用r可进行对字符进行替换,但是如果想要把[]替换为{}是不好进行操作的,但是也有方便的方法,可以先通过%来跳转,这样vim会自动给上一个位置打上标记,然后使用r{来进行替换,完成后使用``来跳会另一个括号处,再使用r}来替换即可。

默认的%只能在这几个括号间跳转,但是vim自带一个插件,该插件功能是在代码间的if /else或者其他相关语句跳转,开启的方式为在vimrc中添加以下命令,懒得折腾了,没有进行尝试。

set nocompatible
filetype plugin on
runtime macros/matchit.vim

文件内跳转

使用可以回跳,而则相反。
使用:jumps可以查看历史记录的跳转的记录,这些内容都可以通过来进行跳转,即使之前关闭了,如:e.命令打开一个目录,之后还可以通过来跳转回来之前的文件中。

使用{count}G也是一个跳转,比:{count}方便一点,但是jk这种上移,下移则不是。

遍历改变列表

当对文件修改的后,vim会自动记录当前光标所在位置。
使用:changes来查看修改列表,使用g;跳转到上一次完成编辑时光标所在行处。

跳转到光标下的文件

gf可以跳转到光标下的文件,如果配置正确的话。比如使用:e.来打开一个目录后,就可以通过gf来跳转到该文件中去,当然使用回车也可以。

复制与粘贴

x命令将某个字符删除并放入一个寄存器中,之后使用p将寄存器中的字符取出放入当前光标的尾部。而P则将字符放入当前光标前
dd命令不仅仅删除一行,还将当前行保存到寄存器中,之后使用p来复制。使用ddp则可以调换当前行和下一行,为什么就不解释了吧。

使用yiw可以复制一个单词,注意是yiw的结合

寄存器

vim默认使用一个无名寄存器,所以在进行复制剪切等操作都会覆盖之前复制或剪切的内容,如果不想这种效果,则可以指定寄存器。
在使用的时候,所有标记的寄存器前边都有一个引号,切记。

如果真正的想删除某个字符或某个字符串,而不保存到寄存器中,类比linux中的/dev/null,vim中可以指定"_寄存器,这个就表示真正的删除,如"_d{motion}

其他的寄存器以字母开头,如"ayiw表示把一个单词复制到"a寄存器中,使用"ap则将"a寄存器中的内容粘贴。
这些寄存器被称为有名寄存器,以为"a~z26个字母进行标记。

而使用命令行模式可以通过:delete c将删除内容放入c寄存器中,:put c则粘贴"c中的内容.

使用y进行复制的时候,其又一个专用的寄存器,称为复制寄存器,与d``x命令的寄存器丝毫不相互影响,但是粘贴的时候,如果使用pP粘贴则实际上粘贴的是无名寄存器中的内容,若要粘贴复制寄存器中的内容,需要使用"0前缀,注意不是0,0前边有个引号,即"0P"0p进行粘贴复制寄存器中的内容。

使用:reg {mark}来查看某个寄存器中的内容,如:reg "0查看"0复制专用寄存器中的内容。
当然使用:reg可查看所有的寄存器的内容。
以上都是在vim中进行操作的,但是如果想要与外部程序进行互通,则需要使用"+,

q键是录制按钮,也是停止按钮,一开始需要按q{reg}指定一个保存宏的寄存器,此时状态显示recording则表示在录制中,之后执行一系列命令,再按q则将命令保存在寄存器中。此时可以通过:reg命令查看对应寄存器中的内容。

而执行方式则通过@{reg}来进行执行。通过@@来执行最近的宏。
使用{count}@{reg}则执行对应的宏count次。

给宏追加命令,则使用大写的方式,如qa来对a寄存器进行录制,而qA则向a寄存器进行中追加命令。

模式

忽略大小写: :set ignorecase,不忽略大小写::set smartcase

正则表达式,通常使用/来进行搜索的时候,如果遇到{这种符号,都需要加上转义字符\,这样非常不方便,为了和python的那种正则表达式类似,可以在搜索的时候加上\v命令,这样后边的字符都有特殊含义,不需要加转义字符,如搜索css中的color的值,vim中一般的搜索方式为/#\([0-9a-fA-F]\{6}\|[0-9a-fA-F]\{3}\),但是如果加上了\v命令,则为:/\v#([0-9a-fA-F]{6}|[0-9a-fA-F]{3}),可以看到少了很多转义符号。同样\v模式下的\x表示16进制字符,那么上述又可以表示为/\v#(\x{6}|\x{3})

如果想要按照原义来进行查找,则可以加上\V字符,表示全匹配,并不会被当作正则来看待。但是\V模式下的\?还是特殊字符。?表示前向匹配,/则是正向匹配。

有时候会有这种问题,想要匹配一全匹配的单词,比如the,但是匹配的时候there也被匹配,那么这种方式的匹配规则则为/\v,即加上<>符号。

使用\zs命令可以进行特殊匹配,如/i love you则匹配i love you,而/i love \zsyou则只有i love you中的you高亮,而其他单独出现的you不会被匹配。\zs是排除之前的字符,而\ze是匹配之后的字符,比如\i \zslove \zeyou则只匹配love

查找

使用:set incsearch则在输入查找字符的时候实时进行查找。

查看匹配的次数:%s///gn注意该命令不会进行替换,因为最后的字符n抑制了替换操作。

在匹配到某个单词的时候,可以按下e自动将光标移动到单词的结尾处,但是也可以直接在查找的命令中写下\e则在查找的时候不用按任何键,则会自动的将光标移动到对应的结尾处,如\love\e

*命令可进行查找当前光标处的单词。

替换

:s/[old]/[new]/g
:%s/[old]/[new]/gc每次替换都会进行提示
使用{reg}可以将寄存器中的内容取出。

global

跳到文件的第一行或最后一行

  • :$ 跳到文件最后一行
  • :0:1 跳到文件第一行
  • :8 跳到文件第8行
    或 另外一组命令:
  • gg 跳到文件第一行
  • Shift + g 跳到文件最后一行

复制粘贴

  1. 选定文本块。使用v进入可视模式,移动光标键选定内容。

2.复制的命令是y,即yank(提起) ,常用的命令如下:
y 在使用v模式选定了某一块的时候,复制选定块到缓冲区用;
yy 复制整行(nyy或者yny ,复制n行,n为数字);
y^ 复制当前到行头的内容;
y$ 复制当前到行尾的内容;
yw 复制一个word (nyw或者ynw,复制n个word,n为数字);
yG 复制至档尾(nyG或者ynG,复制到第n行,例如1yG或者y1G,复制到档尾)

  1. 剪切的命令是d,即delete,d与y命令基本类似,所以两个命令用法一样,包括含有数字的用法.
    d 剪切选定块到缓冲区;
    dd 剪切整行
    d^ 剪切至行首
    d$ 剪切至行尾
    dw 剪切一个word
    dG 剪切至档尾

  2. 粘贴的命令式p,即put(放下)
    p 小写p代表贴至游标后(下),因为游标是在具体字符的位置上,所以实际是在该字符的后面
    P 大写P代表贴至游标前(上)

显示隐藏行号

set nu显示行号
set nonu隐藏行号

你可能感兴趣的:(Vim实用技巧)