在编程的时候,你会把大量时间花在阅读/编辑而不是在写代码上。所以,Vim 是一个多模态编辑器:它对于插入文字和操纵文字有不同的模式。Vim 是可编程的(可以使用 Vimscript 或者像 Python 一样的其他程序语言),Vim 的接口本身也是一个程序语言:键入操作(以及其助记名) 是命令,这些命令也是可组合的。Vim 避免了使用鼠标,因为那样太慢了;Vim 甚至避免用上下左右键因为那样需要太多的手指移动。
这样的设计哲学使得 Vim 成为了一个能跟上你思维速度的编辑器。
★Lecture 3 Editors(vim)
作为程序员,我们大部分时间都花在代码编辑上,所以花点时间掌握某个适合自己的编辑器是非常值得的。通常学习使用一个新的编辑器包含以下步骤:
- 阅读教程(比如这节课以及我们为您提供的资源)
- 坚持使用它来完成你所有的编辑工作(即使一开始这会让你的工作效率降低)
- 随时查阅:如果某个操作看起来像是有更方便的实现方法,一般情况下真的会有
如果您能够遵循上述步骤,并且坚持使用新的编辑器完成您所有的文本编辑任务,那么学习一个复杂的代码编辑器的过程一般是这样的:头两个小时,您会学习到编辑器的基本操作,例如打开和编辑文件、保存与退出、浏览缓冲区。当学习时间累计达到20个小时之后,您使用新编辑器的效率应该已经和使用老编辑器一样快。在此之后,其益处开始显现:有了足够的知识和肌肉记忆后,使用新编辑器将大大节省你的时间。而现代文本编辑器都是些复杂且强大的工具,永远有新东西可学:学的越多,效率越高。
Vim 的哲学
在编程的时候,你会把大量时间花在阅读/编辑而不是在写代码上。所以,Vim 是一个多模态编辑器:它对于插入文字和操纵文字有不同的模式。Vim 是可编程的(可以使用 Vimscript 或者像 Python 一样的其他程序语言),Vim 的接口本身也是一个程序语言:键入操作(以及其助记名) 是命令,这些命令也是可组合的。Vim 避免了使用鼠标,因为那样太慢了;Vim 甚至避免用上下左右键因为那样需要太多的手指移动。
这样的设计哲学使得 Vim 成为了一个能跟上你思维速度的编辑器。
★编辑模式
i、R、v、shift+v、ctrl+v、:
Vim 的设计以大多数时间都花在阅读、浏览和进行少量编辑改动为基础,因此它具有多种操作模式:
- 正常模式:在文件中四处移动光标进行修改
- 插入模式:插入文本
- 替换模式:替换文本
- 可视化模式(一般,行,块):选中文本块
- 命令模式:用于执行命令
在不同的操作模式下,键盘敲击的含义也不同。比如,
x
在插入模式会插入字母x
,但是在正常模式会删除当前光标所在的字母,在可视模式下则会删除选中文块。在默认设置下,Vim 会在左下角显示当前的模式。Vim 启动时的默认模式是正常模式。通常你会把大部分时间花在正常模式和插入模式。你可以按下
<ESC>
(退出键)从任何其他模式返回正常模式。在正常模式,键入
i
进入插入模式,R
进入替换模式,v
进入可视(一般)模式,shift+v
进入可视(行)模式,<C-v>
(Ctrl-V, 有时也写作^V
)进入可视(块)模式,:
进入命令模式。
★基本操作
插入文本
- 在正常模式,键入
i
进入插入模式。现在 Vim 跟很多其他的编辑器一样,直到你键入<ESC>
返回正常模式。你只需要掌握这一点和上面介绍的所有基础知识就可以使用 Vim 来编辑文件了 (虽然如果你一直停留在插入模式内不一定高效)。
缓存, 标签页, 窗口
:sp filename、ctrl+w j、ctrl+w k、ctrl+w t、ctrl+w b、:qa、:tabnew filename、:tabp、:tabn、ngt
Vim 会维护一系列打开的文件,称为“缓存”。一个 Vim 会话包含一系列标签页,每个标签页包含 一系列窗口(分隔面板)。每个窗口显示一个缓存。跟网页浏览器等其他你熟悉的程序不一样的是, 缓存和窗口不是一一对应的关系;窗口只是视角。一个缓存可以在多个窗口打开,甚至在同一个标签页内的多个窗口打开。这个功能其实很好用,比如在查看同一个文件的不同部分的时候。
buffer 缓存、windows窗口、tab标签。通常情况下,一个文件就是一个buffer,buffer是看不见的,需要通过窗口来展示内容,窗口多了需要分类就是Tab。
Vim 默认打开一个标签页,这个标签也包含一个窗口。
如下图所示,有两个标签,第一个标签有三个窗口,其中两个窗口是文件
example.txt
、一个窗口是文件1.txt
。第二个标签有一个窗口,是文件example.txt
。所以,正如前面所说的,一个缓存可以在多个窗口打开,甚至在同一个标签页内的多个窗口打开,而且修改其中任意一个窗口中的内容,相同文件的其他窗口中的内容也相应修改,因为说到底就是一个文件,只是被打开了多个。
关于窗口和标签页的命令,见
vim的窗口切换 - Cloudhan - 博客园 (cnblogs.com)
VIM 实现tab标签页及分屏,切换命令 - Bridge- - 博客园 (cnblogs.com)
常用的有:
- 对于窗口:
:sp filename
:在当前标签页打开指定文件的一个窗口,如果只是:sp
则打开的是当前文件ctrl+w j
:移动到下一个窗口ctrl+w k
:移动到上一个窗口ctrl+w t
:移动到顶端窗口ctrl+w b
:移动到底端窗口:qa
:关闭所有标签页的所有窗口,即会退出vim
- 对于标签页:
:tabnew filename
:建立对指定文件的新的标签页:tabp
:切换到前一个标签页:tabn
:切换到后一个标签页ngt
:切换到第n个标签页,gt(goto tab)
- 对于窗口:
命令行
:q、:q!、:w、:wq、:ls
- 在正常模式下键入
:
进入命令行模式。 在键入:
后,你的光标会立即跳到屏幕下方的命令行。 这个模式有很多功能,包括打开,保存,关闭文件,以及退出 Vim。:q
退出(关闭窗口):q!
:不保存修改并退出:w
保存(写):wq
保存然后退出:e {文件名}
打开要编辑的文件:ls
显示打开的缓存:help {标题}
打开帮助文档:help :w
打开:w
命令的帮助文档:help w
打开w
移动的帮助文档
★Vim 的接口其实是一种编程语言
- Vim 最重要的设计思想是 Vim 的界面本身是一个程序语言。键入操作(以及他们的助记名) 本身是命令,这些命令可以组合使用。这使得移动和编辑更加高效,特别是一旦形成肌肉记忆。
移动
hjkl、w、^、$、gg、G、/{正则表达式}
- 多数时候你会在正常模式下,使用移动命令在缓存中导航。在 Vim 里面移动也被称为 “名词”, 因为它们指向文字块。
- 基本移动:
hjkl
(左, 下, 上, 右) - 词:
w
(光标移动到下一个词),b
(光标移动到词的开头),e
(光标移动到词的末尾) - 行:
0
(光标移动到行初),^
(光标移动到第一个非空格字符),$
(光标移动到行尾) - 屏幕:
H
(屏幕首行),M
(屏幕中间),L
(屏幕底部) - 翻页:
Ctrl-u
(上翻),Ctrl-d
(下翻) - 文件:
gg
(文件头),G
(文件尾) - 行数:
:{行数}<CR>
或者{行数}G
({行数}为行数) - 杂项:
%
(找到配对,比如括号或者 /* */ 之类的注释对),通过%
来在匹配的一对符号(括号、中括号等)之间跳转 - 查找:
f{字符}
、t{字符}
、F{字符}
、T{字符}
- 查找/到 向前/向后 在本行的{字符}
,
/;
用于导航匹配
- ★搜索:
/{正则表达式}
,n
/N
用于导航匹配
- 基本移动:
选择
v、shift+v、ctrl+v
可视化模式:
- 可视化:
v
- 可视化行:
shift+v
- 可视化块:
Ctrl+v
可以用移动命令来选中。
- 可视化:
使用
gg + v + G + $
命令可以全选文件内容。
编辑
d、dd、x、s、a、r、u、ctrl+r、y、yy、p、.
- 所有你需要用鼠标做的事, 你现在都可以用键盘采用编辑命令和移动命令的组合来完成。 这就是 Vim 的界面开始看起来像一个程序语言的时候。Vim 的编辑命令也被称为 “动词”, 因为动词可以施动于名词。
i
:进入插入模式- 但是对于操纵/编辑文本,不单想用退格键完成
O
/o
:在之上/之下插入行并编辑d{移动命令}
:删除 {移动命令} -> delete- 例如,
dw
删除词,d$
删除到行尾,d0
删除到行头,**dd
删除整行**
- 例如,
c{移动命令}
:改变 {移动命令},等价于d{移动命令}
再i
x
删除字符(等同于d+l
,删除光标所在字符)s
删除字符并插入(等同于x+i
,删除字符后进入插入模式)a
在当前光标所在字符的后面插入r
替换字符(将当前光标所在字符替换为其他字符)- 可视化模式 + 操作
- 选中文字,
d
删除 或者c
改变
- 选中文字,
- ★**
u
撤销 “undo”,<C-r>
重做** y
复制 “yank” (其他一些命令比如d
也会复制)yy
:复制当前行
p
粘贴 “paste”- ★**
.
:重复上一步的操作,如插入了一个词、执行了一条指令等** - 更多值得学习的: 比如
~
改变字符的大小写
计数
- 你可以用一个计数来结合“名词”和“动词”,这会执行指定操作若干次。
3w
向前移动三个词5j
向下移动5行7dw
删除7个词
修饰语
ci(、ci’、da’、da(
ci(
:(change inside),改变当前括号内的内容ci[
:改变当前方括号内的内容da'
:(delete around),删除单引号对内的字符串, 包括该对单引号da(
:删除括号对内的字符串, 包括该对括号