京山游侠

专注技术 拒绝扯淡
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束。如果某条评论中出现了两个$,MathJax 会将两个$之间的内容按照数学公式进行排版,从而导致评论区格式混乱。如果大家的评论中用到了$,但是又不是为了使用数学公式,就请使用\$转义一下,谢谢。

想从头阅读该系列吗?下面是传送门:

前言

本来我是想写完 Linux 桌面系统的美化和字体配置之后再写 Vim 的。但是等我写完玩转 Linux 系统的方法论一看,发现一个好用的文本编辑器在 Linux 系统中实在是太重要了,在玩转 Linux 系统的方法论中,我的很多例子都是靠 Vim 展示出来的。没有文本编辑器,怎么去读代码、改配置、写脚本呢?如果不能读代码、改配置、写脚本,该系列后面的内容怎么进行得下去呢?所以,我这一篇写一写 Vim 的配置。

先介绍一下 Vim。Vim 是 Linux 系统上的最著名的文本/代码编辑器,也是早年的 Vi 编辑器的加强版,被誉为文本/代码编辑器之中最为优秀经典的上古神器。 它之所以会获得如此美誉,我想主要有以下原因:1.它古老而神秘,学习曲线陡峭,难以驾驭,但是一旦学会则受益匪浅。如今被看作是高手、Geek 们专用的编辑器。所以尽管 Vim 已经是古董级的软件,但还是有无数新人迎着困难去学习使用。 2.轻便,无需多言,当仅仅只需要对某一文本文件(脚本代码、配置文件)进行简单的编辑的时候,所使用的工具当然是越轻便越好。Vim 同时也是阅读文本文件的利器。 3.经典巧妙的编辑方式及强大的功能。它全程使用键盘操作,用户必须记住一堆快捷键、按键组合以及各种命令才能开始使用,一旦使用熟练则编辑效率远超其余编辑器,而且具有各种插件、语法高亮、代码补全、配色方案等极其丰富的资源以及灵活的配置。

我主要在以下情况下使用 Vim: 1.用来修改服务器系统的配置文件。很多时候, Linux 作为服务器是不会开启图形界面的,当需要远程操作时,只能利用 SSH “命令字符式”的 Shell 界面对其进行操作,这种情况下,Vim 自然是首选。 2.用来阅读内核源代码和系统的脚本。理由同上。 3.用来写简单的程序,一般都是单文件的程序,或多文件但是只有少数几个文件的项目,例如学习一门编程语言的时候做练习题,喜欢看到文件夹内干干净净,不喜欢一大堆类似 .project 的文件。 4.装B,花花绿绿的纯文本字符界面,很酷。

不适合 Vim 使用的场景: 1.大的编程项目,大的项目还是最好使用 IDE,如果要远程连接没有图形界面的服务器写大项目,最好还是在服务器上建立代码仓库。理由:Vim 没有好的项目管理功能,Vim 的自动补全只建立在文本匹配上,没有程序语言的语义分析功能。 2.对内容的输入要求不高,但是经常需要设置显示格式,且每个动作之间本身就有很多的停顿的工作,用其他 GUI 编辑器( LibreOffice Writer、WPS)效率反而比 Vim 高。

有人说,Vim 是“成也插件、败也插件”。Vim 灵活的配置和丰富的插件极大地增强了它的功能,但是也极大地增加了我们管理 Vim 的难度。首先,在使用 Vim 之前,必须经过适当的配置,而 Vim 的配置又极其繁琐。 Vim 的插件丰富,在网上不乏使用各种插件将Vim 配置成强大 IDE 的文章,但是 Vim 的插件管理非常困难,因为每安装一个插件,都需要将该插件的文件分别放到 Vim 安装路径下的 plugin、autoload、syntax、doc 等目录下。好在是目前有不少能管理插件的插件,它们不仅解决了 Vim 插件在文件系统中分散的问题,同时能够自动搜索和下载插件。

Vim 的现状

从前面的介绍可知,Vim 神秘高效水又深,所以吸引了一大批信徒。在网络上关于 Vim 的自定义配置汗牛充栋。既有高手 Tim Pope 的极简配置 tpope/vim-sensible(这个配置一个插件都没有),也有 spf13/spf13-vimSpaceVim 这样大而全的配置。而对我来说,我喜欢简洁而优雅,一大堆 Plugin 堆砌起来的东西我固然不喜欢,但是一个插件都没有的极简配置那用起来也不太顺手。所以我必须得自己配。

自己配 Vim,必然涉及到 Plugin 的选型的问题。说到选型,那就有很多话要说了。首先是 Vim 自身版本的进步和功能的进步,目前 Vim 已经进入到 Vim 8 的时代,增加了不少新功能,主要有异步、内置的 Terminal,还有 language server protocol。而且 NeoVim 的开发也如火如荼。这些特性的引入,使得 Vim 插件的作者的理念发生了变化,他们逐渐瞧不上纯粹 VimScript 写的插件,毕竟纯 VimScript 写的插件功能比较有限,速度也不够快,所以,他们大量应用 Nodejs、Python、Lua、PHP 这些第三方的语言来和 Vim 配合工作;他们也对 Vim 不能进行编程语言的语义分析怨声载道,所以大量使用了第三方的语言服务,比如 clangd、Jedi、Roslyn 等;当然,还有异步,谁愿意在 Vim 执行一个动作的时候我们在屏幕前傻等呢。总体来说,目前的 Vim 插件有几个发展趋势:一是要充分利用异步的支持,二是往往使用某些后端提供更强大的功能支持,三是喜欢搞大而全的框架。下面我来逐一举例说明。

先来说利用 Vim 的异步特性的例子。第一个例子就是管理插件的插件,我以前一直都是用 Vundle,我觉得挺好用的。但是这几年又雨后春笋般的冒出了几种新的管理插件的插件,像 junegunn/vim-plugShougo/dein.vim,看一下它们的说明,无一例外都是说使用了并发技术,加快了插件的下载速度。

对于插件的下载和管理,因为使用的频率较低,大家可能感受不到使用异步和不使用异步究竟有多大的区别,毕竟也就是多等那几分钟的事。但是另外两个例子,影响就稍微大一点了。一个是 tagbar,说实话,这个插件还是挺好用的,但是它不是异步的,每次在保存文件的时候,它都会自动生成索引,如果碰到大文件,那就影响速度了,有时候使 Vim 卡顿 5、6 秒都是可能的,对于追求极致速度的 Vim 来说,这个体验就不太好了。所有,有大神建议不要使用 tagbar,而是使用 vim-gutentags 来自动生成索引,而显示函数列表,可以使用 LeaderF。

最后一个例子,就是 AsyncRun。在 Vim 8 以前,编译和运行程序要么就让 Vim 傻等着结束,不能做其它的事情,要么切换到一个新的终端下面去单独运行编译命令和执行命令,要么开个 tmux 左右切换。而 AsyncRun 插件就可以在 Vim 中异步执行我们的任务。而在 SpaceVim 中,甚至加入了类似与 Vs Code 中的 Task 功能。

至于利用其它变成语言和后端支持的例子,那就更加多了去了。先来说说 Vim 中的自动补全。其实 Vim 自身就支持补全功能,不过使用起来一点都不自动,需要使用 Ctrl+P 或者 Ctrl+X Ctrl+O 这样的快捷键才会调出补全功能。Vim 自身的补全功能支持 buffers 中的单词,也支持 dictionary 和 tags 中的条目。但是不管怎么说,都只是基于字面意义上的补全,不支持深层次的对编程语言的语义分析。自动补全中有大名鼎鼎的 Shougo/neocomplete.vim,还有 Shougo/deoplete.nvim。一个需要 Python 3 的支持,一个需要 Lua 的支持,而且,它们也都需要各种语言模块的支持。当然,YouCompleteMe 仍然经久不衰,并没有因为 Vim 8 的出现而消亡,而 YouCompleteMe 也是需要很多语言引擎的,比如 clangd、Jedi、Roslyn等等。

再以 SpaceVim 中的 markdown 模块为例说明,其中对于 markdown 的语法树支持,就是由 lvht/tagbar-markdown 插件提供的,而该插件,需要 PHP 的支持。再比如对于 markdown 进行格式化,就需要 remark 的支持,而安装 remark,需要先安装 nodejs,然后使用 npm 安装。而实时预览,使用的插件是 markdown-preview.nvim,该插件也是需要 nodejs 支持的。

再来一个例子,关于 Vim 的目录树插件,老牌的 NERDTree 不用说了吧,我用着挺舒服的。但现在流行的趋势是 vimfiler。还有前面提到的 Yggdroot/LeaderF,主要是为了取代经典的 ctrlp,而且其功能比 ctrlp 强大不少。这个倒是没有要求 Vim 8,不过还是要求 Python。值得一用。

最后,就是有大神推荐使用 ALE 取代 syntastic 来做语法检查。

鉴于以上提到的错综复杂的关系,以及我自身的强迫症,所以我有两套 Vim 配置。一套是简洁的、经典的,Vim 7 就能用的,纯 VimScript 的,不想整那后端这后端的,除了 YouCompleteMe。我还是使用 Vundle 管理插件,并选择了 8 个最常用的插件,其中一个还是 colorscheme。唯一的升级,可能算是把 Taglist 升级为 Tagbar 了吧。另外,我还是选择了 CtrlP,没有选择 LeaderF。我觉得功能够用了。至于 tpope/vim-surroundnerdcommenter 之类的,那就不要了吧,不要它们也多敲不了几下键盘,还可以省下学习成本。如果为了美观,这个 vim-airline/vim-airline 插件倒是不错,这个 Lokaltog/vim-powerline 也不错,但是以上两个插件需要特殊字体的支持,到这里 powerline/fonts 可以下载字体,还可以使用 Nerd Fonts。如果需要语法检查,vim-syntastic/syntastic
可以试一下。

必须得说明一下:怎么为 Vim 配插件还得看自己的需求。我主要是看文档和看代码,偶尔改改配置文件,有时还要在非 GUI 环境下改配置文件。就算写代码也只用 Vim 写非常简单的。所以我这个经典配置完全够用了,而且开箱即用,超级方便。至于另外一套复杂的,我也懒得自己配,我直接使用 SpaceVim 。以后有空,我再写写和 SpaceVim 有关的随笔。

安装和配置 Vim

我的配置非常简单,加上空行,也不超过 80 行,我只选择了 8 个插件,几乎所有的插件都是纯 VimScript 的,所有插件都是开箱即用,不需要额外配置,只有 YouCompleteMe,需要自己编译一下。依赖方面,除了 ctags,不需要任何后端的支持。ctags 软件用来分析程序源代码,生成 tags 文件,可不仅仅只支持 C/C++哟,它还支持一大票编程语言。使用man ctags可以查看 ctags 的用法,使用ctags --list-languages可以查看 ctags 支持哪些编程语言。Vim 自身就有很多地方需要用到 tags 文件。首先是 Vim 的跳转功能,快捷键是 Ctrl+],需要 tags 文件支持。其次,Vim 的自动补全功能,不仅支持 buffers 中的单词,也支持 dictionary 和 tags 中的条目。而在我选择的几个插件中,Tagbar 插件可以调用 ctags 对当前编辑的文件进行分析,生成符号表。

目录树插件,我还是选择老牌的 NERDTree。文件搜索插件,我还是选择 CtrlP。自动补全插件,我还是选择了 YouCompleteMe。使用 syntastic 进行语法检查。没有使用 powerline,而是选择了 vim-airline,并且选择了 Nerd Fonts 中的 UbuntoMono Nerd Font Mono 字体,因为该字体的中文宽度正好为两个英文字符的宽度,中文字隔得没有那么开,缺点就是行间距变小了,如果想行间距大一点,可以选择 DejaVuSansMono Nerd Font Mono。我还是使用 Vundle 管理以上这些插件。只需五步,即可完成 Vim 的安装和配置。

第一步、安装并设置字体

我使用的是 Nerd Fonts 中的 UbuntuMono Nerd Font Mono 字体,因为该字体的中文宽度比较正常。根据前面的链接去 github 上下载,并在终端中设置即可。该字体比较小,所以字体大小设置为13号或15号。

第二步、安装 Vim、GVim、exuberant-ctags、curl 和git

sudo aptitude install vim vim-gtk3 exuberant-ctags curl git build-essential cmake python3-dev

之所以安装 build-essential 、cmake 和 python3-dev,是因为要编译 YouCompleteMe。

第三步、把以下代码拷贝到配置文件 ~/.vimrc 中

代码非常简洁,如下:

set nocompatible

filetype off
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'majutsushi/tagbar'
Plugin 'kien/ctrlp.vim'
Plugin 'scrooloose/nerdtree'
Plugin 'ycm-core/YouCompleteMe'
Plugin 'vim-syntastic/syntastic'
Plugin 'altercation/vim-colors-solarized'
Plugin 'vim-airline/vim-airline'
Plugin 'yianwillis/vimcdoc'
call vundle#end()
filetype plugin indent on

set history=1000
set ruler
set number
set showcmd
set showmode
set laststatus=2
set cmdheight=2
set scrolloff=3

set fillchars=stl:\ ,stlnc:\ ,vert:\ 

set noerrorbells
set novisualbell
set t_vb=

set background=dark
syntax on
colorscheme desert
set cursorline
hi CursorLine term=NONE cterm=NONE ctermbg=0 guibg=Gray40

set backspace=2
set whichwrap+=<,>,h,l

set expandtab
set smarttab
set shiftwidth=4
set tabstop=4
set autoindent
set cindent

set nobackup
set noswapfile
set autoread
set autowrite
set autochdir
set fileencodings=utf-8,cp936
set fileformats=unix,dos,mac

set showmatch
set matchtime=2
set hlsearch
set incsearch
set ignorecase
set smartcase
set magic
set lazyredraw
set nowrapscan
set iskeyword+=_,$,@,%,#,-,.

map <F2> :NERDTreeToggle<CR>
map <F3> :TagbarToggle<CR>
map <F4> :CtrlPMixed<CR>

let g:airline_powerline_fonts = 1
let g:airline#extensions#tabline#enabled = 1
set completeopt=menu,menuone,popup,noinsert
if has("gui_running")
    colorscheme solarized
    set guifont=UbuntuMono\ Nerd\ Font\ Mono\ 13
    set guioptions=aegicmT
    let g:airline_powerline_fonts = 0
endif

Vim 是可以访问全局剪切板的,所以只需要复制上面的代码,然后使用vim ~/.vimrc命令编辑~/.vimrc文件,在 Vim 的 Normal 模式下键入"*p就可以把以上内容粘贴到 Vim 中。然后键入:wq保存退出即可。

第四步、下载 Vundle,再用 Vundle 安装其它的插件

先建立Vundle需要用到的目录,然后使用 git 从 github 上下载 Vundle,命令如下:

mkdir ~/.vim
mkdir ~/.vim/bundle
cd ~/.vim/bundle
git clone https://github.com/VundleVim/Vundle.vim.git

然后,再打开 Vim,在 Normal 模式下键入:PluginInstall,静静地等待它安装完成就可以了。

第五步、编译 YouCompleteMe

其实这一步非常简单,YouCompleteMe的安装脚本都写好了,一条命令就可以自动编译。但是有两个前提,一是要有 cmake,二是要有 3.7 版本以上的 python, python 还要有相应的头文件。这两个前面已经安装过了。

然后就可以开始编译安装 YouCompleteMe 了,既然是写 C/C++ 程序,那就制定 clangd 作为 Completer。这里的 clangd 不需要我们额外安装哦, YouCompleteMe 的安装脚本会自动下载。命令如下:

cd ~/.vim/bundle/YouCompleteMe
./install.py --clangd-completer

就是这么简单。

在使用过程中,按 F2 键调出 NERDTree,按 F3 键调出 Tagbar,按 F4 键调出 CtrlP。如果只写个简单的程序,单窗口就够了。写简单的 C 代码,输入函数开始的几个字母后,按 Ctrl+空格 可以调出补全功能,或者输入'.'、'->'、"、'::'等字符时,会自动蹦出补全功能。

使用 Vim 阅读 Linux 内核源代码

实战一下,看看用 Vim 阅读 Linux 内核源代码是什么效果。首先,我们需要安装 linux-source 软件包,然后解压缩,再然后生成 tags 文件。命令如下:

sudo apt install linux-source
cd /usr/src/
sudo tar jxvf linux-source-4.15.0.tar.bz2
cd linux-source-4.15.0
sudo ctags -R --c++-kinds=+p --fields=+ias --extra=+q

最后,在/usr/src/linux-source-4.15.0/目录中运行vim命令就可以了。按 F4 调出 CtrlP,输入我们想看的源代码文件名进行查找,例如红黑树的实现 rbtree.c,你只要输入rbtree,CtrlP就会自动找到lib/rbtree.c。如果想要在代码间跳转,或者自动补全,就需要在 Vim 中加入 tags 文件,使用:set tags+=/usr/src/linux-source-4.15.0/tags命令即可。我在使用 Vim 写 C/C++ 程序时,常常喜欢在/usr/include目录下生成 tags 文件,然后把它添加到 Vim 中,这样,C/C++ 标准库和 Linux 系统库的自动补全就全有了。在控制台下运行的效果,如下图:

我特意退出全屏模式进行展示,因为上一篇一开头就向大家展示过全屏半透明控制台的威力了。在 GVim 中运行的效果,如下图:

体验 YouCompleteMe

YouCompleteMe 在 github 上的地址为 ycm-core/YouCompleteMe,大家可以自行去阅读它的文档。如下两图,就是它的使用效果:

体验 vim-airline

为了获得最佳效果,把终端的字体更改为 UbuntuMono Nerd Font Mono,结果如下图:

还有这样的效果:

体验中文帮助文档

在 github 上有 Vim 的中文文档项目,该中文文档也可以通过插件的形式提供支持。在前面的配置文件中,就有一条Plugin 'yianwillis/vimcdoc'条目,该插件安装后,帮助文档就自动变成中文的了。其效果如下图:

版权申明

该随笔由京山游侠在2018年09月11日发布于博客园,引用请注明出处,转载或出版请联系博主。QQ邮箱:1841079@qq.com