这篇文章搜集 vim 的最佳使用方法,能让人快速上手它的使用
快速纠错
命令 | 功能 |
---|---|
ctrl + h |
删除上一个字符 |
ctrl + w |
删除上一个单词 |
ctrl + u |
删除当前行 |
上面的命令在终端下也可能使用,另外在终端下:
ctrl + a
(^a) 可以移动到首字母^e
移到行尾^b
前移一个字符
快速切换 insert 和 normal 模式
- 使用
ctrl + c
(即^c
) 代替Esc
(但可能会中断 某些插件)或者ctrl + [
gi
快速跳转到最后一次编辑的地方- 在
vimrc
中用:map
映射的方式代替Esc
Vim 的快速移动
在单词间移动
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
w/W | 移到下个 word/WORD 开头 | e/E | 下一个 word/WORD 尾 |
b/B | 回到上个 word/WORD 开头 |
word 指以非空白符分割的单词,WORD 以空白符分割的单词。比如
self.name = name
,w 则跳到.
处,而 W 则会跳转到=
处
行间搜索移动
同一行快速移动最好是通过搜索字符的方式移动
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
f{char} | 向前移动到 char 上 | t{char} | 移动到 char 的前一个字符 |
; | 结过搜索该行下一个 | , | 继续搜索上一个 |
F{char} | 向后移动到 char 上 |
Vim 的水平移动
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
0 | 移到行首 | ^ |
移动第1个非空白字符 |
$ |
移到行尾 | g_ |
移到行尾非空白字符 |
0w | 移到行首(推荐) |
Vim 的垂直移动
我们可以在句子 (sentence) 和段落 (paragraph) 间移动
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
() | 在句子间移动 | {} | 在段落间移动 |
推荐:用 easy-motion
插件
Vim 的页面移动
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
gg/G | 文件开头/结尾 | ctrl + o |
快速返回上一个标签 |
H/M/L | 跑到屏幕开头/中间/结尾 | zz | 把光标置为中间 |
Vim 的增删改查
删除
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
x | 删除字符 | daw/diw | 删除一个字符串对象 |
dt( | 删除()内部的内容 | dt” | 删除引号内的内容 |
d$ |
删除光标到行尾的内容 | d0 | 删除光标到开头内容 |
- daw 删除带后面空格的单词
- diw 仅删除单词本身
- dt( delete to “(“ 删除直到括号
- 还可以在 visual 模式下选中行,再使用
d
命令来删除
修改
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
r/c/s | 替换单个字符/改变/替换后进入insert模式 | R | 进入替换字符串模式 |
S | 删除整行跳到第1列进入编辑模式 | C | 删除整行跳转行首进入编辑模式 |
ct” | 删除引号中的内容并进入编辑模式 |
查询
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
/ |
前向搜索 | ? |
反向搜索 |
n/N | 跳转到下/上一个 | */# |
当前光标单词匹配 |
Vim 的搜索替换
:[范围]s/{待替换的字符}/{替换后的字符}/[选项]
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
:10,20 | 10 ~ 20 行 | % | 全部行 |
g | 全局范围内执行 | c | 修改前确认 |
n | 报告匹配次数,但不替换 |
例子:
:% s/self/this/g
- 在全文本中将 self
替换成 this
,如果不用 g,则替换一次后就会停止
:1,6 s/self/this/g
- 在 1~6 行文本中将 self
替换成 this
,如果不用 g,则替换一次后就会停止
:1,6 s/self//n
- 在 1~6 行文本中统计 self
出现的次数,因为不需替换所以 this 部分为空
:% s/\<quack\>/jojo/g
- 只替换 quack
,不替换 a_quack
中的 quack 字符,\<
表开头
Vim 多文件操作
基本概念
- buffer
Buffer 是指打开的文件的内存缓冲区,Vim 打开文件后会将内容加载到缓冲区中,之后的修改都是针对内存中的缓冲区,并不会直接保存到文件。直到执行:w
时才会把缓冲区中的内容写入文件 - 窗口
窗口是 Buffer 的可视化的分割区域 - Tab
Tab 可以组织多个窗口为一个工作区
命令
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
:ls | 显示当前缓冲区 | :b n | 跳转到第 n 个缓冲区 |
:b pre/next/first/last | 跳转到对应缓冲区 | :b name | 跳转到 name 缓冲区 |
:sp | 水平分割出一个窗口 | :vs | 垂直分割出一个窗口 |
<C-w>w/h/j/k |
在窗口间切换 | <C-w>W/H/J/K |
移动窗口 |
<C-w>= |
所有窗口等宽高 | ||
:tab file | 在新标签页中打开 file | <C-w> T |
当前窗口移到新标签页 |
:tabc | 关闭当前标签页 | :tabo[nly] | 仅保留当前标签页 |
:tabn | 跳到下一标签页 | :tabp | 跳到上一标签页 |
Vim 的 text object
Vim 中文本也有对象的概念,如一个单词,一个句子,一个段落。以单个字符对单位编辑比较低效,通过文本对象操作高效很多。
文本对象操作方式:
[次数]<命令>[文本对象]
- 命令:d(delete), c(change), y(yank)
- 文本对象:w(word), s(sentence), p(paragraph)
- iw:表示 inner word
- aw:表示 a word,不但选中单词,还会选中单词后的空格,可以记成 around word
Vim 复制粘贴与寄存器
从外部复制粘贴
在 vimrc 中设置了 autoindent
后,粘贴 python 代码缩进会错乱,原因是在终端的 vim 中没有相应的程序来处理这个从其他应用复制粘贴的过程,所以 Vim 通过插入键盘输入的buffer来模拟这个粘贴的过程,这个时候 vim 会以为这是用户输入的。
问题就是出在这:当上一行结束,光标进入下一行时 Vim 会自动以上一行的的缩进为初始位置。这样就会破坏原始文件的缩进这时可以使用 :set paste
解决这个问题。粘贴完成之后再用 :set nopaste
恢复自动缩进。
寄存器
- vim 中操作的是寄存器而不是系统剪贴板,用 d 和 y 操作的内容都放到了“无名寄存器”中。
- 通过
"{reg}
可以指定寄存器,比如"ayiw
复制一个单词到寄存器a
中,"bdd
删除当前行并存到寄存器b
中。 - 通过
:reg {reg_name}
可以查看 reg_name 的内容 - 通过
"ap
可以粘贴寄存器a
的内容
其他常见寄存器
"0
是复制专用寄存器,使用y
复制的文本会被拷贝到无名寄存器""
和寄存器 0 中"+
是系统剪贴板,可以在复制前加上"+
把内容复制到系统剪贴板中"%
当前文件名寄存器".
上次插入的文本
例子: 拷贝内容到系统剪贴板:
:echo has(‘clipborad')
查看 vim 是否支持系统剪贴板- 通过 V 选择两行
- 通过
"+y
把文本拷贝至系统剪贴板 - 通过
"+p
把文本从系统剪贴板拷贝到 vim 中
另一种方式:
:set clipboard=unnamed
把无名寄存器与系统剪贴板连通- 通过
y
和p
复制粘贴
宏
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
q |
录制宏 | 再q |
结束录制 |
q{reg} |
选择保存的寄存器 | @{reg} |
使用对应寄存器宏 |
- 宏是一系列的操作集合。vim 的宏使用
q
录制,同时也是用q
结束录制。 - 可以使用
q{reg}
来选择保存的寄存器 - 使用
@{reg}
回放宏。回放可以先用 V 选择要回放的行,然后输入:
,之后再输入一些命令,看起来是这样::'<,'>normal @a
vim 中利用宏来实现插入一列递增或递减序号
- 进入 VIM,读取文件内容。
- 在需要加入行号的首行开头输入起始行号(序号)并加入一个空格与后文隔开(空格用于后面的单词复制分隔,如要不希望加入空格也可以用其它方式来框选序号,偶就不一一列举了)。
- 将光标置于行首(其实就是序号上),按下 q(命令模式下),开始录制操作啦~;再按下 t(偶将宏存到 t 中,大家也可以使用其它字符命名宏,注意是单个字符)
- 在命令模式下按下 yw,将行序号当作单词复制下来。
- 按 j 到下一行,现在光标应该正对应到插入位置,按下 P(最好是大写,表明在当前字符前粘贴),将上行序号粘贴到这个位置。
- 按下 ^(无视空格用 0[零,非欧]),光标回到行首(其实就是回到行序号上,还有其它方法可以实现),按下 Ctrl-a,序号会加 1( Ctrl-x 表示减 1,大家明白加 2 减 2……如何处理了吧),然后再次按下 ^,保证光标在行序号开始位置。
- 按下 q 结束录制。
- 在光标位于行序号首的情况下,想插入 10 个连续的行号就输入 10@t,10 代表执行次数,@表示执行宏,t 是偶刚才给宏的命名,大家按自己命名使用。
并且,默认情况下这个宏定义不会被清除,只要以后不重新在 t 上定义其它宏,再次重启 VIM 时也可以使用,再次使用时就不用录制了,直接使用就可以了 ^_^
。
vim 的补全
命令 | 功能 | 命令 | 功能 |
---|---|---|---|
ctrl + n/p | 补全单词 | ctrl + x, ctrl + f | 补全文件名 |
:r! echo % |
插入当前文件名 | :r! echo %:p |
插入全路径 |
比如输入 ./
后再按 ctrl + x
和 ctrl + f
就可以补全文件名
更改配色
用 :colorscheme <ctrl+d>
可以显示所有配色,用:colorscheme 名
修改配色
可以此网站中安装主题管理器,之后就有大量主题可更换了
推荐使用 hybrid
使用小技巧
总是显示最后5行
set scrolloff=5
打开拼写检查
set spell
在错误处输入 z=
就可以修改单词。或者在写入模式下移到词尾用 <c-x>s
也可以修改
快速退回刚才位置
<c-o>
:退回位置1
<c-i>
:再返回位置2
打开文件
在 vim 中有完整文件路径时,把光标移到文件上,输入 gf
即可(go to file)。回到刚才编辑处:<c-o>
。
如何实现 root 权限
用 vim 打开 root 文件,如何升级为 root,保存修改?在 vim 中执行访问终端操作:
// % 是当前文件
:w !sudo tee %
占位符
把 <++>
设置为点位符,双空格就可以跳转到占位符处
" Press space twice to jump to the next '<++>' and edit it
map <LEADER><LEADER> <Esc>/<++><CR>:nohlsearch<CR>c4i
Ascii Art 插件 figlet
" Call figlet
map tx :r !figlet
当前文件输出为 html
:%TOhtml
其中 %
是当前文件
保存光标位置
" === Restore Cursor Position
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif