也许是Vim的帮助已经很详细,关于VIM的书籍比较少,
这本【Practical Vim】,中文译名【Vim实用技巧】(书名太朴实)中描述了很多技巧和思路,
对有一定经验的Vim使用者而言,是非常好的提高资料。以下内容是书中摘录和部分总结。
————————————————————–
文本对象操作
文本对象
[i|a]{obj}
a表示包含范围字符,可理解为all; i表示不包含范围字符,可理解为内部。
obj可以是:'"{}[]()<>
中的任意1个,还可以是b(代表圆括号),B(代表大括号),t(标签),ap(段落)
可在文本对象前添加动作命令
比如:
di( di) dib 删除内含 '(' ')' 块, 保留括号
da( da) dab 删除一个 '(' ')' 块
di{ di} diB 删除内含 '{' '}' 大块, 保留括号
da{ da} daB 删除一个 '{' '}' 大块
di[ di] 删除内含 '[' ']' 块, 保留括号
da[ da] 删除一个 '[' ']' 块
di> di< 删除内含 '<' '>' 块, 保留括号
da> da< 删除一个 '<' '>' 块
dat 删除标签内容
dit 删除标签内容,不含标签本身
di" 删除当前的第一个字符串,保留引号 da" 删除当前的第一个字符串,不保留引号
di’ 删除当前的第一个字符串,保留引号
da’ 删除当前的第一个字符串,不保留引号
dap 删除一个段落
cab 修改()中的内容
dit 删除标签中的内容
ci" 修正字符串内容
————————————————————–
插入模式下粘贴寄存器文本
<C-r>{register}0
复制专用默认寄存器名为0,其他寄存器为a~z
例如,复制当前单词
普通模式:yaw
插入模式:<C-r>0
例如,使用a寄存器复制当前行
普通模式:"ayy
插入模式:<C-r>a
————————————————————–
在插入模式下随时随地计算
<C-r>=
=是表达式寄存器
例如,插入模式时计算23小时的秒数:
<C-r>=23*3600=82800
————————————————————–
虚拟替换模式
对Tab等进行替换时,如果想保持格式不变化,可以使用gR替换R,
gR虚拟替换模式下视Tab为空格进行替换
尽量使用gR替换R的使用。
————————————————————–
normal命令
normal可以在命令模式下执行若干普通模式命令。
例如,注释文件的所有内容
:%normal i//
因为normal在执行普通命令时会移动到行首,所以I和i效果一样
@: 重复上一次执行的Ex命令, @@用来重复上一次的命令(和宏一样)
————————————————————–
补全Ex命令
例如,列出所有的颜色主题
:colorschema <c-d>
————————————————————–
命令行窗口
q: 打开命令行窗口,可在其中浏览、编辑、执行历史命令
q/ 打开搜索历史命令窗口
————————————————————–
打开和当前文件同一目录下的文件
:e %:h<Tab>
其中%代表当前文件名,:h则会去除文件名本身,剩下路径
————————————————————–
一些快捷键
gj 屏幕行下移 (wrap的情况下)
gk 屏幕行上移 (wrap的情况下)
F{char} 反向查找字符
————————————————————–
path的设置
find命令、gf命令在寻找文件时从path中按路径查找
例如增加/usr/include路径作为检索路径
:set path+=/usr/include/**
:find mong<c-d>
可以显示出所有mong开头的头文件,如果你装了mongodb的话。
————————————————————–
寄存器使用
“0为复制专用寄存器,d/c/s命令不会覆盖它的内容,只有y会。
“+为系统剪切板,”是linux上的主剪切板,windows下 “+和”相同
————————————————————–
gp和gP
普通的p/P在复制后,光标被置于复制行的首位,复制多行时不方便。
gp和gP复制后,光标处于复制内容之后,方便多次连续复制。
————————————————————–
正则表达式的魔术模式
vim的正则表达式对特殊字符如+*.等默认转义和主流语言不太一样,
记忆哪些字符需要转义十分麻烦。
例如,查找附着在行尾的空白符
正常模式:
/\s+$
+必须转义
应用魔术模式\v,会将_,大小写字母,数字以外的字符均视为特殊字符。
魔术模式: /\v\s+$ +已被是为特殊字符,无需转义
相反的\V(原义开关)将会把 \以外的所有字符视为普通字符
————————————————————–
自动补全
补全整行文本
{char}<c-x><c-l>
{char}<c-x><c-i>
根据tag文件补全
{char}<c-x><c-]>
文件名补全(根据vim的当前工作路径)
{char}<c-x><c-f>
工作路径可以通过:cd命令进行变更
上下位置调整可以用
<c-p>和<c-n>
————————————————————–
global命令
:global命令允许在某个指定模式的所有匹配行上运行Ex命令
:[range] global[!] /{pattern}/ [cmd]
默认range为整个文件%,默认命令为print
例如,删除以#开头的行
:g /^#/ de
例如,将#开头的行都复制到文件末尾
:g /^#/ t$
例如,将#开头的行都复制寄存器a
:g /^#/ y A
vglobal是global的反向操作
————————————————————–
vimgrep和quickfix的配合
:vim[grep][!] /{pattern}/[g][j] {file} ...
在文件 {file} ... 里搜索模式 {pattern},并用匹配结果设
置错误列表。
如果没有 'g' 标志位,每行只加一次。
如果有 'g',每个匹配都被加入。
:vim[grep][!] {pattern} {file} ...
同上,但不用非 ID 的字符包围模式,而只用空白分隔。该模
式必须以 ID 字符开头。
上面命令1的g如果没有指定,每行只匹配一次
上面命令1的j如果没有指定,则有检索结果的情况下会直接跳转到第一项
上面命令2的区别在于分隔符,如果不需要检索空格,则后者更方便些。
:copen 20 打开quickfix窗口,20行高度
:cn
:cp
@: 重复上一次Ex命令(:cn或:cp)
@@ 重复上一次Ex命令
例如,在下层目录中搜索所有c和文件
搜索
:vimgrep include **/*.c **/*.h
:vimgrep /\cinclude/gj **/*.c **/*.h
\c为不区分大小写
查看
:copen 30
移动
:cn
重复移动(先@:,再@@)
@: @@
另外,vimgrep的输出是quickfix,但quickfix只有一个。
多种输出的场合下,可以使用lvimgrep,对应的输出会放到当前窗口列表中
:lvimgrepa[dd][!] /{pattern}/[g][j] {file} ...
:lvimgrepa[dd][!] {pattern} {file} ...
和 “:vimgrepadd” 类似,但使用当前窗口的位置列表而不是quickfix 列表。
另外,输出内容还可以追加
:vimgrepa[dd][!] /{pattern}/[g][j] {file} ...
:vimgrepa[dd][!] {pattern} {file} ...
和 “:vimgrep” 类似,但不是建立新的错误列表,而是附加到现有的列表之后。“`
比如还是刚才的例子:
:vimgrep include **/*.c
:vimgrepadd include **/*.h
————————————————————–
关于**
在 Unix、Win32、Mac OS/X 和一些其它系统上,可以扩展 “**”。它允许你在目录树里搜
索。最大深度可以到 100 层目录。
注意 有些命令的工作方式略有不同。见 |file-searching|。
例如:
:n */.txt 找到文件: ttt.txt subdir/ttt.txt a/b/c/d/ttt.txt 如果使用了非通配字符,只匹配第一层目录。例如: :n /usr/inc**/*.h 找到文件: /usr/include/types.h /usr/include/sys/types.h /usr/inc_old/types.h