The Missing Semester - 第三讲 学习笔记
阅读原文时间:2023年07月09日阅读:2

第三讲 Vim

课程视频地址:https://www.bilibili.com/video/BV1Dy4y1a7BW

课程讲义地址:https://missing-semester-cn.github.io/2020/editors/

本机学习使用平台:虚拟机ubuntu18.04.6

在编程的时候,你会把大量时间花在阅读/编辑而不是在写代码上。所以,Vim 是一个多模态编辑 器:它对于插入文字和操纵文字有不同的模式。Vim 是可编程的(可以使用 Vimscript 或者像 Python 一样的其他程序语言),Vim 的接口本身也是一个程序语言:键入操作(以及其助记名) 是命令,这些命令也是可组合的。Vim 避免了使用鼠标,因为那样太慢了;Vim 甚至避免用上下左右键因为那样需要太多的手指移动。

这样的设计哲学使得 Vim 成为了一个能跟上你思维速度的编辑器。

然而一开始学习并使用vim的过程总是很痛苦的..看看能不能坚持下去..

Vim 是基于模式的文本编辑器。

Normal --< i >--------> Insert
       --< R >--------> Replace
<esc> <--< V >--------> View
       --< Shift-V >--> View Line
       --< Ctrl-V >---> View Block
       --< : >--------> Command Line

需要熟悉这些切换,不然你就可以在你的屏幕上得到一串随机字符串

因为你会在使用 Vim 时大量使用 <ESC> 键,所以可以考虑把大小写锁定键重定义成 <ESC> 键(MacOS 教程),这个通过 Vim 里面的映射来完成。

我们来了解一下基本操作,起码能做到不慌不忙地退出 Vim。

插入文本

在正常模式,键入 i 进入插入模式。现在 Vim 跟很多其他的编辑器一样,直到你键入 <ESC> 返回正常模式。你只需要掌握这一点和上面介绍的所有基础知识就可以使用 Vim 来编辑文件了 (虽然如果你一直停留在插入模式内不一定高效)。

缓存, 标签页, 窗口

Vim 的窗口与我们以前所用的编辑器都不同。

Vim 会维护一系列打开的文件,称为“缓存”(即 buffer)。一个 Vim 会话包含一系列标签页(即 tab),每个标签页包含 一系列窗口(分隔面板 window)。每个窗口显示一个缓存。跟网页浏览器等其他你熟悉的程序不一样的是, 缓存和窗口不是一一对应的关系;窗口只是视角。一个缓存可以在多个窗口打开,甚至在同一 个标签页内的多个窗口打开。这个功能其实很好用,比如在查看同一个文件的不同部分的时候,即你可以在一个标签页内打开两个窗口,一个窗口看文件头部,一个看文件尾部的内容。你在其中一个窗口输入的时候,另一个在同一个buffer下的窗口内容也会跟着改变。

命令行模式

在正常模式下键入 : 进入命令行模式。 在键入 : 后,你的光标会立即跳到屏幕下方的命令行。 这个模式有很多功能,包括打开,保存,关闭文件,以及退出 Vim。

  • :q 退出(关闭窗口)

  • :w 保存(写)

  • :wq 保存然后退出

  • :e {文件名} 打开要编辑的文件(配合上下键选择已经打开的缓存)

  • :ls 显示打开的缓存

  • :help {标题}

    打开帮助文档时要注意区别:

    • :help :w 打开 :w 命令的帮助文档
    • :help w 打开 w 移动的帮助文档

Vim 最重要的设计思想是 Vim 的界面本身是一个程序语言。键入操作(以及他们的助记名) 本身是命令,这些命令可以组合使用。

移动

  • 基本移动: hjkl (左, 下, 上, 右)
  • 词: w (下一个词), b (词初), e (词尾)
  • 行: 0 (行初), ^ (第一个非空格字符), $ (行尾)
  • 屏幕: H (屏幕首行), M (屏幕中间), L (屏幕底部)
  • 翻页: Ctrl-u (上翻), Ctrl-d (下翻)
  • 文件: gg (文件头), G (文件尾)
  • 行数跳转:
    • :{行数}<CR回车>,跳转的指定的行
    • {行数}G ,跳转到下 n 行
  • 杂项: % (找到配对,比如括号或者 /* */ 之类的注释对)
  • 查找:f{字符} t{字符} F{字符} T{字符}
    • 查找/到 向前/向后 在本行的字符
    • 小写向后查找,大写向前查找
    • f是定位到查找的字符上,t是定位到查找的字符前,大写同理
    • , / ; 用于导航匹配
  • 搜索: /{正则表达式}, n / N 用于导航匹配(下一个/上一个匹配项)

选择

即进入可视化模式:

  • 可视化:v
  • 可视化行: V(即 shift-v
  • 可视化块:Ctrl+v

可以用移动命令来选中。

编辑

所有你需要用鼠标做的事, 你现在都可以用键盘:采用编辑命令和移动命令的组合来完成。 这就是 Vim 的界面开始看起来像一个程序语言的时候。下面是 Vim 处于普通模式下的一些编辑命令:

  • i进入插入模式
  • O / o 在之上/之下插入行并进入插入模式
  • d{移动命令}
    • 删除 +
    • 例如,dw 删除词, d$ 删除到行尾, d0 删除到行头。
  • c{移动命令}
    • 改变 +
    • 例如,cw 改变词
    • 相当于 d{移动命令}ic命令会自动进入insert模式
  • x 删除字符(等同于 dl
  • s 替换字符(等同于 xi
  • 可视化模式 + 操作
    • 选中文字, d 删除 或者 c 改变,或者 y p 复制粘贴
  • u 撤销, <C-r> 重做
  • y 复制 / “yank” (其他一些命令比如 d 也会复制,相当于剪切)
  • p 粘贴 / "paste"
  • 更多值得学习的: 比如 ~ 改变字符的大小写,看老师演示时挺难蚌的

计数

你可以用一个计数来结合“名词”和“动词”,这会执行指定操作若干次。

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

修饰语

你可以用修饰语改变“名词”的意义。修饰语有 i,表示“内部”或者“在内“,和 a, 表示”周围“。

  • i不包含配对符,a则包含
  • ci( 改变当前括号内的内容
  • ci[ 改变当前方括号内的内容
  • da' 删除一个单引号字符串, 包括周围的单引号

这里是一个有问题的 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)

我们会修复以下问题:

  • 主函数没有被调用
  • 从 0 而不是 1 开始
  • 在 15 的整数倍的时候在不用行打印 “fizz” 和 “buzz”
  • 在 5 的整数倍的时候打印 “fizz”
  • 采用硬编码的参数 10 而不是从命令控制行读取参数
  • 主函数没有被调用
    • G 文件尾
    • o 向下打开一个新行
    • 输入 “if name …”
  • 从 0 而不是 1 开始
    • 搜索 /range
    • ww 向前移动两个词
    • i 插入文字, “1, “
    • ea 在 limit 后插入, “+1”
  • 在新的一行 “fizzbuzz”
    • jj$i 插入文字到行尾
    • 加入 “, end=’’”
    • jj. 重复第二个打印
    • jjo 在 if 打开一行
    • 加入 “else: print()”
  • fizz fizz
    • ci' 变到 fizz
  • 命令控制行参数
    • ggO 向上打开
    • “import sys”
    • /10
    • ci( to “int(sys.argv[1])”

展示详情请观看课程视频(37分40秒处)。比较上面用 Vim 的操作和你可能使用其他程序的操作。 值得一提的是 Vim 需要很少的键盘操作,允许你编辑的速度跟上你思维的速度。

# 改后
import sys
def fizz_buzz(limit):
    for i in range(1, limit+1):
        if i % 3 == 0:
            print('fizz', end = '')
        if i % 5 == 0:
            print('fizz', end = '')
        if i % 3 and i % 5:
            print(i, end = '')

def main():
    fizz_buzz(int(sys.argv[1]))

if __name__ == '__main__':
    main()

自定义 Vim

Vim 由一个位于 ~/.vimrc 的文本配置文件(包含 Vim 脚本命令)。你可能会启用很多基本设置。

我们提供一个文档详细的基本设置,你可以用它当作你的初始设置。我们推荐使用这个设置因为它修复了一些 Vim 默认设置奇怪行为。 这儿下载我们的设置,然后将它保存成 ~/.vimrc.

扩展 Vim

Vim 有很多扩展插件。跟很多互联网上已经过时的建议相反,你需要在 Vim 使用一个插件 管理器(从 Vim 8.0 开始)。你可以使用内置的插件管理系统。只需要创建一个 ~/.vim/pack/vendor/start/ 的文件夹,然后把插件放到这里(比如通过 git clone)。

以下是一些老师们使用的插件:

也可以去找找相关的 Vim 插件的博客。

其他程序的 Vim 模式

很多工具提供了 Vim 模式。

  • Shell 如果你是一个 Bash 用户,用 set -o vi,使用set -o emacs来返回默认模式。 Zsh用bindkey -v。Fish 用fish_vi_key_bindings。另外,不管利用什么 shell,你可以 export EDITOR=vim。 这是一个用来决定当一个程序需要启动编辑时启动哪个的环境变量。 例如,git 会使用这个编辑器来编辑 commit 信息。

  • Readline 很多程序使用 GNU Readline 库来作为 它们的命令控制行界面。Readline 也支持基本的 Vim 模式, 可以通过在 ~/.inputrc 添加如下行开启:

    set editing-mode vi

    比如,在这个设置下,Python REPL 会支持 Vim 快捷键。

有关扩展资料

  1. 完成 vimtutor。备注:它在一个 80x24(80 列,24 行) 终端窗口看起来效果最好。

  2. 下载我们提供的 vimrc,然后把它保存到 ~/.vimrc。 通读这个注释详细的文件 (用 Vim!), 然后观察 Vim 在这个新的设置下看起来和使用起来有哪些细微的区别。

  3. 安装和配置一个插件:ctrlp.vim

  4. 练习使用 Vim, 在你自己的机器上重做 演示

  5. 下个月用 Vim 完成所有的文件编辑。每当不够高效的时候,或者你感觉 “一定有一个更好的方式”时, 尝试求助搜索引擎,很有可能有一个更好的方式。如果你遇到难题,可以来我们的答疑时间或者给我们发邮件。

  6. 在其他工具中设置 Vim 快捷键 (见上面的操作指南)。

  7. 进一步自定义你的 ~/.vimrc 和安装更多插件。

  8. (高阶)用 Vim 宏将 XML 转换到 JSON (例子文件)。 尝试着先完全自己做,但是在你卡住的时候可以查看上面 章节。