1. 移动技巧
1.1 在同一行移动
- 首先是基本的hjkl
- 使用
f<chat>来移动到当前行光标之后的字符上,这里可以选择一些出现频率较低的字符,这样有更高的移动效率。在使用f<char>后,,可以使用;来重复上次的查找移动,如果不小心多移动了一个,可以按,回退 - 使用
w,e,b,ge在单词间跳转,其各自含义为:w正向移动到下一单词的开头b反向移动到当前单词/上一单词的开头e正向移动到当前单词/下一单词的结尾ge反向移动到上一单词的结尾
w、b等是在单词间的跳转,但一个逗号或点也算单词,如果是想把一个用空格分隔的串叫做单词,可以使用W,B,E,gEgj,gk按屏幕行进行上下移动
1.2 在当前文件内移动
- 使用
*跳转到当前文件内的当前光标下的单词 %跳转到匹配的括号- 使用
/执行常规搜索,并按n再次执行搜索
1.3 使用位置标记跳转
m<a-z>在当前文件中标记当前位置,mA-Z在全局定义一个mark'<a-zA-Z>跳转到刚才的缓冲区- vim还预置了一些特殊的标记:
''当前文件中,上次跳转之前的位置;'.上次修改的地方;'^上次插入的地方'<,'>上次高亮选区的起始和结束位置
1.4 在文件之间移动
<C-o>,<C-i>后退和前进[count]G跳转到某个行号, 例如40G跳转至40行(,)跳转到上一句/下一句的开头,{,}跳转到上一段/下一段的开头gf跳转到光标下的文件名<C-]>跳转到光标下关键字的定义- 改变列表,
:changes查看最近的更改,g;和g,跳转到下一个和上一个更改
2. 选择技巧
在可视模式下的选择技巧
- 使用
o来切换选区的活动端 <CR>+v进入列选择模式- 当你在一个具有特定结构的文本中时,例如程序源码,可以使用例如
vi}来选择当前大括号中的所有字符,类似的:vi),vi" vi<char>是选择除之外的字符,如果你想选择包括外围大括号}在内的字符,可以使用va}。为了便于记忆,可以把 i 想成"inside",而把 a 想成"around" 或"all"。
形如
i},a)的选区选择的文本在vim中被称为文本对象,Vim 的文本对象由两个字符组成,第一个字符永远是 i 或是a。我们一般说,以 i 开头的文本对象会选择分隔符内部的文本,而以 a 开头的文本对象则会选择包括分隔符在内的整个文本。这里我们使用文本对象进行选取,但也可以借助文本对象进行编辑。
3. 编辑技巧
3.1 使用文本对象进行编辑
d{motion}、c{motion}、y{motion},其中的{motion}都可以被替换为文本对象。例如:ci"修改双引号"之间的文本,yit命令拷贝标签内的文本,di}删除大括号}之间的文本
文本对象包含两类,一类是操作分隔符的文本对象,如
i)、i"和it,它们被称为分隔符文本对象;另一类用于操作文本块,如单词、句子和段落,例如iw在当前单词内,is当前句子,ip当前段落,iW当前字串,当i被替换为a,这类文本对象将多包含一个空格或空行,这被称为范围文本对象。d{motion}和aw,as等配合较好,y/c{motion}和iw,is等配合较好
3.x 使用surround.vim操作分隔符文本对象
cs"'将双引号"替换为单引号', 其前缀命令为cs,可记为change surroundds"删除双引号", 其前缀命令为ds,可记为delete surroundysiw)在当前单词周围添加括号(,其前缀命令为ys,iw是文本对象,最后的)代表在周围加上小括号且不包含空格yss{在当前行周围加上大括号{},其前缀命令为yss
4. 寄存器操作
- 在使用
y,d进行复制,删除等操作时,默认使用无名寄存器,这就导致一个问题,当你使用yiw复制了一个单词,然后在另一个地方使用diw删除了一个单词之后,再想粘贴刚刚复制的单词,就会发现寄存器被占用了.此时通过一些寄存器操作来获取刚刚复制的单词. - 在复制命令之前加上
"<a_z>来将复制的内容保存到指定寄存器中,例如"ayiw将当前单词复制到寄存器a中,然后通过"ap将寄存器a中的内容粘贴到当前位置 - 复制专用寄存器
"0, yank操作会将内容保存到寄存器0中,例如["0]yiw将当前单词复制到寄存器0中,然后通过"0p将寄存器0中的内容粘贴到当前位置 - 黑洞寄存器
"_, 通过"_d删除内容,不会保存到任何寄存器中 - 系统剪贴板
"+,可从中读取系统剪贴板的内容 :reg命令可以查看所有寄存器的内容- 使用
R进入替换模式
基本操作
%跳转到匹配的括号f<character>找到当前行中,在光标之后的字符,在找到字符后,使用;跳转到后一个字符,,跳转到前一个字符F<character>找到当前行中,在光标之前的字符<line_number>G跳转到某行CTRL-e向下翻滚页面CTRL-u向上翻滚半页CTRL-d向下翻滚半页d$删除至行末,dgg删除从光标到文件开头,ggdG删除整个文件,diw删除当前单词,dip删除当前段,ciw替换当前单词,yiw复制当前单词
vim的抽象层
缓冲区
缓冲区有三种不同状态:
active缓冲区显示在窗口hidden缓冲区不显示,但存在且文件处于打开状态inactive缓冲区不显示且为空,没有链接任何文件:buffers查看所有打开的缓冲区:buffer <ID_or_name>移动到该缓冲区:bnext或:bn移动到下一个缓冲区:bprevious或:bp移动到上一个缓冲区:bfirst或:bf移动到第一个:blast或:bl移动到最后一个缓冲区CTRL-^切换到备用缓冲区,在列表中用#显示<ID>CTRL-^切换到ID的特定缓冲区,例如75CTRL-^切换到ID为75的缓冲区:bufdo <command>将命令应用到所有缓冲区并非所有缓冲区但在列表中,使用
:buffers!或:ls!列出所有缓冲区:badd <filename>将某文件添加到缓冲区:bdelete <ID_or_name>或:bd 1删除缓冲区,1,10bdelete删除id从1到10的缓冲区
窗口 windows
vim中的窗口是一个用来显示缓冲区内容的空间,当关闭窗口时,缓冲区仍保持打开状态
:new创建新的窗口CTRL-W s水平拆分当前窗口CTRL-W v垂直拆分当前窗口CTRL-W n水平拆分当前窗口并编辑新文件CTRL-W ^使用备用文件拆分<buffer_ID>CTRL-W ^使用某ID的缓冲区拆分窗口CTRL-W 上下左右将光标移动到另一个窗口CTRL-W r旋转窗口,CTRL-W x与下一个窗口互换CTRL-W =调整窗口大小,使其适合相同大小的屏幕CTRL-W -降低窗口高度,CTRL-W +增加窗口高度,CTRL-W <减小窗口宽度,CTRL-W >增加窗口宽度:q退出当前窗口
Tabs
:help tab-page
缓冲区是一个打开的文件,窗口是活动缓冲区的容器。可以将选项卡视为一堆窗口的容器。这样一来,它与标准 IDE 中的选项卡概念非常不同
:tabnew或:tabe打开新的选项卡:tabclose或:tabc关闭当前选项卡tabonly或tabo关闭除当前选项卡外的所有传其他选项卡gtgo 到下一个tabgTgo 到上远程tab1gTgo到第一个选项卡
参数列表 arglist
:help arglist
参数列表用于组织打开的文件,可将其视为缓冲区列表的稳定子集。它遵循以下两个原则:
- arglist 中的每个文件都将位于缓冲区列表中。
- 缓冲区列表中的某些缓冲区不会出现在 arglist 中。
运行 Vim 时要打开的文件(例如执行 vim file1 file2 file3 )将自动添加到 arglist 中
:args显示arglist:argadd将文件添加到arglistargdo对arglist中的每个文件执行命令:next移动到arglist中的下一个文件:prev移动到arglist中的上一个文件:first移动到arglist中的第一个文件
跳跃
:jumps
CTRL-o转到上一个光标位置CTRL-i转到下一个光标位置
:help jump-motions :help jumplist :help changelist
[m移动到方法的开头]m移动到方法的末尾
更改列表
每次插入内容(使用 INSERT 模式)时,光标的位置都会保存在更改列表中。
g;跳转到下一个更改g,跳转到上一个更改
重复
:help single-repeat
.重复上一次更改@:重复执行上次的命令
录制宏
- `q<lowecase_letter>`` - 开始在寄存器中记录击键。您可以将寄存器视为内存中的一个位置,也可以将其视为剪贴板。
- 您接下来要执行的每次击键都将被保存。
q- 停止录制。@<lowercase_letter>- 执行您录制的击键。
命令行窗口
:help cmdline-window
q:打开命令行历史记录q/或q?打开搜索历史记录CTRL+f在命令行模式下打开命令行历史记录:history :命令行历史记录:history /或:history ?搜索记录
搜索与替换
单个文件搜索
- 基本搜索,在normal模式下使用
/然后键入要搜索的pattern,这将向前搜索,结果将在文件中突出展示;?向后搜索 //使用上次的模式搜索:set hlsearch设置搜索结果高亮*搜索当前光标下的单词g*搜索部分单词
多个文件搜索
:help :vimgrep
:vimgrep <pattern> **/*.php在*.php文件中搜索。这将使用搜索结果填充quickfix列表,使用:cnext或:cn、:cprev或:cp来查看结果,也可以通过:copen快速打开修复窗口并浏览结果:vimgrep pattern *在工作目录中的每个文件搜索模式
使用grep搜索
可通过
grepprg设置要使用的外部搜索程序
:help :grep
:grep <pattern> *搜索工作目录中出现的每个pattern:grep <pattern> a.txt b.txt在这两个文件中搜索出现的pattern
替换
:help :substitute
s/pattern/replace/g在当前行上使用“replace”替换“pattern”, 这里的s代表substitute,g表示全局%s/pattern/replace/g在当前文件中用“replace”替换“pattern”:s/pat\/tern/replace/g转义以匹配pat/tern:s#pat\tern#replace#g也可以使用其他分隔符:s/pattern/replace/ 10将从当前开始的10行中的pattern替换为replace:1,10s/pattern/replace/将文件前10行中的pattern替换为replace
一些标志的含意:&使用上一个替换命令中的标志;c要求用户确认每个替换;g替换每行中出现的内容;i不区分大小写;I区分大小写;n只报告匹配次数
逐个替换
- 使用
/执行常规搜索 - 使用
cgn替换当前单词 - 使用
n转到下一个结果 - 使用
.重复上次的替换或使用n跳转到下一个结果
在多个文件中查找和替换
可通过稳定的arglist来作为可以修改的文件的列表
例如,要替换每个html和twig文件中的匹配项,键入如下命令
:arg *.html使用当前工作目录中的所有html文件填充arglist,然后编辑第一个文件:argadd *.twig将twig文件添加到arglist:argdo %s/pattern/replace/ge | update将arglist中的每个文件中出现的pattern替换为replace:bufdo %s/pattern/replace/ge | update缓冲区中替换
通过快速修复列表替换
:grep pattern **/*.html查找子目录中的html文件:cdo s/blink/div/g | update替换
g
gf编辑位于光标下文件路径中的文件gx打开位于光标下文件路径中的文件gi移动到上次插入并切换到INSERT模式gv启动VISUAL模式并使用在上次VISUAL模式下所做的选择gn选择上次搜索的匹配项gI在行首插入文本,无论第一个字符是什么ga以十进制、十六进制或八进制打印光标下字符的 a scii 值gu使用动作的小写(例如, guiw )gU使用动作的大写(例如, gUiw )
Range 范围
.表示当前行$表示当前缓冲区最后一行%表示整个文件*表示在上一个VISUAL模式下所做的最后选择'<,'>分别表示选择的第一行和最后一行
例如,结合range与d
:1,40d删除1-40行:2,$d删除从第二行到最后.,$d删除从当前行到最后%d删除每一行
QuickFix 和文件列表
TODO
全局命令
基本形式: :g/pattern/command,其语义为:对全局的pattern执行command命令
例如,删除当前缓冲区中所有包含“useless”单词的行: :g/useless/d
:norm命令,可以在命令模式下执行normal模式中的一些指令,例如::norm daw将删除光标下的单词 :q
将normal模式命令与全局命令结合起来:
:g/useless/norm gu$ 这将把每个包含useless的行小写
marks 书签
- normal模式下,使用
m<a-z>当前缓冲区,mA-Z全局缓冲区来定义一个mark - normal模式下,使用
'<a-z>跳转到刚才的缓冲区 :marks显示标记集:marks <marks>显示一些特定标记:delmarks <mark>or:delm <mark>删除标记:delmarks!或delm!删除a-z范围内所有标记:marks <>显示两个标记<和>
排序
:sort或:sor根据范围对行进行排序:sort!或:sor!倒序
还可以为sort添加一些选项
i忽略大小写n根据行中的第一个小数排序f根据行中的第一个浮点数排序/pattern/根据匹配后的情况排序r与/pattern/结合,根据匹配模式排序
例如:对csv,根据第二列对每一行进行排序::sort /[^,]*,/