vim编辑模式_Missing Semester (三):Editors(Vim)

838af10c50ac694298e7f9e10712b19d.png

这是MIT CSAIL推出的短课Missing Semester的第三课。关于课程整体的介绍参见第一篇。

之前的课程:

Missing Semester (一):The Shell

Missing Semester (二):Shell Tools and Scripting

课程原地址:

The Missing Semester of Your CS Education​missing.csail.mit.edu

用英语遣词造句和写代码是截然不同的两种体验。在编程时,你会更多的花时间在文件切换、阅读、浏览与修改代码上,而不是连写一大段话。因此写文章和写代码用不一样的程序是有道理的(比如 Microsoft Word 和 Visual Studio Code)。

作为程序员,我们大部分时间都花在编辑代码上,所以花点时间掌握某个适合自己的编辑器是值得的。这是学习使用新编辑器的过程:

  • 先看教程(比如这节课以及课里提到的额外资料)
  • 坚持使用它来完成你所有的文本编辑工作(即使一开始这会让你的工作效率降低)
  • 随时查阅说明:如果某个操作看起来像是有更方便的实现方法,那可能真的会有

如果你遵循如上的方法,将所有的文本编辑工作都交给新编辑器,学习一个成熟的文本编辑器的时间线就会像这样:在一两个小时内,你会学到编辑器的基础操作,像是打开与编辑文件、保存与退出、浏览buffer。到20个小时左右,新编辑器的工作效率就应该和你用之前顺手的编辑器差不多了。再往后便会获益良多:有了足够的知识和肌肉记忆后,使用新编辑器将大大节省你的时间。而现代文本编辑器都是些复杂且强大的工具,永远有新东西可学:学的越多,效率越高。

该学哪个编辑器?

程序员对自己使用的编辑器都有固执的感情。

现在最流行的编辑器有哪些?可以参考Stack Overflow调查(结果可能会有些偏差,因为Stack Overflow用户并不能代表全体程序员)。Visual Studio Code 是当下最流行的编辑器,而 Vim 则是最流行的基于命令行的编辑器。

Vim

这节课的所有导师都将Vim作为自己的编辑器。它有着丰富的历史:从1976年的Vi编辑器发源,直到现在还在不断更新。Vim的背后有着非常简洁的思想,因此,许多工具都支持模拟Vim模式(举个例子,有140万人安装了 Vim emulation for VS code )。即使你最后换用别的文本编辑器,Vim大概也是值得一学的。

50分钟内肯定讲不完Vim的所有功能,所以我们将重点解释Vim的理念,教授基础操作,展示一些高级应用并且给出掌握Vim所需的其他资源。

Vim的理念

编写程序时,我们大多数时间都花在阅读与编辑上,而不是单纯的写。因此,Vim是一个多模式编辑器:它在插入文本和操作文本时对应不同的模式。Vim是可编程的(通过Vimscript和其他语言比如Python),它的接口本身就是一种程序语言:按键(有助记名)就是命令,同时这些命令是可以组合的。Vim尽可能避免鼠标的使用,因为太慢了;它甚至避免方向键的使用,因为那需要做很多次移动。

于是就诞生了Vim这个能跟上你思考速度的编辑器。

编辑模式

Vim的设计以大多数时间都花在阅读、浏览和稍加改动上为基础,因此有这几种操作模式:

  • 正常模式:在文件中四处移动光标,做些修改
  • 插入模式:插入文本
  • 替换模式:替换文本
  • 可视(一般,行,块)模式:选中文本块
  • 命令模式:运行命令

不同模式下的按键有不同的功能。例如字母 x 在插入模式中就只是插入了一个字符 'x',而在正常模式中则会删除光标下的字符,在可视化模式下,它会删除被选中的所有内容。

在默认配置下,Vim会在左下角显示当前所处的模式。初始/默认为正常模式,一般来说大多数时间你都会使用正常模式与插入模式。

在任何模式下按 <ESC>(左上角退出键)会切换回正常模式。正常模式中,输入 i 进入插入(insert)模式,输入 R 进入替换(Replace)模式, 输入 v 进入可视(Visual)模式,输入 V 进入可视行模式,输入 <C-v> (Ctrl+V,有时也写作 ^V)进入可视块模式,命令模式则通过 : 进入。

使用Vim时会经常用到 <ESC> 键,你可以考虑把 Caps Lock 键映射成退出键(macOS上的操作指南)。

基本操作

插入文本

在正常模式中,按 i 进入插入模式。现在,Vim会表现得像其他大多数文本编辑器一样,直到你按下 <ESC> 返回正常模式为止。其实你只需要知道这些就可以开始用Vim编辑文件了(不过只通过插入模式来编辑的话效率不高)。

Buffer,选项卡和窗口

Vim维护着一组打开的文件,并称它们为“Buffers(暂存,缓冲)”。一个Vim会话下有数个分页,每个分页中则有数个窗口(分屏的窗格),每个窗口中显示一个buffer。和其他你熟悉的程序,比如网页浏览器不同的是,buffer与窗口之间并没有一一对应的关系,窗口只是用来显示。一个特定的buffer可以在多个窗口中被打开,甚至是同一分页下的窗口。这一点有时会很方便,例如,需要同时查看一个文件的两个部分时。

默认情况下,Vim打开时有一个分页,其中包含一个窗口。

命令行

命令模式由正常模式下输入 : 进入,你的光标同时会跳转到屏幕底部的命令行。这一模式有许多功能,包括打开、保存和关闭文件,以及退出Vim。

  • :q 退出(关闭窗口)
  • :w 保存(“Write”)
  • :wq 保存并退出
  • :e {文件名} 打开文件以编辑
  • :ls 显示目前打开的所有buffer
  • :help {主题} 打开帮助
    • :help :w 打开 :w 命令的帮助
    • :help w 打开 w 移动的帮助

Vim的接口就是一种程序语言

Vim中最重要的一个概念就是,Vim的接口本身是一种程序语言。按键(有助记名)即命令,而且它们相互组合。这使得高效地移动与编辑成为可能,尤其是当这些命令成为肌肉记忆时。

移动

在正常模式下的大多数时间里,你都应该在使用移动命令浏览buffer。Vim中的移动命令也被称为“nouns(名词)”,因为它们本质上指的是某种文字区块。

  • 基础移动:hjkl (左,下,上,右)
  • 词:w (下一个词,word), b (单词开头,beginning),e (单词结尾,end)
  • 行:0 (行的开头),^ (第一个非空字符), $ (行的结尾)
  • 屏幕: H (屏幕顶端,High), M (屏幕中央,Middle),L (屏幕底端,Low)
  • 滚动: Ctrl-u (向上,up),Ctrl-d (向下,down)
  • 文件: gg (文件开头), G (文件结束)
  • 行数: :{number}<CR>{number}G (number即行数)
  • 多功能: % (对应的功能)
  • 查找:f{character}t{character}F{character}T{character}
    • 在当前行中 向前/向后 查找(find/Find)/前往(to/To){character}的位置
    • , / ; 在多个匹配结果中切换
  • 搜索:/{regex} ,用 n / N 在结果中切换

选择

可视模式:

  • 可视
  • 可视 行
  • 可视 块

可以用移动按键来选中文本。

编辑

之前所有由鼠标完成的操作,现在你都可以通过键盘将编辑命令与移动命令组合来完成。从这里开始,Vim的接口就开始像程序语言了。Vim的编辑命令被称为“动词”,因为动词对名词进行操作。

  • i 进入插入模式
    • 但对于操作/删除文本,除了退格之外还有更多方法
  • o / O 在下一行/上一行插入
  • d{motion} 删除{motion}
    • 例如, dw 是删除单词, d$ 删除到行尾, d0 删除到行首
  • c{motion} 修改{motion}
    • 例如, cw 是修改单词
    • 相当于 d{motion} 之后接 i
  • x 删除字符(相当于 dl
  • s 替换(substitute)字符(相当于 xi
  • 可视模式+操作
    • 选中文本后,用 d 来删除或用 c 来修改
  • u 撤销(undo),<C-r> 恢复(redo)
  • y 复制,把文本“拽(yank)”到寄存器里(有些其他的指令比如 d 也会复制)
  • p 粘贴(paste)
  • 还有很多要学的:像是 ~ 会反转字符的大/小写

计数

你可以把名词动词与数字结合起来,这会让给定的操作执行一定次数。

  • 3w 向前移动3个单词
  • 5j 向下移动5行
  • 7dw 删除7个单词

修饰语

你可以使用修饰语来改变名词的意思。一些修饰语像是 i 表示“内部(inner)”或是“里面(inside)”, a 则表示“围绕(around)”。

  • ci( 修改当前圆括号对中的内容
  • ci[ 修改当前方括号对中的内容
  • da' 删除单引号内的字符串,包括两边的单引号

示例

这是一个失败的 fizz buzz 实现:

译注:简单来说就是从1往上数,遇到3的倍数就说fizz,5的倍数就说buzz,15的倍数就说fizz 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)

我们将要修复如下的问题:

  • Main从未被调用
  • 从 0 而不是从 1 开始
  • 对于15的倍数“fizz”和“buzz”会分两行输出
  • 对5的倍数也输出了“fizz”
  • 直接把10写死了,无法接受命令行输入的参数

具体演示在讲座视频中(37分30秒开始)。比较用Vim实现这些改动和你用其他的编辑器来做有什么不同。在Vim中只需要很少的按键,这让你编辑的速度和思考一样快。

自定义Vim

Vim通过 ~/.vimrc 中的一个文本配置文件(包括一些Vimscript命令)来自定义。其中可能有一大堆基本选项你都想打开。

我们已经准备了一份写好文档的基础配置,你可以一开始先用着。我们推荐你使用这份配置,因为它修复了Vim本身一些奇怪的默认行为。在此处下载我们的配置,并保存到 ~/.vimrc

Vim是高度可自定义的,值得花些时间研究一下这些选项。你可以在Github上查看别人的配置文件来找些灵感,比如说,这门课导师们的配置文件(Anish,Jon(他用的是neovim),Jose)。这一主题下还有很多优秀的博文。尽量不要直接复制粘贴整个配置文件,而是阅读,理解,然后取你需要的部分。

扩展Vim

有非常多的插件可以用来扩展Vim。与你可能在网上找到的那些过时的建议相反,从Vim8.0开始,你不再需要一个插件管理器。作为替代,你可以使用内置的包管理系统。只需要新建一个文件夹 ~/.vim/pack/vendor/start/ ,然后把插件放进去(例如通过 git clone)就可以了。

这是一些我们最爱的插件:

  • ctrlp.vim : 文件模糊查询
  • ack.vim : 代码查找
  • nerdtree : 文件浏览器
  • vim-easymotion :更好的移动

我们尽可能避免在这里列出太长的插件列表。你可以通过导师们的配置文件来查看他们用了哪些插件(Anish,Jon,Jose)。查看 Vim Awesome网站 来寻找更多好用的插件。同时也有无数的博客文章:只需要搜索“best Vim plugins(最好用的Vim插件)”就可以。

其他程序的Vim模式

许多其他工具都支持模拟Vim。虽说质量参差不齐,取决于具体的工具,不一定支持所有的Vim特性,但大多数都很好的覆盖了基本功能。

Shell

如果你是Bash用户,set -o vi 。如果你是Zsh用户, bindkey -v 。Fish用户使用 fish_vi_key_bindings。此外,不管你使用何种shell,都可以使用 export EDITOR=vim 。这个环境变量决定了启动编辑器时默认启动哪一个。举例来说, git 就会调用编辑器来编辑提交信息。

Readline

许多程序都使用 GNU Readline 库作为命令行接口。Readline支持(基础)Vim模拟,可通过将以下内容加入 ~/.inputrc 文件来启用:

set editing-mode vi

有了这一设置,像 Python REPL 等就会支持Vim键位。

其他

甚至网页浏览器()都有vim键位扩展,其中一些比较流行的有 Google Chrome 的 Vimium 和 Firefox的 Tridactyl 。 连 Jupyter notebooks 都有Vim键位支持。

进阶Vim

接下来的一些例子展示了Vim的强大之处。我们无法教给你全部,但你会随着使用慢慢学到。有种启发式学习法:使用编辑器时,每当你觉得“一定有什么更好的方法来做这件事”,就去网上查一下是不是真的有。

查找与替换

:s (替换,substitute)命令 (文档)

  • %s/foo/bar/g
    • 把文件中所有的foo替换成bar
  • %s/[.]((.))/1/g
    • 将所有Markdown文字链接换成地址

多窗口

  • :sp / :vsp 拆分窗口
  • 同一个buffer可以被多个窗口查看

宏命令

  • q{character} 开始录制宏,并保存在寄存器 {character}
  • q 停止录制
  • @{character} 运行录制好的宏
  • 宏命令遇到错误会中止
  • {number}@{character} 将宏执行{number}次
  • 宏可以是递归的
    • 首先用 q{character}q 将宏清空
    • 录制宏时,使用 @{character} 来递归使用宏(在录制完成前不会执行)
  • 举例:将xml转换为json (文件)
    • 一个对象数组,键为“name”和"email"
    • 要使用Python吗?
    • 还是用sed/regexes?
      • g/people/d
      • %s/<person>/{/g
      • %s/<name>(.*)</name>/"name": "1",/g
      • ...
    • 使用Vim命令/宏
      • Gddggdd 删除首位行
      • 录制格式化一个元素的宏(使用寄存器 e
        • 前往有 <name> 的行
        • qe^r"f>s": "<ESC>f<C"<ESC>q
      • 录制格式化一个人物对象的宏
        • 前往有 <person> 的行
        • qpS{<ESC>j@eA,<ESC>j@ejS},<ESC>q
      • 录制格式化完成跳转到下一个对象的宏
        • 前往有 <person> 的行
        • qq@pjq
      • 执行宏直到文件尾
        • 999@q
      • 手动删除最后的 , 并加上 [ ] 分隔符

资源

  • vimtutor Vim安装时自带的教程
  • Vim Adventures 一个用来学习Vim的游戏
  • Vim Tips Wiki
  • Vim Advent Calendar 有各种Vim小提示
  • Vim Golf 是 code golf 的Vim UI版
  • Vi/Vim Stack Exchange
  • Vim Screencasts
  • Practical Vim(实体书)
  • 既然是中文翻译,我自己加一个中文手册,感谢 Nek_in 的翻译。

习题

  1. 完成 vimtutor。注:在 80x24 尺寸(80列,24行)的终端窗口下显示效果最好。
  2. 下载我们的 basic vimrc 并将其保存到 ~/.vimrc。使用Vim阅读全文,寻找使用新配置的Vim与之前的不同之处。
  3. 安装并配置插件:ctrlp.vim。
    1. 使用 mkdir -p ~/.vim/pack/vendor/start 创建插件目录
    2. 下载插件:cd ~/.vim/pack/vendor/start; git clone https://github.com/ctrlpvim/ctrlp.vim
    3. 阅读插件文档。尝试使用它来定位某个文件:进入项目目录,打开Vim,命令行 :CtrlP
    4. 通过给 ~/.vimrc 添加配置来自定义CtrlP,使得按下Ctrl-P就能打开它。
  4. 在自己的机器上重现课上的示例(fizz buzz)。
  5. 下个月所有的文本编辑都用Vim完成。当你发现有不方便的地方,或者你觉得“这肯定有更好的办法”,就去搜索可能的解决方案。如果还有难处,可以给我们发邮件。
  6. 把你其他的工具配置成Vim键位(参见上面的说明)。
  7. 进一步定制你的 ~/.vimrc 并安装其他插件。
  8. (进阶)使用Vim宏完成XML到JSON的转换(示例文件)。尝试独立完成,如果遇到困难,可以查看宏那一节。

Licensed under CC BY-NC-SA 4.0。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值