神级编辑器 Vim 使用-插件篇

在这篇中, 会列举各种实用的插件, 包括他们的安装, 配置及使用方法

注意: 不是本部分的所有插件都是你需要装的, 如果盲目安装插件只会导致你 vim 功能混乱, 速度底下, 所以适时整理真正需要的插件, 禁用或清除掉不常用的插件才是正确使用方法.

himg

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

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

vim-plug

vim-plug 是 vim 下的插件管理器, 可以帮我们统一管理后续的所有插件, 后续的安装插件全部由此工具完成

类似的插件管理工具还有 Vundle, 相较而言 vim-plug 支持异步且效率非常高, 具体选择交由读者自己

安装

终端中输入如下命令

1
2
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

基础命令

  • PlugInstall : 安装插件
  • PlugUpdate : 更新所有插件
  • PlugUpgrade : 更新插件本身
  • PlugClean : 删除插件, 把安装插件对应行删除, 然后执行这个命令即可

安装插件流程

安装完 vim-plug 之后, 我们就可以使用其为我们服务安装插件了, 我们只需要在 call plug#begin(~/.vim/plugged)call plug#end() 中指明我们需要的第三方插件即可, 如下:

1
2
3
4
5
6
7
8
call plug#begin('~/.vim/plugged')

Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } " 模糊搜索
Plug 'junegunn/fzf.vim' " 模糊搜索
Plug 'embear/vim-localvimrc'
Plug 'ycm-core/YouCompleteMe' " 补全插件

call plug#end()

后续的所有插件除非特别说明, 否则都按照 Plug 'PlugName' 的方式进行安装

AutoFormat

自动格式化管理插件, 可根据不同文件类型使用不同的格式化工具

安装

1
Plug 'Chiel92/vim-autoformat'

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"*****************   vim-autoformat   **********************
let g:autoformat_verbosemode=0 "详细模式
let g:autoformat_autoindent = 0
let g:autoformat_retab = 1
let g:autoformat_remove_trailing_spaces = 1
let g:formatdef_hl_js='"js-beautify"'
let g:formatdef_hl_c='"clang-format -style=\"{BasedOnStyle: LLVM, UseTab: Never, IndentWidth: 4, PointerAlignment: Right, ColumnLimit: 150, SpacesBeforeTrailingComments: 1}\""' "指定格式化的方式, 使用配置参数
let g:formatters_c = ['hl_c']
let g:formatters_cpp = ['hl_c']
let g:formatters_json = ['hl_js']
let g:formatters_js = ['hl_js']
let g:formatdef_sqlformat = '"sqlformat --keywords upper -"'
let g:formatters_sql = ['sqlformat']

"保存时自动格式化指定文件类型代码
"au BufWrite * :Autoformat
"autocmd BufWrite *.sql,*.c,*.py,*.java,*.js :Autoformat "设置发生保存事件时执行格式化

ALE

AutoFormat 插件类似, 本插件也相当于一个错误统计处理平台, 通过为不同语言配置不同 linter 来达到错误统计的效果

如果你安装了 lightline 或者其他的类似工具, 那么也可以集成到你的底部工具栏中

himg

安装

1
Plug 'dense-analysis/ale'

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
"*********************   dense-analysis/ale   ************************
let b:ale_fixers = ['prettier', 'eslint']
let g:ale_fixers = {
\ '*': ['remove_trailing_lines','trim_whitespace' ],
\ 'python': ['autopep8']
\}
let g:ale_set_highlights = 0
"let g:ale_fix_on_save = 1 "auto Sava
let g:ale_echo_msg_format = '[#%linter%#] %s [%severity%]'
let g:ale_sign_column_always = 1 "始终开启标志列
let g:ale_sign_error = '•'
let g:ale_sign_warning = '•'
let g:ale_echo_msg_error_str = ''
let g:ale_echo_msg_warning_str = ''
let g:ale_completion_delay = 500
let g:ale_echo_delay = 20
let g:ale_lint_delay = 500
let g:ale_linters_explicit = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_lint_on_insert_leave = 1
let g:airline#extensions#ale#enabled = 1
let g:ale_c_gcc_options = '-Wall -O2 -std=c99'
let g:ale_cpp_gcc_options = '-Wall -O2 -std=c++14'
let g:ale_c_cppcheck_options = ''
let g:ale_cpp_cppcheck_options = ''
let g:ale_linters = {
\ 'c': ['clangd'],
\ 'swift': ['swiftlint'],
\ 'markdown': ['markdownlint'],
\ 'sh': ['shellcheck'],
\ 'json': ['jsonlint'],
\ 'zsh': ['shellcheck']
\}
let g:ale_list_window_size = 5
let g:ale_statusline_format = ['E•%d', 'W•%d', 'OK']
1
2
3
" 快速跳转至错误的快捷键
nnoremap <Leader>en <Plug>(ale_next)
nnoremap <Leader>ep <Plug>(ale_previous)

netrw

很多人使用 vim 编辑文件, 完成后退出 vim 进行目录切换, 殊不知 vim 其实自带路径管理功能的, 从 vim 7 以后我们可以使用vim 自带的 netrw 进入路径管理窗口

himg

netrw 是 vim 自带的插件, 不需要额外安装, 其提供的功能非常强大, 相比与 NERDTREE 这些第三方插件来说速度更快, 体量更轻, 设计更简洁

操作命令

  • :Ex : 全屏进入 netrw, 全称是 :Explorer
  • :Sex> : 水平分割进入 netrw
  • :Vex> : 垂直分割进入 netrw
  • <F1> : 在 netrw 界面弹出帮助信息
  • <CR> : 打开光标下文件/夹
  • - : 进入上一级目录
  • p : 预览文件(光标保持不动)
  • P : 打开文件, 会在上一个使用的窗口一侧的第一个窗口打开文件
  • <C-w>z: 关闭预览窗口
  • gn : 使光标下的目录作为目录树最顶部, 在 tree style 下与 <CR> 是不同的
  • d : 创建文件夹
  • D : 移除文件/夹
  • cd : change 工作目录到当前路径
  • I : 显示/隐藏顶部 banner
  • o : 以水平分割窗口方式打开光标下文件
  • v : 以垂直分割窗口方式打开光标下文件
  • % : 在当前目录下新建一个文件并编辑
  • r : 翻转排序方式
  • qb : 列出所有的目录以及历史路径
  • qf : 显示文件详细信息
  • R : 重命名文件/文件夹
  • s : 在 name, timefile size 之间切换排序
  • t : 新 tab 中打开文件
  • <c-h> : 编辑隐藏列表
  • <c-l> : 更新 netrw 列表内容
  • a : 隐藏/显示由 g : netrw_list_hide 所控制的文件
  • C : 设置编辑窗口
  • gb : 跳转到上次标记的书签
  • gd : 强制作为目录
  • gf : 强制作为文件
  • gh : 快速隐藏 . 开头的文件
  • i : 在 thin, long, wide, tree listings 状态之间切换
  • mb : 将当前目录存为书签
  • mc : Copy marked files to marked-file target directory
  • mm : Move marked files to marked-file target directory
  • md : 对标记的文件做 diff 操作
  • me : 将标记的文件放入参数列表中并进行编辑
  • mf : 标记一个文件
  • mF : 取消标记一个文件
  • mg : 对标记的文件使用 vimgrep 命令
  • mp : 打印标记的文件
  • mr : 使用 shell-style 标记文件
  • mt : 使当前目录成为标记文件目标
  • mT : 对标记文件应用 ctags
  • mu : 对所有标记文件取消标记
  • mz : 压缩/反压缩标记文件
  • O : Obtain a file specified by cursor
  • qF : Mark files using a quickfix list
  • S : 确认在 name 排序状态下的扩展名优先级
  • u : 跳转到上一次浏览的目录
  • x : 使用系统中与之关联的程序打开光标下文件
  • X : 执行光标下的文件

配置

1
2
3
4
5
6
7
8
9
10
11
let g:netrw_hide = 1 "设置默认隐藏
let g:netrw_liststyle = 3 " tree 模式显示风格
let g:netrw_banner = 0 " 显示帮助信息
let g:netrw_browse_split = 0 "控制 <CR> 直接在当前窗口打开光标下文件
let g:netrw_winsize = 30 " 占用宽度
let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+' " 需要隐藏的文件
let g:netrw_localrmdir = 'trash' "默认的删除工具使用 trash
let g:netrw_altv = 1 " 控制 v 分裂的窗口位于右边
let g:netrw_preview = 1 " 默认是水平分割, 此项设置使之垂直分割
let g:netrw_alto = 0 " 控制预览窗口位于左侧或右侧, 与 netrw_preview 共同作用
" let g:netrw_chgwin = 2 " 控制按下 <CR> 的新文件在位于屏幕右侧的 2 号窗口打开, Lex 默认会设为 2

NerdTree

不管出于任何原因不想使用 netrw, 我们都有很多第三方插件可以选择, NerdTree 就是其中的佼佼者

安装

  1. 先在 .vimrc 文件中添加 Plug 名称及设定:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Plug 'preservim/nerdtree'
    Plug 'Xuyuanp/nerdtree-git-plugin' "目录树 git 状态显示
    "F1 开启和关闭 NerdTree
    map <F1> :NERDTreeToggle<CR>
    let NERDTreeChDirMode=1

    let NERDTreeShowBookmarks=1 "显示书签
    let NERDTreeIgnore=['\~$', '\.pyc$', '\.swp$'] "设置忽略文件类型
    let NERDTreeWinSize=25 "窗口大小
  2. 运行 vim , 输入命令 :PlugInstall

操作命令

  1. 文件操作

    • e : 进入文件夹内部浏览, 会在右侧开启小窗口进入文件夹列表
    • o : 在预览窗口中打开文件, 左侧 NerdTree 仍然被保留(事实上除非打开新 tab 或手动退出, 否在会一直存在)
    • O : 递归地打开其内所有文件夹
    • go : 在预览窗口中打开文件, 光标将仍然保留在小窗口中, 非常好用, 用于预览多个文件特别有用.
    • i : 以分割视图打开文件
    • gi : 以分割视图打开, 但是光标仍然保留在小窗口
    • s : 以分割视图打开文件
    • gs : 以分割视图打开文件, 但是光标仍然保留在小窗口
    • t : 在新标签页打开选择的文件, 全屏
    • T : 在新标签页静默打开选择的文件, 全屏, 因为是静默, 所以不会跳转到新窗口
    • C : 将当前所选文件夹改为根目录, 即进入到所选择的文件夹, 与 o 不同, o 是在当前视图下将文件夹展开, C 则是直接进入到文件夹.
    • cd : 将当前文件夹改为 cwd(当前工作目录)
    • CD : 将文件夹目录跳转到 CWD(当前工作目录)中
    • m : 对所选择的文件或文件夹弹出编辑菜单. 包括修改文件名, 复制, 移动, 删除等操作
    • B : 隐藏 / 显示书签, 如果显示书签, 还会将光标自动跳转至书签
    • I : 显示系统隐藏文件
  2. 关闭移动系列

    • Ctrl+W l : 光标向右分屏移动
    • Ctrl+W q : 关闭当前分屏, 如果是最后一个, 则出 vim
    • Ctrl+W + o : 关闭其他窗口只留下当前窗口
    • q : 直接退出 NerdTree
    • Ctrl+W L : 分屏向右移动
    • Ctrl+W + + : 分屏增加或减少高度
    • Ctrl+W + < : 分屏增加或减少宽度
    • gt : 跳转到下一个 tab
    • gT : 跳转到上一个 tab
    • D : 删除书签
    • F : 隐藏文件, 只保留文件夹在视图中
    • ⌃ j : 当同一个 NerdTree 有多个目录级别时, 只在同一级别下向下移动
    • ⌃ k : 当同一个 NerdTree 有多个目录级别时, 只在同一级别下向上移动
    • J : 移动到同一级别的最下方
    • K : 移动到同一级别的最上方
  3. 其他

    • A : 全屏进入 NerdTree 窗口
    • r : 刷新当前文件夹的缓存, 使界面刷新
    • R : 刷新整个文件夹树的缓存, 使整个界面更新
    • ? : 快速显示帮助, 非常有用, 忘记功能时使用!

每次 NERDTree从左侧显示出来的时候其所在目录即工作目录, 可以通过cd命令进行设置, 或者在.vimrc中设置set autochair 进行自动切换, 这个概念对于文件批量操作很重要, 因为文件批量操作时添加待操作文件是依靠当前工作目录来进行筛选的.

unimpaired

一个映射了大量实用命令的插件, 主要前缀键是 [],

安装

1
Plug 'tpope/vim-unimpaired'

使用

  • [b :bprevious
  • ]b :bnext
  • [B :bfirst
  • ]B :blast
  • [Space :当前行上增加空行
  • ]Space :当前行下增加空行
  • [e :当前行上移
  • ]e :当前行下移
  • [f :previous file in current directory
  • ]f :next file in current directory
  • <p :复制到当前行下, 减少缩进
  • <P :复制到当前行上, 减少缩进
  • =P :复制到当前上, 自动缩进
  • >p :复制到当前行下, 增加缩进
  • >P :复制到当前行上, 增加缩进
  • [p :复制到当前行上
  • ]p :复制到当前行下
  • [q :cprevious, quickfix previous
  • ]q :cnext
  • [Q :cfirst
  • ]Q :clast
  • [a :previous
  • ]a :next
  • [A :first
  • ]A :last
  • [l :lprevious
  • ]l :lnext
  • [L :lfirst
  • ]L :llast
  • [<C-L> :lpfile
  • ]<C-L> :lnfile
  • [<C-Q> :cpfile
  • ]<C-Q> :cnfile
  • [<C-T> :ptprevious
  • ]<C-T> :ptnext
  • [n :previous scm conflict
  • ]n :next scm conflict
  • [t :tprevious, tag previous
  • ]t :tnext
  • [T :tfirst
  • ]T :tlast

xkbswitch

vim 下的输入法自动切换工具, 在进入命令模式时自动切换至英文输入法, 回到插入模式时返回到上一次选择的输入法(在需要中英文切换的环境中非常有用)

安装

  1. 下载基础工具xkbswitch-macosx(每个系统有不同的实现工具, 这里以 macOS 为例)

    1
    2
    3
    4
    5
    git clone https://github.com/myshov/xkbswitch-macosx
    # 把 git 下来的 xkbswitch 弄到 /usr/local/bin 下, 其实环境变量能搜到就行
    cp xkbswitch-macosx/bin/xkbswitch /usr/local/bin
    git clone https://github.com/myshov/libxkbswitch-macosx
    cp libxkbswitch-macosx/bin/libxkbswitch.dylib /usr/local/lib/
  2. 在 vim 中安装插件
    vimrc 中加入下面的内容:

    1
    2
    3
    4
    5
    6
    Plug 'lyokha/vim-xkbswitch', {'as': 'xkbswitch'}

    "vim-xkbswitch
    let g:XkbSwitchEnabled = 1
    let g:XkbSwitchIMappings = ['cn']
    let g:XkbSwitchIMappingsTr = {'cn': {'<': '', '>': ''}}

    最后 PlugInstall 即可.

  3. 先在 .vimrc 文件中添加 Plug 名称及设定:

    1
    2
    Plug 'lyokha/vim-xkbswitch', {'as': 'xkbswitch'}
    let g:XkbSwitchEnabled = 1
  4. 运行 vim, 输入命令 :PlugInstall

使用方式

normal 模式下手动切换至英文输入法模式, 然后进入 insert 模式后手动切换到中文输入法模式, 此时插件已经记忆了输入法的状态了, 在 ESC 回到 normal 模式后会自动切换到英文输入法模式, 再次进入 insert 模式时会自动切换到中文输入法模式

tabular

一款对齐插件, 快速按照给定的分隔符号完成指定范围内的对齐操作

安装

1
Plug 'godlygeek/tabular'

操作

  • :Tabularize /,/ : 将整个缓冲区的所有行按照 , 符号进行对齐

  • :'<,'>Tabularize /,/ : 对高亮选中范围内的行进行对齐

  • :Tabularize /,/l1/c1/r0 : 按照 , 进行对齐, 并且为每个分割的文本区域内的文本指定对齐方式, l, c, r 分别为左中右对齐, 1 代表空距离分隔符一个空格

    1
    2
    3
    4
    5
    6
    7
    8
    9
    abc,def,ghi
    a,b
    a,b,c

    :Tabularize /,/r1c1l0

    abc , def, ghi
    a , b
    a , b , c

Markdown-preview

一款在浏览器中预览 markdown 文件的插件

himg

安装

1
Plug 'iamcco/markdown-preview.nvim', {'do': 'cd app & yarn install'}
  1. 运行 vim, 输入命令 :PlugInstall

配置

1
2
3
4
5
6
7
8
map <F3> :MarkdownPreview<CR> "设置 F3 开启 Markdown 文件预览
let g:mkdp_auto_start = 0 "打开文件后自动弹出, 0 为否
let g:mkdp_auto_close = 1 "关闭文件后自动关闭预览窗口, 1 为是
let g:mkdp_refresh_slow = 1 "慢速预览, 修改后退出 insert 模式后方会刷新视图, 1 为是
let g:mkdp_open_to_the_world = 0 "开启公网链接, 0 为否
let g:mkdp_browser = '' "指定浏览器, 默认会跟随系统浏览器
let g:mkdp_port = '' " 指定端口, 默认随机端口
let g:mkdp_page_title = '「${name}」' "指定浏览器窗口标题, 默认为 Markdown 文件名

操作命令

  • :MarkdownPreview : 开启预览
  • :MarkdownPreviewStop : 停止预览
  • :MarkdownPreviewTroggle : 开关预览

markdown2ctags

在窗口右侧显示 markdown 目录结构的一个插件, 此插件基于 ctags 和 tagbar(Tagbar 是一个著名的文档目录显示插件, 但是不支持 markdown, 此插件在 Tagbar 的基础上添加了对 markdown 的支持). 因此此插件必须同时安装以上两种插件方可正常工作

安装

  1. 通过 brew 安装 ctgs

    1
    brew install ctags
  2. .vimrc 文件中添加 Plug 名称

    1
    2
    Plug 'jszakmeister/markdown2ctags'
    Plug 'majutsushi/tagbar'

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"*****************   Tagbar   *************************************
"F4 开启和关闭
map <F4> :TagbarToggle<CR>
let g:tagbar_type_markdown = {
\ 'ctagstype': 'markdown',
\ 'ctagsbin' : '~/.vim/plugged/markdown2ctags/markdown2ctags.py',
\ 'ctagsargs' : '-f - --sort=yes ',
\ 'kinds' : [
\ 's:sections',
\ 'i:images'
\ ],
\ 'sro' : '|',
\ 'kind2scope' : {
\ 's' : 'section',
\ },
\ 'sort': 0,
\ }

使用

只要在 vim 界面中使用 :TagbarToggle 即可调出 Tagbar 界面, 即可显示 markdown 的目录结构.

markdownlint

一款 markdown 语法检查工具, 可以根据预设的规则进行 markdown 语法错误警告或提示, 可根据需要进行规则自定义

安装

1
brew install markdownlint-cli

使用

配合 ALE 插件一起使用

1
2
3
4
5
6
7
let g:ale_linters = {
\ 'c': ['clangd'],
\ 'swift': ['swiftlint'],
\ 'markdown': ['markdownlint'],
\ 'sh': ['shellcheck'],
\ 'zsh': ['shellcheck']
\}

配置规则

在项目根目录下建立 .markdownlint.json 配置文件, 在其中对默认的规则进行配置, ale markdownlint 工具在被调用的时候会自动去查找该名称配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"default": true,
"MD013": false,
"MD014": false,
"MD024": false,
"MD029": false,
"MD033": false,
"MD040": false,
"no-hard-tabs": false,
"no-inline-html": {
"allowed_elements": [
"a"
]
}
}

fzf

fuzzy find, 快速模糊搜索查找工具

fzf.vim 与 终端工具 fzf 配合使用, 在 vim 中的 :FZFFiles 命令都会调用 export FZF_DEFAULT_COMMAND='...' 这个参数, 需要在 .zshrc 中配置好

安装

  1. 在终端中安装 fzf 工具

    1
    brew install fzf
  2. ~/.vimrc 中安装 vim 的fzf 插件

1
2
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'

配置使用

首先在 .zshrc 中配置终端中的fzf 选项, 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
export FZF_DEFAULT_COMMAND="fd --hidden --follow -I --exclude={Pods,.git,.idea,.sass-cache,node_modules,build} --type f"
export FZF_DEFAULT_OPTS="
--color=dark
--color=fg:#707a8c,bg:-1,hl:#3e9831,fg+:#cbccc6,bg+:#434c5e,hl+:#5fff87
--color=info:#af87ff,prompt:#5fff87,pointer:#ff87d7,marker:#ff87d7,spinner:#ff87d7
--height 60%
--layout reverse
--preview-window 'hidden:right:60%'
--preview '(highlight -O ansi -l {} 2> /dev/null || cat {} || tree -N -C {}) 2> /dev/null | head -500'
--bind ',:toggle-preview'
--border
--cycle
"
export FZF_CTRL_T_COMMAND=$FZF_DEFAULT_COMMAND
export FZF_CTRL_T_OPTS=$FZF_DEFAULT_OPTS
export FZF_CTRL_R_OPTS="
--layout=reverse
--sort
--exact
--preview 'echo {}'
--preview-window down:3:hidden:wrap
--bind ',:toggle-preview'
--cycle
"

export FZF_ALT_C_OPTS="--preview 'tree -N -C {} | head -500'"
export FZF_TMUX_OPTS="-d 60%"
export FZF_COMPLETION_TRIGGER='**'

(fzf 可扩展性很高, 如果进行适当配置, 它可以在你进行路径跳转, 历史命令搜索, 文件搜索等方面给你极大的帮助!)

然后在 vim 中配置 fzf 插件的相关设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
nnoremap <Leader>fh :History<CR>
nnoremap <Leader>fl :Lines<CR>
nnoremap <Leader>fb :Buffers<CR>
nnoremap <Leader>ff :Files<CR>
nnoremap <Leader>fg :GFiles<CR>
nnoremap <Leader>f? :GFiles?<CR>
nnoremap <Leader>ft :Tags<CR>
nnoremap <Leader>fa :Ag<CR>
nnoremap <Leader>fc :Commits<CR>

let g:fzf_preview_window = 'right:60%' " Always enable preview window on the right with 60% width
let g:fzf_buffers_jump = 1 " [Buffers] Jump to the existing window if possible
let g:fzf_commits_log_options = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"' " [[B]Commits] Customize the options used by 'git log'
let g:fzf_tags_command = 'ctags -R' " [Tags] Command to generate tags file
let g:fzf_commands_expect = 'alt-enter,ctrl-x' " [Commands] --expect expression for directly executing the command
let g:fzf_action = {
\ 'ctrl-t': 'tab split',
\ 'ctrl-x': 'split',
\ 'ctrl-v': 'vsplit'
\}
let g:fzf_layout = { 'down': '~60%' }

命令

:Files [path]: 列出 path 路径下的所有文件 (功能等价于 :FZF 命令)
:Buffers: 文件缓冲区切换
:Colors: 选择 Vim 配色方案
:Tags [QUERY]: 当前项目中的Tag (等价于: ctags -R)
:BTags: [QUERY] 当前活动缓冲区的标记
:Marks: 所有Vim标记
:Windows: 窗口
:Lines [QUERY]: 在所有加载的文件缓冲区里包含目标词的所有行
:BLines [QUERY]: 在当前文件缓冲区里包含目标词的行
:Locate PATTERN: locate command output
:History: v:oldfiles and open buffers
:History:: 命令行命令历史
:History/: 搜索历史
:Commands: Vim 命令列表
:Maps: 普通模式下的按键映射
:Snippets: Snippets ([UltiSnips][us])
:Commits: Git commits (requires [fugitive.vim][f])
:BCommits: 查看与当前缓冲区有关的 commit
:GFiles [OPTS]: Git files (git ls-files)
:GFiles?: Git files (git status)
:Ag [PATTERN]: ag search result (ALT-A to select all, ALT-D to deselect all)
:Rg [PATTERN]: rg search result (ALT-A to select all, ALT-D to deselect all)
:Filetypes: File types

YouCompleteMe

命令补齐插件, 支持 c, c++, java, python, PHP 等多语言

安装

  1. 先在 .vimrc 文件中添加 Plug 名称

    1
    Plug 'ycm-core/YouCompleteMe'`
  2. 运行 vim , 输入命令 :PlugInstall

经历过上述 2 个步骤后, YouCompleteMe 插件还没法使用, 此时打开 Vim 时会看到如下的报错:

1
The ycmd server SHUT DOWN (restart with ‘:YcmRestartServer’). YCM core library not detected; you need to compile YCM before using it. Follow the instructions in the documentation.

这是因为, YouCompleteMe 需要手工编译出库文件 ycm_core.so (以及依赖的 libclang.so) 才可使用.
假设使用 vim-plug 下载的 YouCompleteMe 源码保存在目录 ~/.vim/plugged/YouCompleteMe, 在该目录下执行

1
2
3
4
5
# 编译全部语言
./install.py --all # 或者 /usr/bin/python install.py

# 或仅编译 C 族语言
./install.py --clang-completer

ludovicchabant/vim-gutentags

管理 tag 文件, tag 文件关乎着项目的引用与跳转, 因此是一个比较大的话题, 详细可以参考韦大的文章

安装

  1. 安装 universal-ctags 命令行程序

    1
    2
    brew tap universal-ctags/universal-ctags
    brew install --HEAD universal-ctags
  2. 安装 vim 插件 vim-gutentags

    1
    Plug 'ludovicchabant/vim-gutentags'

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
"*****************   gutentags   *************************************
let g:gutentags_project_root = ['.root', '.svn', '.git', '.hg', '.project'] " gutentags 搜索工程目录的标志, 当前文件路径向上递归直到碰到这些文件/目录名
let g:gutentags_ctags_tagfile = '.tags' " 所生成的数据文件的名称
let g:gutentags_modules = [] " 同时开启 ctags 和 gtags 支持:
if executable('ctags')
let g:gutentags_modules += ['ctags']
endif
if executable('gtags-cscope') && executable('gtags')
let g:gutentags_modules += ['gtags_cscope']
endif

let g:gutentags_cache_dir = expand('~/.cache/tags') " 将自动生成的 ctags/gtags 文件全部放入 ~/.cache/tags 目录中
" 配置 ctags 的参数, 老的 Exuberant-ctags 不能有 --extra=+q, 注意
let g:gutentags_ctags_extra_args = ['--fields=+niazS', '--extra=+q']
let g:gutentags_ctags_extra_args += ['--c++-kinds=+px']
let g:gutentags_ctags_extra_args += ['--c-kinds=+px']
let g:gutentags_ctags_extra_args += ['--output-format=e-ctags'] " 如果使用 universal ctags 需要增加下面一行, 老的 Exuberant-ctags 不能加下一行
let g:gutentags_auto_add_gtags_cscope = 0 " 禁用 gutentags 自动加载 gtags 数据库的行为

为系统头文件生成 tags

默认情况下, 我们不能跳转到 printf 这类标准库中的方法中, 如果需要的话, 我们可以为系统标准库生成 tags, 然后将在 .vimrc 文件中为其进行指定, 这样即可跳转到系统的标准库头文件定义中了.

首先将系统中的头文件目录找出来, 然后使用 ctags 对目录中所有文件进行生成

1
ctags --fields=+niazS --extras=+q --c++-kinds=+px --c-kinds=+px --output-format=e-ctags -R -f ~/.vim/systags /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include  ~/header

然后在 vim 中指定 tags 文件的路径即可

1
set tags+=~/.vim/systags

vim-surround

一款超级强大的快速添加/删除/改变包围符号的神器

安装

1
Plug 'tpope/vim-surround'

命令

  • ds : 删除包围符号
  • cs : 改变包围符号
  • ysw : 当前至下一个词尾添加一个包围符号
  • ysW : 当前至至下一个空格添加一个包围符号
  • ySw : 当前至下一个词尾添加一个包围符号并将焦点移至下一行
  • ySW : 当前至下一个空格添加一个包围符号并将焦点移至下一行
  • yss) : 整行添加包围符号()
  • ysiw): 为当前光标下单词添加包围符号()
  • S": Visual 模式下对选中区域添加包围符号 "
  • gS": Visual 模式下对选中区域进行换行并添加包围符号
  • ⌃-s : Insert 模式下插入包围符号
  • ⌃-s, ⌃-s : Insert 模式下在插入包围符号并将焦点移至下一行
  • dst : 删除 html/xml 的标签内部的所有字符
  • cst : 删除 html/xml 的标签内部的所有字符并进入插入模式
  • ysa<': 在 <> 包裹的范围上加符号 '

范例

1
2
3
4
5
6
7
8
9
| Old text              | Command    | New text                    |
| :-------------------: | :-----: | :-----------------------: |
| "Hello *world!" | ds" | Hello world! |
| [123+4*56]/2 | cs]) | (123+456)/2 |
| "Look ma, I'm *HTML!" | `cs"<a>` | `<a>Look ma, I'm HTML!</a>` |
| if *x>3 { | ysW( | if ( x>3 ) { |
| my $str = *whee!; | vlllls' | my $str = 'whee!'; |
| <div>Yo!*</div> | dst | Yo! |
| <div>Yo!*</div> | `cst<p>` | `<p>Yo!</p>` |

nerdcommenter

快速注释插件

安装

1
Plug 'preservim/nerdcommenter'

命令

  • <leader>cc: NERDCommenterComment, 注释当前行或所选择行(文本)
  • <leader>cu: NERDCommenterUncomment, 取消当前所处位置的注释状态 Uncomments the selected line(s).
  • <leader>ci: NERDCommenterInvert, 反转所选择行的注释状态(逐个地反转) 仅支持行
  • <leader>c<space>: NERDCommenterToggle (反)激活所选择行的注释状态, 依据最顶部行的注释状态进行判断, 执行命令后, 所选择行的注释状态均为最顶部行注释状态的相反状态. 仅支持行
  • <leader>cn: NERDCommenterNested, 与 cc 相同, 不过嵌套地进行注释
  • <leader>cs: NERDCommenterSexy, 将当前选择文本以块的方式进行注释(即在选择文本的上方与下方加上单行注释) 仅支持行
  • <leader>cy: NERDCommenterYank, 与 cc 完全相同, 不过会先进行复制操作
  • <leader>c$: NERDCommenterToEOL Comments the current line from the cursor to the end of line.
  • <leader>cA: NERDCommenterAppend, Adds comment delimiters to the end of line and goes into insert mode between them.
  • <leader>ca: NERDCommenterAltDelims Switches to the alternative set of delimiters.
  • <leader>cm: NERDCommenterMinimal, Comments the given lines using only one set of multipart delimiters.

tpope/vim-commentary

快速注释插件, 相比于 nerdcommenter 更加简洁实用

安装

1
Plug 'tpope/vim-commentary'

命令

  • gcc: 注释或反注释
  • gcap: 注释一段
  • gc: visual 模式下直接注释所有已选择的行

terryma/vim-multiple-cursors

实现真正的多光标的一个插件, vim 的 visual block 模式并不是多光标, 如果想将 visual block 模式下被选中的多行的当前单词推进到每个单词的末尾, 那么就需要使用到多光标的概念.

我理解的此多光标插件的使用分为两种状态

  • 从 normal 模式直接使用 <C-n> 进入多光标状态并选中当前光标下的单词, 然后再次使用 <C-n> 选择下一个, <C-x> 跳过当前符合的单词, 最后进行插入修改等操作
  • 从 visual 或 visual block 模式下使用 <C-n> 进入直接添加光标到当前所有行的选中单词处, 然后移动光标, 在合适位置进行进行插入修改等操作, 最后 esc 两次退出

安装

1
Plug 'terryma/vim-multiple-cursors'

命令

  • <C-n>: 进入多光标状态/或选择下一个符合当前选择的单词
  • <C-x>: 跳过当前候选
  • <C-p>: 移除当前单词处的光标及选择状态跳转到上一个光标处
1
2
3
4
5
6
7
8
9
10
11
let g:multi_cursor_use_default_mapping=0

" Default mapping
let g:multi_cursor_start_word_key = '<C-n>'
let g:multi_cursor_select_all_word_key = '<A-n>'
let g:multi_cursor_start_key = 'g<C-n>'
let g:multi_cursor_select_all_key = 'g<A-n>'
let g:multi_cursor_next_key = '<C-n>'
let g:multi_cursor_prev_key = '<C-p>'
let g:multi_cursor_skip_key = '<C-x>'
let g:multi_cursor_quit_key = '<Esc>'

seoul256.vim

一套配色 vim 配色方案, 韩国人出品. 与之匹配的还有一个 iTerm 配色方案, 两者结合的比较好看

安装

在 .vimrc 文件中添加 Plug 名称及设定:

1
2
3
4
5
6
7
Plug 'junegunn/seoul256.vim'
colo seoul256
let g:seoul256_background = 236 "设置背景颜色深度
set background=dark "设置背景颜色为黑色, 必须设置, 否则上面的数值设置没有意义
" seoul256 (dark):
" Range: 233 (darkest) ~ 239 (lightest)
" Default: 237

Goyo.vim

一款专注写作的 vim 插件, 开启后四周空白, 更利于专注. 不适用于写代码和看代码

安装

  1. 在 .vimrc 文件中添加 Plug 名称及设定:

    1
    Plug 'junegunn/goyo.vim'

命令

  • :Goyo: 进入专注模式
  • :Goyo!: 退出专注模式, 或使用 :q
  • :Goyo 90%: 调整高度为窗口的 90%
  • :Goyo x30%: 调整宽度为窗口的 30%
  • :Goyo 70%-10x90%+10%: 调整区域宽为窗口 70%, 左边距向左移 10 单位, 高度为窗口 90%, 向下移动窗口的 10%

Limelight

Goyo, seoul256 为同一开发者, 联合使用效果最佳. 不适用于写代码和看代码.

官网

安装

.vimrc 文件中添加 Plug 名称及设定:

1
2
3
4
5
6
Plug 'junegunn/limelight.vim'
let g:limelight_default_coefficient = 0.5 // 设置隐藏区域的黑暗度, 值越大越暗
let g:limelight_paragraph_span = 2 // 设置暗光的跨度, 暗光所能照亮的范围
let g:limelight_priority = -1 // 暗光优先级, 防止搜索的高亮效果被覆盖
autocmd! User GoyoEnter Limelight // 进入 Goyo 专注插件时, 同时开启暗光效果
autocmd! User GoyoLeave Limelight! // 离开 Goyo 专注插件时, 同时退出暗光效果

命令

  • :Limelight // 进入Limelight 状态
  • :Limelight! // 退出 Limelight 状态
  • :Limelight0.3 //

XVim

如果你同时是一名 iOS 开发者, 那么 XVim 可以帮助你在 Xcode 中找回缺失的 Vim 操作, XVim 可以让 Xcode 像 vim 一样编辑.

由于 XVim 没有上架到 Mac App Store, 因此我们需要进入官网下载源码编译按照, 编译前需要对 Xcode 进行自签名, 否则我们自己编译出来的结果文件是不能安装到 Xcode 上的

官网

安装

  1. 对系统的代码证书重新生成

    XVimProject/XVim2

  2. 克隆源码仓库

    1
    git clone https://github.com/XVimProject/XVim2.git
  3. 确认 xcode 内容点

    1
    2
    xcode-select -p
    /Applications/Xcode.app/Contents/Developer

    如果有多个版本 Xcode, 此项会让你清楚你将安装 XVim 到哪一个版本上, 如果结果不是你想要的版本, 那么使用 xcode-select -s <path-of-xcode> 进行手动指定

  4. make

    1
    2
    cd XVim2
    make
  5. 按照需要可生成 .xvimrc文件 (.xvimrc 文件必须放在用户主目录, 即.vimrc 同级目录)

  6. 重启 Xcode

  7. 完成安装

使用

  • :run : xcode 代码运行
  • :make : 构建 xcode 代码
  • :xhelp : 光标位置快速帮助
  • :xccmd : 执行 xcode 菜单
  • ⌃ g : 打印当前行的位置

Vimum

Vimum 是一款 Chrome 插件, 使用 vim 的模式概念让我们可以脱离鼠标访问浏览网页

  • gg: 跳转到页面顶部
  • G: 跳转到页面底部
  • gi: 激活搜索框
  • j: 页面向下滚动
  • k: 页面向上滚动
  • u: 页面向上翻页
  • d: 页面向下翻页
  • r: 刷新当前页面
  • H: 页面回退到上一次历史
  • L: 页面从历史记录中返回来
  • x: 关闭页面
  • X: 恢复被关闭的页面(可多次重复)
  • f: 显示页面上各个点击点的链接, 可以在当前页打开
  • F: 显示页面上各个点击点的链接, 在新页面打开
  • gt: 向右侧浏览下一个 tab
  • gT: 向左侧浏览 tab
  • yf: 拷贝页面上显示的链接
  • yy: 拷贝当前网页的链接
  • yt: 复制当前 tab
  • v: 进入选择模式, 可选择文本, 第一次按下时会进入 creat mode, 选中起点后再次按下 v 将启用选择模式, 然后按下 y 来进行复制. 如果需要再次进入 creat mode, 可使用 c 按键. 如果在复制中要改变复制区域的起点, 可以使用 o 按键, 或者在使用 / 进行搜索确定焦点后进行 v 选择操作. 在选择模式中可使用 w, b, h, j, k, l, e, $ 来进行移动
  • V: 进入行选择模式, 可批量选择多行文本
  • o: 键入搜索内容, 可在当前页面显示历史记录或打开网页链接或搜索新内容
  • O: 兼容搜索内容, 在新页面给出与 o 键相同的结果
  • b: 搜索书签, 并在当前页面打开
  • B: 搜索书签, 并在新页面打开
  • T: 在已打开的 tab 中进行搜索
  • /: 搜索当前页面值, 使用 ⌘ F 进行也页面搜索, / 不能搜索中文
  • n: 选中下一个搜索结果
  • N: 选中上一个搜索结果

Vimari

如果你正在使用 Safari, 但是也想在浏览器中使用 vim 的操作, 那么 Vimari 就很适合你了, 因为 Vimum 不支持 Safari, 因此 Vimari 就诞生出来了, 虽然没有 Vimum 功能那么强大, 但是基本的浏览操作倒是都覆盖了

  • f : 触发跳转
  • F : 触发跳转(新 tab 中打开链接)
  • h/j/k/l : 移动
  • u : 向上翻页
  • d : 向下翻页
  • gg : 跳转到页面顶部
  • G : 跳转到页面底部
  • gi : 跳转到第一个输入处
  • H : 回到前一个历史页面
  • L : 回到后一个历史页面
  • r : 重载页面
  • w : 下一个 tab
  • q : 上一个 tab
  • x : 关闭当前 tab
  • t : 开启新 tab

其他插件

vim 丰富的插件生态是其一大特色, 本文只是起到抛砖引玉的功能, 更多实用的插件有待读者的发现. 以下列举了笔者常用的插件.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
"============= File Management =============
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } " 模糊搜索
Plug 'junegunn/fzf.vim' " 模糊搜索
Plug 'embear/vim-localvimrc' " 用于针对工程设置 vimrc

" ============= Edit ===========
Plug 'ycm-core/YouCompleteMe' " 补全插件
Plug 'SirVer/ultisnips' " 自定义某些片段
Plug 'ludovicchabant/vim-gutentags' " 根据 ctags 或 gtags 生成 tags 进行使用, 自动管理
Plug 'skywind3000/gutentags_plus' " 提供
Plug 'Shougo/echodoc.vim'
Plug 'lyokha/vim-xkbswitch', {'as': 'xkbswitch'} " 返回到 normal 模式时快速切换为英文输入法
Plug 'dense-analysis/ale' " 提示语法错误
Plug 'easymotion/vim-easymotion' " 空格任意跳转
Plug 'bronson/vim-visual-star-search'
Plug 'jiangmiao/auto-pairs' " 匹配括号
Plug 'dhruvasagar/vim-table-mode' " 自动表格, 使用`\tm` 就进入了表格模式, 会进行自动对齐
Plug 'godlygeek/tabular' " 文本对齐, 使用 :Tabularize /= 可以等号对齐多行
Plug 'terryma/vim-multiple-cursors' " 多行文本操作
Plug 'tpope/vim-commentary' " 快速注释, gcc
Plug 'tpope/vim-repeat' " 支持重复
Plug 'tpope/vim-surround' " 包围符号
Plug 'tpope/vim-unimpaired'

" ============= Appearance ============
Plug 'joshdick/onedark.vim'
Plug 'ap/vim-css-color' " 显示 css 颜色
Plug 'machakann/vim-highlightedyank' " 使 yank 的文档半透明高亮
Plug 'mhinz/vim-signify' " 显示当前行的 git 状态
Plug 'Yggdroot/indentLine' " 显示缩进线
Plug 'itchyny/lightline.vim' " 显示底部导航栏

"============== Function ==============
Plug 'majutsushi/tagbar' " 显示文档的层级
Plug 'qpkorr/vim-renamer' " 批量修改文件的神器, 使用 :Ren 进行编辑与保存, 完成后退出即可
Plug 'Chiel92/vim-autoformat' " 自动格式化文档
Plug 'skywind3000/asyncrun.vim' " 异步执行
Plug 'tpope/vim-fugitive' " git 插件
Plug 'jiazhoulvke/jianfan' " 简繁转换 Tcn, Scn
Plug 'simnalamburt/vim-mundo' " 显示修改历史

"============== Language ==============
Plug 'plasticboy/vim-markdown' " markdown 增强插件
Plug 'jszakmeister/markdown2ctags' " markdown 层级显示
Plug 'iamcco/markdown-preview.nvim', {'do': 'cd app & yarn install'} " Markdown 实时预览

实际上以上所列出的插件很多仅由百余行的文件构成, 所以如果一些插件不能满足需求的话完全可以按照自己的想法写出一个适合自己的插件. 想法最重要, 做一件事只要有了想法就成功了 80%.

最后

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