主题 3 编辑器(Vim)
主题 3 编辑器(Vim)
编辑器 (Vim) · the missing semester of your cs education (missing-semester-cn.github.io)
代码编辑器和和其他的编辑器(比如用来写文章的编辑器)有一些不同。
因为写程序和写文章不同。当你写程序时,会花大量时间来阅读你写的东西,或者来移动光标,做一些小小的修改;而不是像写文章的时候,从上到下一气呵成。因此,对于不同的用途,我们会使用不同的编辑器。
1.编辑器选择
Stack Overflow 的调查 显示,VS Code 是目前最流行的代码编辑器。而 Vim 则是最流行的基于命令行的编辑器。就算最终你没有打算长期使用Vim,我们仍然认为学习Vim背后的思想很有价值。
另外,许多工具也觉得 vim 哲学很棒,从而提供了 Vim 模式。例如当前最热门的 VS Code,支持 Vim 键位绑定,该插件已经被下载了数百万次。
2.Vim的思想
Vim 是一个基于模式(Modal)的编辑器,这意味着 Vim 有多个模式。
Modal 这个词源于 Mode
多模式的思想源于,当你在写程序的时候会经常做不同的事情,在编程的时候,你会把大量时间花在阅读/编辑而不是在写代码上。
所以 Vim 是一个多模态编辑器:它对于插入文字和操纵文字有不同的模式。
Vim 是可编程的(可以使用 Vimscript 或者像 Python 一样的其他程序语言)。
Vim 的接口本身也是一个程序语言:键入操作(以及其助记名) 是命令,这些命令也是可组合的。Vim 避免了使用鼠标,因为那样太慢了;Vim 甚至避免用上下左右键因为那样需要太多的手指移动。
这样的设计思想使得 Vim 成为了一个能跟上你思维速度的编辑器。
3.编辑模式
正常模式:Normal,在文件中四处移动光标进行修改
插入模式:Insert,插入文本
替换模式:replace,替换文本
可视化模式(一般,行,块):Visual,Visual Line,Visual Block,选中文本块
命令行模式:Command Line,用于执行命令
- Normal 正常模式 & Insert 插入模式
当你开始使用 Vim 时,它会在 Normal 模式下启动。
在这个模式下,各种键位组合拥有在这个模式下的特定意义。其中就有一些按键组合来切换到其他的模式。而切换后这些键位组合和意义也相应改变。
但你的大部分时间都会在 Insert 和 Normal 模式下,在Normal模式下按下i
键就可以进入Insert模式。而在Insert模式下按下Esc
就可以回到Normal模式。
这里注意一下我们表示按键的方式,这个表示方式将会用于笔记以及Vim给你的提示中:
当仅仅是代表
i
键这样一个按键本身时,那么就会直接写i
。但是对于如Ctrl+v这种按键组合,就有可能以这么几种形式来体现:第一种是一个脱字符号后跟着控制用字符:
^v
(这里控制用字符指v,也就是组合键中的另一个键),另一种写法可能是你最熟悉的:Ctrl-v
,而有的地方我们可能会写成:<c-v>
Vim 有好几种模式,而 Normal 模式是用来移动光标、阅读东西,以及在文件间切换的。
而 Insert 模式是用来输入的,因此在 Insert 模式下,你的按键大多会直接进入 buffer(缓冲区),而在 Normal模式下则不然,它们不会进入 buffer,而是用来进行了一些浏览和编辑操作。
- replace 替换模式
不像插入模式那样会把字符往后移,替换模式会直接覆盖掉文本。
- 可视化模式(一般,行,块)
可视化模式有 Visual 模式,Visual Line 模式,以及一个 Visual Block 模式。
- 各种模式的切换
你可以按下 <ESC>
(退出键)从任何其他模式返回正常模式。在正常模式,键入 i
进入插入 模式,R
进入替换模式,v
进入可视(一般)模式,shift+V
进入可视(行)模式,<C-v>
(Ctrl-V, 有时也写作 ^V
)进入可视(块)模式,:
进入命令模式。
- 映射Esc键
从非 Normal 模式切换到 Normal 模式下都是按 Esc
键,因此使用 Vim 时要频繁按 Esc
键。但这个键在键盘的角落里,按起来很不方便,所以很多人会将键盘上某个键映射成 Esc。通常这个键是 Caps Lock
,因为它在键盘的中间一行上。
4.基本操作
- 如何打开Vim程序
Vim 是一个基于命令行的编辑器,我们要打开 Vim,只需要在命令行中键入 vim
。
vim 也可以接收参数,当我们想用它直接编辑特定的文件时,可以在 vim 后面加上文件的路径+文件名。
[lighthouse@VM-8-17-centos vim]$ ls
poem.md
[lighthouse@VM-8-17-centos vim]$ vim poem.md
4.1插入文本
Vim 以 Normal 模式启动。在 normal 模式下按下i
键,进入 Insert 模式,屏幕左下角将会提示--INSERT--
。在插入模式下按下<esc>
键,可以返回 Normal 模式。
左下角总会显示你所在的模式,但 Nomal 模式下是空白的。
4.2命令行
在 Normal 模式按下 :
(冒号)将会进入命令行模式。这时你的光标将会跳到屏幕左下方的命令行。这个模式有很多功能,包括打开,保存,关闭文件,退出 vim。
在命令行模式下:
命令 | 释义 |
---|---|
:q / :quit |
退出(关闭窗口) |
:w / :wirite |
保存文件 |
:wq |
保存并退出 |
:ls |
显示打开的缓存 |
:e {文件名} |
打开对应文件 |
:help <特定键/特定命令> |
打开帮助文档 |
注意,这里的特定命令和特定键不同,如 :help :w
表示获取命令 :w
的说明,而 :help w
表示在 Normal 模式下 w 键的说明。
4.3buffer, tab, window
Vim 会维护一系列打开的文件(buffer),称为缓存。
一个 Vim 会话包含一系列标签页(tab),每个标签页包含一系列窗口(window,分隔面板)。每个窗口显示一个缓存(buffer)。
跟普通的程序不一样的是, 缓存和窗口不是一一对应的关系;窗口只是视角。一个缓存可以在多个窗口打开,甚至在同一个标签页内的多个窗口打开。这个功能其实很好用,比如在查看同一个文件的不同部分的时候。
Vim 默认打开一个标签页,这个标签包含一个窗口。
5.Vim的接口是一种编程语言
Vim 最重要的设计思想是 Vim 的界面本身是一个程序语言。你可以键入命令来对文件,窗口等进行操作。而不仅仅是编辑字符。
5.1移动命令
Normal 模式下:
-
基本移动:
h j k l
(左, 下, 上, 右) -
以词为单位:
w
(word,向前移动一个单词)b
(beginning of word,向后移动一个单词)e
(end of word,移动到单词末尾)
-
以行为单位:
0
(到行首)^
(到本行第一个非空格字符)$
(到行末)
-
屏幕:
H
(Highest,屏幕首行),M
(Middle,屏幕中间),L
(Lowest,屏幕底部) -
翻页:
Ctrl-u
(上翻),Ctrl-d
(下翻) -
文件:
gg
(到文件最开始),G
(到文件最底部) -
行数:
:{行数}<CR>
或者{行数}G
({行数}为行数) -
杂项:
%
(找到配对,比如括号或者 /* */ 之类的注释对) -
查找:
f{字符}
,t{字符}
,F{字符}
,T{字符}
-
f{字符}
/t{字符}
:相对于光标,在本行向前查找的第一个匹配的 -
F{字符}
/T{字符}
:相对于光标,在本行向后查找的第一个匹配的相对于f/F,t/T 查找的光标不会落在匹配的字符上,而是落在匹配的字符的前一个/后一个字符
-
,
/;
用于导航匹配
-
-
搜索:
/{正则表达式}
,此时n
/N
用于前后导航匹配,Esc+u
撤销搜索高光显示(或者使用:nohlsearch
)
5.2编辑命令
在 Normal 模式下:
-
按下
i
,进入insert模式 -
按下
o
键,可以在光标下面开(open)新的一行,同时切入 Insert 模式。 -
按下
O
键,在光标上面开新的一行,同时切入 Insert 模式 -
d{移动命令}
,命令可以配合移动命令来选择删除范围dw
删除词d0
删除到行首d3l
向右删除3个字符de
从当前位置开始删除到词末
-
c{移动命令}
,和上面命令相似,不同的是它删除后会进入insert模式(c代表change)cw
删除词,并进入insert模式c$
删除到行尾,并进入到insert模式
c 和 d 这两个命令很像,它们都会接受一个操作范围作为参数,然后按照操作的范围进行删除或者更改。不同在于c命令会进入insert模式,d命令不会
-
如果按下某个编辑键两次,它将作用于当前行
dd
删除当前行cc
删除当前行,并进入insert模式
-
x
删除一个字符(等于dl
) -
r
替换一个字符 -
u
撤销操作,最早可以回到你打开的状态 -
ctrl+r
重做操作 -
y
赋值(yank,提取,拉拽),y 也接收一个操作范围作为参数yy
复制当前行yw
复制单词
-
p
粘贴
5.3选择命令
Visual 模式下可以使用大多数 Normal 模式下的移动命令移动光标,它会自动选中移动范围的文本,然后可以对其进行操作,其中最常用的就是复制(y)这段文本,复制完后会自动退回普通模式。
-
普通 Visual 模式(normal 模式下按
v
进入) -
Visual Line 模式(normal 模式下按
V
进入),它的操作以行为单位,一次可以选择一行文字。 -
Visual Block 模式(normal 模式下按
ctrl+v
进入),它可以选择矩形的文字块,其他与上述模式类似。
5.4计数
数字可以和移动、编辑、选择命令结合。
例如:4j
:表示执行j命令4次,光标向下移动4行;5w
:执行w命令5次,光标向前移动5个单词。或者在普通visual模式下,按10e
,就可以向右选中单词10次;
还可以和编辑命令结合,例如:7dw
,表示执行dw命令7次,向右删除7个单词。
5.5修饰语
你可以用修饰语改变“名词”的意义。修饰语有 i
,表示“内部”或者“在内“(inside),和 a
, 表示”周围“(around)。
ci(
删除当前括号()
之内的内容;di(
删除包括()
在内的内容ci[
改变当前方括号[]
之内的内容;di[
删除包括[]
在内的内容da'
删除一个单引号字符串, 包括周围的单引号
6.演示
这里有一个存在bug的代码fizz_buzz,使用vim来快速修改它:
fizz_buzz是一个输出1到n的练习,当数字能被3整除时,输出fizz;当数字能被5整除时,输出buzz;当数字同时能被3和5整除时,输出fizzbuzz;如果这些条件都不满足,就直接输出数字。
例如:1,2,fizz,4,buzz,...
def fizz_buzz(limit):
for i in range(limit):
if i % 3 == 0:
print('fizz')
if i % 5 == 0:
print('fizz')
if i % 3 and i % 5:
print(i)
def main():
fizz_buzz(10)
问题和解决操作:
问题一:主函数没有被调用:
-
G
跳到文件尾 -
o
向下打开一个新行 -
输入 “if name …”
问题二:fizz_buzz命令应该从 0 而不是 1 开始
-
搜索
/range
-
ww
向前移动两个词 -
i
插入文字1,
-
ea
在 limit 后插入+1
(a表示append)
问题三:在 5 的整数倍的时候打印 “fizz”
-
搜索
/fizz
,按n搜索下一个,一直到第三个"fizz“ -
键入
ci'
,再将“fizz”改为“buzz”
问题四:在 15 的整数倍的时候在换行打印了 “fizz” 和 “buzz”
-
在第四行,键入
$i
插入文字到行尾,然后加入内容, end=''
-
想要对下两行如法炮制,先键入
jj
跳到下两行,然后键入.
(在vim中按下.
会重复之间的编辑命令) -
jjo
在 if 打开一行 -
加入 “else: print()”
问题五:采用了硬编码的参数 10 而没有从命令控制行读取参数
-
gg
回到文件头,O
向上打开新行,然后键入内容“import sys”,然后回到normal模式 -
键入
/10
,跳到10
文字处,然后键入ci(
命令,添加内容:int(sys.argv[1])
7.自定义Vim
Vim 由一个位于 ~/.vimrc
的文本配置文件(包含 Vim 脚本命令)。
在这儿下载我们的设置,将它保存成
~/.vimrc
Vim 能够被重度自定义,你可以参考其他人的在 GitHub 上共享的设置文件如:Anish, Jon (uses neovim), Jose。
8.扩展Vim
Vim 有很多扩展插件。可以使用内置的插件管理系统。只需要创建一个 ~/.vim/pack/vendor/start/
的文件夹,然后把插件放到这里(比如通过 git clone
)。
以下是一些常用插件:
- ctrlp.vim: 模糊文件查找
- ack.vim: 代码搜索
- nerdtree: 文件浏览器
- vim-easymotion: 魔术操作
可以查看开源的配置文件 (Anish, Jon, Jose) 或者浏览 Vim Awesome 来了解一些很棒的插件。
这个话题也有很多博客文章,可以搜索 “best Vim plugins”。
9.拓展资料
vimtutor
是一个 Vim 安装时自带的教程- Vim Adventures 是一个学习使用 Vim 的游戏
- Vim Tips Wiki
- Vim Advent Calendar 有很多 Vim 小技巧
- Vim Golf 是用 Vim 的用户界面作为程序语言的 code golf
- Vi/Vim Stack Exchange
- Vim Screencasts
- Practical Vim(书籍)
10.课后练习
参考答案:Solution-编辑器 (Vim)
-
完成
vimtutor
。备注:它在一个 80x24(80 列,24 行) 终端窗口看起来效果最好。直接在linux的shell中键入
vimtutor
即可看到文档,这里是中文文档 -
下载我们提供的 vimrc,然后把它保存到
~/.vimrc
。 通读这个注释详细的文件 (用 Vim!), 然后观察 Vim 在这个新的设置下看起来和使用起来有哪些细微的区别。 -
安装和配置一个插件: ctrlp.vim.
- 用
mkdir -p ~/.vim/pack/vendor/start
创建插件文件夹 - 下载这个插件:
cd ~/.vim/pack/vendor/start; git clone https://github.com/ctrlpvim/ctrlp.vim
- 阅读这个插件的 文档。 尝试用 CtrlP 来在一个工程文件夹里定位一个文件,打开 Vim, 然后用 Vim 命令控制行开始
:CtrlP
. - 自定义 CtrlP:添加 configuration 到你的
~/.vimrc
来用按 Ctrl-P 打开 CtrlP
- 用
-
练习使用 Vim, 在你自己的机器上重做 演示。
-
下个月用 Vim 完成所有的文件编辑。每当不够高效的时候,或者你感觉 “一定有一个更好的方式”时, 尝试求助搜索引擎,很有可能有一个更好的方式。如果你遇到难题,可以来我们的答疑时间或者给我们发邮件。
-
在其他工具中设置 Vim 快捷键 (见上面的操作指南)。
-
进一步自定义你的
~/.vimrc
和安装更多插件。 -
(高阶)用 Vim 宏将 XML 转换到 JSON (例子文件)。 尝试着先完全自己做,但是在你卡住的时候可以查看上面宏章节。