神级编辑器 Vim 使用-基础篇

最近一段时间, 看了两本关于 vim 的书, 重新学了一遍 vim, 在感慨 vim 强大的同时, 也为从前的自满感到汗颜, 我拿起了从前做的关于 vim 的笔记, 重新梳理了一遍, 作为一个系列分享到网上, 主要目的是想让更多 vim 的爱好者能够掌握更多的操作技巧.

本系列 vim 笔记的目的不是从零教会你如何操作 vim, 而是作为一本手册或者扩展你的视野, 让你知道原来 vim 还能这么用.

希望你能从本系列教程中收获到你感兴趣的部分内容!

himg

本系列教程共分为以下五个部分:

  1. 神级编辑器 Vim 使用-基础篇
  2. 神级编辑器 Vim 使用-操作篇
  3. 神级编辑器 Vim 使用-插件篇
  4. 神级编辑器 Vim 使用-正则操作篇
  5. 神级编辑器 Vim 使用-最后

vim 是否值得学习

网上有很多形容 vim 的学习曲线是如何陡峭的说法. 人, 最恐惧未知的事情. 如果有人给你说: 你花一天的时间找一个入门教程进行学习就可以学会基础操作, 你会学习 vim 吗? 绝大部分人都是会的, 其实事实也就是这样, 如果只是基础操作的话 1 天时间绝对是够了. 但是绝大多数人得不到这样的答案, 所以他们关上了这扇窗.

在我看来, vim 的学习投入与产出的性价比是很高的, 学习了 vim 后你会有如下的一系列好处:

  • vim 基于终端, 熟练掌握 vim 后你对终端的理解也会变得更为深刻
  • vim 可以联合终端中的其他工具共同组成你的工具链(譬如 git)
  • Atom, Sublime, VSCode, NOTEPAD++ 等工具泛滥的如今, 你可以选择一个有着近 40 年历史的经过了时间考验的编辑器
  • 操作远程服务器时经常需要在终端中进行文本编辑, vim 可以让你如履平地
  • vim 支持所有平台, 你可以使用一份配置文件全平台通用
  • 装 13

编辑器的切换是有成本的, 而且成本不小. 任何事情做到一半再去做另外的事情绝对比从一而终的人损失大得多, 因此选择一个适合自己的编辑器作为以后的伙伴是一件应该慎重的事情, 而使用过 vim 的人很少会再换用其他的编辑器, 这应该能说明很多问题.

有些人持有工具无用论的观点, 认为写好代码才是一切, 事实确实是这样. 但是难道有人会拒绝更快速, 更高效的写完一段优雅的代码吗? 这两者并非是鱼和熊掌不可兼得, 我们都可以有.

这方面话题比较容易引战, 点到为止, 具体如何交由读者自行判断.

Let’s go!

安装

第一步当然是安装, 这里对 MacOSLinux 进行安装示范

MacOS

不同版本安装

  1. 系统内置

    Mac OS 默认内置 vim, 在没有安装任何其他版本 vim 的情况下在终端中输入 vim --version 可看到如下图:

    himg

    + 代表含有的功能, - 代表不包含的功能. 可以看到系统内置 Vimclipboard 选项为 - , 代表没有剪贴板功能, 也就是说不会与系统剪贴板有任何互动, 即在 vim 中的内容无法复制到另一个程序中, 无论如何设置都无法改变. 这是最大的区别.

    而且由于是系统内置, 所以如果想要手动升级的话没有可能, 只能等到系统更新的时候 Apple 更新官方内置 vim .

  2. 官方版 Vim, 通过 Homebrew 安装

    在终端输入 brew install vim 可以通过包管理工具 Homebrew 来安装官方版本 Vim. 安装完后的 vim 位置在 /usr/local/bin/vim (通过系统命令 which vim 可以知道具体程序的路径), 而系统自带的 vim 位置在 /usr/bin/vim, 如果要使用通过 Homebrew 安装的 Vim, 则必须将系统识别的环境变量 PATH 顺序调整为

    1
    2
    3
    4
    5
    /usr/local/bin
    /usr/bin
    /bin
    /usr/sbin
    /sbin

    调整 PATH 顺序方法: 打开路径 /private/etc/paths (此为隐藏路径, 需要打开显示隐藏文件开关才能看到), 使用任意文本编辑器打开修改并保存. 如下图:

    himg

    这样设置之后当在终端中输入 vim 时系统会先对 /usr/local/bin 路径进行检索, 如果此路径没有的话在对 /usr/bin 进行检索, 以此类推. 此时再次验证 which vim 命令, 如果返回了 /usr/local/bin 就说明设置成功. 以后只要是使用 vim [filename] 即可使用通过 Homebrew 安装的 vim 来打开了.

    此时通过 vim --version 可看到如下图

    himg

    最大的改变是 clipboard 选项变为了 +, 而且很多功能也变为了 + .

    通过 Homebrew 安装的 vim 一切都很好, 我也用了很长一段时间, 但是有两个问题一直困扰着我:

    1. 使用输入法插件在插入模式与普通模式切换之间有较大延迟, 例如在退出输入模式后会有 2-3 秒的延迟, 在这段延迟中如果我操作了键盘任何键位, 结果将被键入到输入法中. 体验极差.

    2. 速度. 在编辑较长的 Markdown 文件时, 如果开启了语法渲染以及底部状态栏插件的话会在快速移动光标过程中有较大延迟. 这种感觉在遇到语法段落结构复杂, 且光标移动较快时最为明显. 极大的影响了使用感受.

      如果 vim 一直是这种问题的话也当不得 编辑器之神 的称呼了. 我上网搜索后发现有很多人都跟我一样注意到了这一点. Mac 终端上的 vim 速度慢, 卡顿, 在 Linux 下就非常流畅没有任何延迟. 通过多方查证, 我测试了 MacVim 在 Mac 系统下的流畅程度. 果然有惊喜.

  3. MacVim, 通过 Homebrew 安装

    MacVimvim 在 Mac 系统的移植, 其内核与官方版本保持一致. 也就是说如果官方版本的 vim 在 Mac 上能实现什么功能, 那么 MacVim 也能实现相同的功能.

    通过 Homebrew 安装的话只需要用到命令 brew install macvim. 安装完成后在终端使用 mvim 即可打开 MacVim 桌面程序.

    如果想通过终端打开 MacVim 的命令行版本, 使用 mvim -v [filename] 即可.

    注: 由于通过 Homebrew 安装的绝大部分包都没有 GUI, 因此 Homebrew 不会将包移入 /Applications, 这导致了如果想在桌面上双击一个文件来使用 MacVim 打开很难实现, 而且在 Mac 的 LaunchPad 里是找不到 MacVim 的(即使它是一个 GUI 软件)

    因此, 有了下一个解决方法.

  4. MacVim, 通过 Homebrew Cask 安装

    CaskHomebrew 的一个软件管理程序. Homebrew 本身就已经是包管理工具了, 其下的 Cask 又能管理程序, 一层套一层, 真会玩. 不过 Homebrew 绝大部分包都是一些环境, 而不是日常用户操作的交互式软件. 而 Cask 绝大部分包都是 GUI 软件. 通过 Cask 我们能安装绝大部分我们日常需要的软件, 比如 QQ, 音乐, 浏览器, 各种工具…

    通过 brew install cask 安装 Cask 包. 安装完成后再通过 brew install macvim --cask 来安装 MacVim .

    himg

    安装完成后你可以通过终端得知 MacVim 自动将 mvim 命令与路径 /usr/local/bin 里的 vim, gvim, view 等命令进行了绑定. 这表示在 系统变量 PATH/usr/local/bin 第一的时候, 我们只要是使用 vim, gvim, view 中的任意一个都会打开 MacVim 桌面端程序.

    如果此时还是想用 MacVim 以命令行模式打开文件的话可以使用 mvim -v 或者 vim -v 或者其他几个绑定的命令. 当然我为了方便直接在 ~/.zshrc (我是用的是 zsh) 中设置了 alias.

    1
    alias vim='mvim -v'

    设置完记得使用 source ~/.zshrc 或者重启终端来重载 ~/.zshrc

对比与总结

通过 MacVim 与 终端 vim 的安装体验对比, 总结了 MacVim 的如下优缺点(同样对应 vim 的优缺点):

  1. 优点

    • 有系统级别的复制粘贴撤销快捷键,
    • 滚动更流畅,
    • 输入法切换速度更快,
    • 右侧的导航滑轨也有了作用
  2. 缺点

    • 没有集成在终端中意味着与终端切换的成本更大
  3. 总结

    如果必须在 Mac 上使用 vim, 而且对流畅度要求比较高, 那么就是用 MacVim 吧.

    如果绝大多数工作环境都在终端上完成, 那么就使用终端 vim .

    如果要求兼具了以上两者, 就等待吧, 等官方解决 Mac 系统上的延迟问题

CentOS

在 CentOS 中我们可以使用如下方法安装 vim

  • 源码编译
  • yum 安装
  • GUI 版 vim 安装

但是经过多次试验之后发现这三种方法的前两种都是剪贴板缺失的 vim, 也就意味着不能与系统剪贴板进行交互, 因此最好安装 GUI 版 Vim

1
sudo yum install vim-X11

调用 vim 时使用 vimx 代替 vim

Debian && Ubuntu

安装 vim-gtk or vim-gnome.

Arch Linux

安装 install gvim

Vim 模式区分

模式是 vim 与其他编辑器的最重要区别之一, 简单来说就是同样一个界面的同样操作在不同模式下会产生不同的效果. 最常用的模式有 Normal Mode, Insert Mode, Visual Mode, 与 Command Line Mode

普通模式(Normal mode)

Vim 默认模式, 又称为命令模式, 可使用 hjkl 进行移动和简单编辑

插入模式(Insert Mode)

该模式下可以尽情地输入, 普通模式通过 i, a, o, cc 等命令可进入插入模式.

可视模式(Visual Mode)

与普通模式类似, 不同的是当移动时会进行扩展当前的选择区域. 普通模式按 v(进入字符选择模式) 或 V (进入行选择模式)进入该模式

命令行模式(Command Line Mode)

在该模式下可以在窗口的下方输入一行命令, 然后执行. 当一条命令执行完会自动退出命令模式进入普通模式.

命令模式通过输入 : 进行开启

替换模式(Replace Mode)

新输入的文本会替换光标所在处的文本, 并使光标依次向后移动.

普通模式下通过按 R 进入该模式

Ex Mode

与命令模式相似, 不同的是在该模式下可执行多次命令不会自动退出命令模式. 直至输入 :visual 退出该模式

在普通模式下通过按 Q 可以进入该模式

vim 键位映射

当我们写了脚本或者不喜欢某些按键的触发方式, 我们当然可以将其改为我们认为最适合我们的键位, vim 对按键映射做了极为精细的区分, 让我们可以更好地掌控全局.

键表

  • <k0>-<k9>: 小键盘数字 0 到 9
  • <S-x>: 大写 S 配合 x, 意味着 shift+x 组合键
  • <C-x>: 大写 C 配合 x, 意味着 ctrl+x 组合键
  • <A-x>: 大写 A 配合 x, 意味着 alt+x 组合键
  • <ESC>: ESC 键
  • <BS>: backspace 退格键
  • <CR>: ENTER 回车键
  • <Space>: 空格键
  • <Shift>: shift 键
  • <Ctrl>: ctrl 键
  • <Alt>: alt 键
  • <F1>-<F12>: F1 到 F12 功能键

前缀

因为 vim 有多种模式, 因此我们可以针对不同的模式设置不同的快捷键映射

  • map: 用于正常模式, 可是模式, 选择模式, 操作待决模式

  • nmap: 用于正常模式

  • vmap: 用于可视模式与选择模式

  • xmap: 用于可视模式

  • smap: 用于选择模式

  • omap: 用于操作待决模式

  • map!: 用于插入模式与命令行模式

  • imap: 用于插入模式

  • cmap: 用于命令行模式

  • nore: 不递归, 否则在下面的按键映射下按下 i 就等于按下 k, 就等于按下 j, 最后结果乱套.

    1
    2
    3
    nnoremap  i   k
    nnoremap k j
    nnoremap j h
  • <Leader>: 意思就是在各种快捷键的最前面加上<leader> , 避免了二义性. 如下所示, 在普通模式按下##w 时, 就完成了文件的保存工作(如果不进行自定义设置的话, 默认的 leader 键为反斜杠 \)

    1
    2
    let mapleader="##"
    nmap `<leader>` w :w<CR>

实际修改举例

1
2
3
4
5
6
inoremap ' ''<esc>i                   " 单引号补全
" 在普通模式, 快速按下 fw, 就相当于输入了: w<CR>, fw 可以理解成 file\_write.
" 文件保存与退出
nmap fw :w `<CR>`
nmap fq :q `<CR>`
nmap fwq :wq `<CR>`

vim 的配置路径

当然, 通常我们可以将所有的配置都放在 ~/.vimrc 中, 但是随着时间的推移, 我们的 ~/.vimrc 文件会越来越大, 功能也越来越混乱, 很难一下就在其中找到需要的配置. 为此, vim 为我们预设了多个工作路径, 每个工作路径都不不同的加载时机.

  • ~/.vim/colors/: 加载我们的 colorscheme, 使用 :color mycolors 将会调用 ~/.vim/colors/mycolors 文件
  • ~/.vim/plugin/: plugin 目录, 每次启动 vim 将会将在其中的全部内容
  • ~/.vim/ftdetect/: 每次启动 vim 将会加载其中全部内容, 用于判断打开的文件是什么类型然后 set filetype ***
  • ~/.vim/ftplugin/: 当 vim 查找到一个文件的类型后, 为其 set filetype, 然后根据具体的类型在本目录下寻找对应的加载文件, 比如一个 test.md 文件, vim 在确定其是 markdown 类型后, 使用 setf markdown 设置其类型, 然后在本目录下寻找 markdown.vim 进行加载(有的话就加载, 没有就不加载)
  • ~/.vim/indent/: 与 ~/.vim/ftplugin 类似, 也是在确定了文件类型后在本目录下查找对应的文件进行加载, 不过只针对于缩进
  • ~/.vim/compliler/: 与 ~/.vim/ftplugin 类似, 也是在确定了文件类型后加载对应文件然后确定执行时使用的命令
  • ~/.vim/after/: 每次启动 vim 都会加载其中的文件, 其中可以含 pluginftplugin 文件夹, 加载时机位于 ~/.vim/plugin/~/.vim/ftplugin 之后
  • ~/.vim/autoload/: 按需加载, 也是延时加载, 在第一次呼叫相关插件命令后进行加载
  • ~/.vim/doc/: vim 的相关文档说明, 插件加载完成后进行加载

通过 :scriptnames 我们可以看到当前 buffer 的所有加载的 script

最后

本文作者 Hanley Lee, 首发于 闪耀旅途, 如果对本文比较认可, 欢迎 Follow