Vim Pickups 001(2017)
整理点 vim 小技巧。如无特殊说明,本文所列命令都是 VIM 内置的,无需额外插件。
1. VIM 别名
一些编辑器看似独立,其实后台都是调用的 VIM,只是启动参数不同:
vim
- 正常启动 VIMex
- 以Ex
模式启动 VIMview
- 以只读模式启动 VIM,和vim -R
效果一样- 其他:
gvim
,gview
,rview
等等
用 file
命令看一下:
$ file /usr/bin/ex
/usr/bin/ex: symbolic link to '/etc/alternatives/ex'
$ file /etc/alternatives/ex
/etc/alternatives/ex: symbolic link to '/usr/bin/vim.gtk'
$ file /usr/bin/vim.gtk
/usr/bin/vim.gtk: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=3544bf336449c36023788f68ed25a6d75e575a08, stripped
2. VIM 打开文件:高级功能
启动 VIM 时可以加额外参数,完成很多神奇炫酷的功能。
2.1 以二进制模式打开文件
$ vim -b <file>
2.2 +
指定额外命令
打开文件后,跳转到第 N 行
$ vim +5 test.txt
打开文件后,跳转到 {pattern}
第一次出现的位置
$ vim +/{pattern} <file>
# 跳转到 'vim' 字符串第一次出现的位置
$ vim +/vim test.txt
其他命令
$ vim "+{command}" <file>
$ vim -c {command} <file>
# example: turn off showing number on opening index.html
$ vim "+set nonu" index.html
2.3 以 diff 模式打开多个文件
$ vim -d <file1> <file2> ... <fileN>
效果和 vimdiff
一样。
$ vimdiff file1 file2
]c 跳到下一个差异点
[c 跳到前一个
:diffupdate 手动重新加载文件内容(正常会自动加载)
2.4 一次打开多个文件
分别显示在不同的窗口。
# 窗口上下排列, N 可省略
$ vim -o[N] <file1> <file2> ... <fileN>
# 窗口左右排列, N 可省略
$ vim -O[N] <file1> <file2> ... <fileN>
3 匹配然后删除(match then delete)
3.1 基础匹配删除操作
-
删除匹配的字符串:
%s/<pattern>//g
本质上是替换(substitute),用空字符替换了
<pattern>
。 -
删除匹配行:
:%g/<pattern>/d
例如
:%g/cloud/d
,表示删除当前文件内包含cloud
的行。
3.2 删除空行
-
g/^\s*$/d
:以空格类字符(^\s
)开头,连续匹配直到行结束(*$
),删除(d
)。https://stackoverflow.com/questions/706076/vim-delete-blank-lines
3.3 删除匹配行前后 n/m 行
来自 Deleting a range of n lines before and after a matched line?:
:%g/<pattern>/-10,+28d
:找到包含<pattern>
的行,然后从该行前面 10 行一直删除到该行后面 28 行。:%g/<pattern>/-10,.d
:删除从匹配行-10
行直到当前行,小数点表示当前行。
3.4 删除不匹配的行 :g!/<pattern>/d
3.5 删除文档中所有空行
:g/^\s*$/d # 删除空行,其中可能包括若干个空格或 tab
:g/^$/d # 删除纯空行(其中不包含空格或 tab)
:%s/\s\+$//g # 删除 trailing 空格或 tab
:g!/pattern/d # 删除不匹配的行
4 替换(substitution)
4.1 将多个连续空行合并为一行
- 通用方式,将多个连续空行合并为一行:
:%s/\n\{3,}/\r\r/e
-
Linux 上,用 cat 命令合并空行,
:%!cat -s
。-s, --squeeze-blank
: suppress repeated empty output lines。
4.2 追加相同内容到所有行
几种方式:
%s/$/<your content>/gc
- 用替换 \n 实现,例如,在每行后面追加一个分号,注意后面的 pattern 里换行符得用 \r:
%s/\n/;\r/gc
4.3 将 windows 下的换行(^M) 替换为 Linux 换行
:%s/<Ctrl-V><Ctrl-M>/\r/g
<C-V><C-M>
才能按出 ^M 符号。
4.4 将指定 pattern 替换为换行符
搜索文本中的换行符需要使用 \n
作为 pattern,
替换需要使用 \r
作为换行符,\n
不行:
:%s/<pattern>/\r/gc
5 待归类
插入内容时不要将 tab 自动替换为空格
:set noexpandtab
:set expandtab
:set list 能看到到底是 tab 还是空格
匹配直到某个 pattern 出现
https://stackoverflow.com/questions/3625596/vim-select-until-first-match/3625645
使用非贪婪搜索(non-greedy)模式:{-}
/^.\{-\}hello
从头开始匹配,直到遇到 hello%s/<h1.\{-\}>/# /g
将 h1 tag 替换为一个 # 加空格。例如<h1 id="xx" name="xx">Head 1</h1>
会被替换为# Head 1 </h1>
, 再将 </h1> 替换为空,就实现了将 html 元素转为 markdown 元素的目的。
另存为文件
:saveas <filename>
统计字数、行数等:g Ctl-g
https://superuser.com/questions/149854/how-can-i-get-gvim-to-display-the-character-count-of-the-current-file
先按 g,再按 Ctl-g。效果:
Col 1 of 113-77; Line 19 of 217; Word 30 of 434; Char 261 of 5084; Byte 383 of 6104
计算
计算表达式并将结算插入到光标位置
插入模式下:<ctl-r>=
(先按 ctl-r,再按 =
) 进入编辑表达式状态,再输入 3*2
之后,结果 6
就会插入到光标位置。
这是使用了 Vim 表达式寄存器 "=
。
操作数字(+1/-1
):ctl-a/ctl-x
c-a 对光标下的数字 +1
c-x 对光标下的数字 -1
visusal 选中列,g c-a 将依次加 1,例如 1/1/1 变成 2/3/4
重绘窗口,将光标所在行移动到平面正中间、顶部、底部
zz
:移动到正中间zt
:移动到顶部(top)zb
:移动到底部(bottom)
References
- VIM Man Manual (
man 1 vim
)