把Vim配置成属于自己的模样
本文最后更新于 2024-10-15,文章内容距离上一次更新已经过去了很久啦,可能已经过时了,请谨慎参考喵。
title: 把Vim配置成属于自己的模样
tags:
- Linux
- Vim
- Vimrc
categories:
- 工具
top_img: false
cover: '/upload/cdn0files/20200721130037.jpg'
abbrlink: bfe797d6
date: 2019-12-30 22:06:09
updated: 2019-12-30 22:06:09
启用 Vim 的特性
Vim编辑器相关的所有功能开关都可以通过.vimrc
文件进行设置,.vimrc
配置文件分系统配置和用户配置两种。
系统vimrc配置文件存放在Vim的安装目录,默认路径为 /usr/share/vim/.vimrc
。可以使用命令 echo $VIM
来确定Vim的安装目录。用户 vimrc 文件,存放在用户主目录下 ~/.vimrc
,可以使用命令 echo $HOME
确定用户主目录。
$ vim ~/.vimrc
基础设置
双引号内的中文均为注释,其他视情况而定。
设置中文不乱码
与Vim编码有关的变量包括:encoding
、fileencoding
、termencoding
。
encoding
选项用于缓存的文本、寄存器、Vim 脚本文件等;fileencoding
选项是Vim写入文件时采用的编码类型;termencoding
选项表示输出到终端时采用的编码类型。
"设置编码
set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936
set termencoding=utf-8
set encoding=utf-8
显示行号
nu是number的缩写,两个配置命令是完全等效的
set nu
set number
突出显示当前行
set cursorline
启用鼠标
Vim编辑器里默认是不启用鼠标的,也就是说不管你鼠标点击哪个位置,光标都不会移动。通过以上设置就可以启动鼠标,不过对于高级玩家来说,用Vim就是为了解放双方不用鼠标,所以这个设置可以根据个人爱好选择.
set mouse=a
set selection=exclusive
set selectmode=mouse,key
设置缩进
"设置Tab长度为4空格
set tabstop=4
"设置自动缩进长度为4空格
set shiftwidth=4
"继承前一行的缩进方式,适用于多行注释
set autoindent
粘贴格式
显示空格和tab键在Vim中通过鼠标右键粘贴时会在行首多出许多缩进和空格,通过 set paste
可以在插入模式下粘贴内容时不会有任何格式变形、胡乱缩进等问题。Vim编辑器中默认不显示文件中的tab和空格符,通过上面的配置可以获得以下的显示效果,方便定位输入错误
set paste
set listchars=tab:>-,trail:-
显示状态栏和光标当前位置
"总是显示状态栏
set laststatus=2
"显示光标当前位置
set ruler
Vim配置变更立即生效
要让.vimrc
变更内容生效,一般的做法是先保存.vimrc
再重启vim,增加以下设置,可以实现保存 .vimrc
时自动重启加载
autocmd BufWritePost $MYVIMRC source $MYVIMRC
语法高亮
Vim 自带语法高亮显示功能,只需要打开 syntax
选项即可, 依赖于 Vim 的文件类型检测功能.
"打开文件类型检测
filetype on
"打开语法高亮显示
syntax on
插件功能
代码自动补齐
虽然 Vim自带自动补齐功能,但是这种自带的补齐功能其本质就是 猜:通过对文本进行正则表达式匹配,再根据字典文件和生成的tags文件实现自动补全的效果, 因此其功能相对也较为简单。
YouCompleteMe 简称 YCM,是一款 Vim 下非常流行的自动代码补齐神器。YouCompleteMe 基于 clang/llvm 等开源语法分析库进行构建,并整合了多种自动补齐引擎:
an identifier-based engine that works with every programming language、a Clang-based engine that provides native semantic code completion for C/C++/Objective-C/Objective-C++/CUDA、a clangd-based experimental completion engine for the C-family languages、a Jedi-based completion engine for Python 2 and 3、an OmniSharp-based completion engine for C#、a combination of Gocode and Godef semantic engines for Go、an omnifunc-based completer that uses data from Vim’s omnicomplete system to provide semantic completions for many other languages (Ruby, PHP etc.)。
由此可见,YouCompleteMe 几乎对现在所有流行的编程语言都提供了非常强大的补齐功能。
编译 YouCompleteMe 插件时需要依赖 cmake 构建 Makefile,且依赖 Python 源码头文件
安装Python依赖
$ sudo apt-get install build-essential cmake python-dev python3-dev
安装Clang
clang 是一个面向 C 族语言(C-family languages)的轻量级编译器,YouCompleteMe 插件依赖 clang 实现对 C 族语言的语义补全
$ sudo apt-get install clang
Clone
可以使用 Vundle 或 vim-plug 等 Vim 插件管理器从 github 获取 YouCompleteMe 最新的源码,这里推荐使用 Vundle。也可以直接使用
git clone https://github.com/Valloric/YouCompleteMe.git ~/.vim/plugged/
获取依赖
在源码目录执行:
git submodule update --init --recursive
编译安装
在源码目录执行:
$ python3 install.py --clang-completer
--clang-completer
参数是编译C族语言的补全,如果需要全部语言,换成--all
参数即可
安装Vundle插件管理器
Vundle插件是提供一个Vundle.vim文件,其下载地址为:https://github.com/VundleVim/Vundle.vim.git
将下载的Vundle.vim文件夹(之后的所有插件相同)保存到~/.vim/bundle然后修改配置文件即可完成Vundle的安装
配置Vundle
修改.vimrc
文件,添加下列配置:
"去除VIM一致性
set nocompatible
filetype off
"设置包括vundle和初始化相关的运行时路径
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
"启用vundle管理插件
Plugin 'VundleVim/Vundle.vim'
"在此增加其他插件,安装的插件需要放在vundle#begin和vundle#end之间
"安装github上的插件格式为 Plugin '用户名/插件仓库名'
call vundle#end()
"加载vim自带和插件相应的语法和文件类型相关脚本
filetype plugin indent on
更多Vundle有关配置可以参考官方文档
使用Vundle安装插件
首先需要将要安装的插件,按照上面的配置格式将插件地址填写在vundle#begin
和vundle#end
之间并保存设置好配置文件后,可通过下述两种方法安装插件:
- 在Vim尾行模式下运行命令
:PluginInstall
- 在终端命令行下通过命令
vim +PluginInstall +qall
删除插件
- 编辑Vim配置文件.vimrc文件,删除要移除插件所对应的Plugin一行
- 打开Vim,在Vim尾行模式执行命令
:BundleClean
即可删除对应Vim插件
Vim自带的代码补全功能
在插入模式下,Vim可以不借助任何插件实现自动补全功能。Vim自带有单词自动补全、行自动补全和基于用户自定义字典的自动补全。
Ctrl + n
:当输入完第一个字母后,再按Ctrl + n
,Vim会自动出现下拉菜单,且默认选中第一个单词- 继续按
Ctrl + n
可以上下选择,但如果缓冲区没有可选单词,那么下拉列表不会有任何选项 Ctrl + p
:功能同上,只是默认选中的是列表最后一个单词- 在Vim插入模式下输入已经存在行的第一个单词,再按
Ctrl + x
、Ctrl + l
命令,就会列出该整行出来实现Vim行自动补全
字典补全
假设有一个备选单词表,文件名为dict.txt,每行一个单词,里面包含以下内容:
- Hello
- Vim
- editor
- best
- tool
若要实现基于该单词表的Vim自动补齐,需要设置以下步骤:
- 在~/.vimrc配置文件中加入代码:
set dictionary-=~/dict.txt dictionary+=~/dict.txt
- 打开Vim,在插入模式下输入
Ctrl + x
后再输入Ctrl + k
,就能看到dict.txt文件中定义的单词 - 若想直接通过
Ctrl + n
命令就显示其中的列表,再配置.vimrc文件,加入set complete-=k complete+=k
函数跳转
可以使用 Vim 插件 vim-gutentags 自动生成和更新 tags 文件进行跳转,得益于 Vim 8 提供的异步机制,vim插件vim-gutentags能够自动异步生成 tags 文件,当检测到同一个工程下面的文件有修改时,gutentags能自动增量更新对应工程的 tags 文件,而不用全部重新生成tags文件,是一个非常高效的tags生成工具。vim-gutentags的本质仍然是使用ctags生成tag标签来实现函数跳转等功能,只是在ctags的基础上进行了封装和简化,方便用户在vim中使用。由于vim-gutentags依赖ctags工具,因此在使用vim-gutentags插件的系统中必须安装ctags软件,否则会报错”Excutable ‘ctags’ can’t be found.”。
安装tags软件
$ sudo apt-get install exuberant-ctags
其次,vim-gutentags需要在vim8.0以上版本才能正常工作,因为vim-gutentags实现的是增量更新tags的方式,依赖于vim8提供的异步机制。在低于vim8.0的版本是运行vim-gutentags插件,会报错”this plugin requires the job API from Vim8 or Neovim”。 把相应vim文件放在~/.vim/bundle/下
在配置文件 ~/.vimrc 中增加配置项:
Plugin 'ludovicchabant/vim-gutentags'
再在vim的Normal模式下执行命令 :PlugInstall
vim-gutentags插件的基本工作原理可以这么理解:首先确定vim当前打开的文件是否需要自动生成tags标签,若需要则通过某种方式确定tag文件的路径,再基于tag标签文件完成函数跳转、结构体定义跳转等功能。
gutentags配置
" gutentags搜索工程目录的标志,碰到这些文件/目录名就停止向上一级目录递归
let g:gutentags_project_root = ['.root', '.svn', '.git', '.project']
" 所生成的数据文件的名称
let g:gutentags_ctags_tagfile = '.tags'
" 将自动生成的 tags 文件全部放入 ~/.cache/tags 目录中,避免污染工程目录
let s:vim_tags = expand('~/.cache/tags')
let g:gutentags_cache_dir = s:vim_tags
" 检测 ~/.cache/tags 不存在就新建
if !isdirectory(s:vim_tags)
silent! call mkdir(s:vim_tags, 'p')
endif
" 配置 ctags 的参数
let g:gutentags_ctags_extra_args = ['--fields=+niazS', '--extra=+q']
let g:gutentags_ctags_extra_args += ['--c++-kinds=+pxI']
let g:gutentags_ctags_extra_args += ['--c-kinds=+px']
变量 gutentags_project_root 是vim-gutentags提供的用于搜索工程目录的标志,gutentags插件启动后,会从文件当前路径递归往上查找 gutentags_project_root 中指定的文件或目录名,直到第一次找到对应目标文件或目录名停止。若没有找到 gutentags_project_root 变量指定的文件或目录名,则gutentags不会生成tag文件。
变量 gutentags_ctags_tagfile 和 gutentags_cache_dir 分别用于告诉ctags要使用的tag文件目录和tag文件名后缀,tag文件名的生成规则默认是根据生成tag文件的工程绝对路径按 - 分割而成。
变量 gutentags_ctags_extra_args 用于配置ctags生成tag标签的参数
ctags参数意义
参数 | 含义 |
---|---|
c | 类(classes) |
d | 宏定义(macro definitions) |
e | 枚举变量(enumerators) |
f | 函数定义(function definitions) |
g | 枚举类型(enumeration names) |
l | 局部变量(local variables),默认不提取 |
m | 类、结构体、联合体(class, struct, and union members) |
n | 命名空间(namespaces) |
p | 函数原型(function prototypes),默认不提取 |
s | 结构体类型(structure names) |
t | (typedefs) |
u | 联合体类型(union names) |
v | 变量定义(variable definitions) |
x | 外部变量(external and forward variable declarations),默认不提取 |
需要注意的是,gutentags 需要靠上面定义的 gutentags_project_root
判断文件所在的工程,如果一个文件没有保存在包含 .git
、.svn
、.root
等 定义在 gutentags_project_root
中的文件,gutentags就不会为该野文件生成 tags
。 #在为当前目录生成tags文件后,可以通过按键 Ctrl + ]
跳转到对应的定义位置,再使用命令 Ctrl + o
回退到原来的位置。 建议多使用 Ctrl + W + ]
用新窗口打开并查看光标下符号的定义,或者 Ctrl+W+]
使用 preview 窗口预览光标下符号的定义。
工程项目树展示
Vim插件NERDTree是一款用来在Vim界面显示树形目录的文件管理器插件,可在vim操作界面进行文件打开、目录浏览操作。其github地址为:https://github.com/scrooloose/nerdtree
使用Vim插件管理器Vundle安装Vim插件NERDTree:
Plugin 'scrooloose/nerdtree'
通过vundle安装好NERDTree插件后,在vim命令行模式输入命令:NERDTree
就可以看到NERDTree的显示界面。使用快捷键 Ctrl + w
,可将光标自动在左右侧窗口进行切换。
配置.vimrc文件
"在 vim 启动的时候默认开启 NERDTree:
autocmd VimEnter * NERDTree
或使用autocmd的缩写形式
au VimEnter * NERDTree
"将NERDTree的窗口设置在vim窗口的右侧(默认为左侧):
let NERDTreeWinPos="right"
NERDTree常用命令汇总
命令 | 作用 |
---|---|
q | 关闭 NERDTree |
o | 在已有窗口中打开文件或目录,并将光标跳到该窗口 |
O | 递归打开选中 结点下的所有目录 |
x | 合拢选中结点的父目录 |
X | 递归 合拢选中结点下的所有目录 |
p | 跳到根结点 |
P | 跳到父结点 |
u | 设置上级目录为根路径 |
U | 设置上级目录为跟路径,但是维持原来目录打开的状态 |
r | 刷新光标所在的目录 |
R | 刷新当前根路径 |
I | 显示或者不显示隐藏文件 |
f | 打开和关闭文件过滤器 |
A | 全屏显示 NERDTree,或者关闭全屏 |
C | 将根路径设置为光标所在的目录 |
代码折叠
Vim支持多种折叠形式:手动折叠manual、基于缩进行折叠indent、基于语法进行折叠syntax、未更改文本折叠diff等
在 ~/.vimrc 配置文件中增加以下配置项
"基于缩进进行代码折叠
set foldmethod=indent
"启动 Vim 时关闭折叠
set nofoldenable
Vim打开文件后,重复使用操作命令
za
可打开或关闭当前折叠;zM
用于关闭所有折叠,zR
则用来打开所有折叠
全局搜索
推荐Vim模糊搜索插件ctrlp。ctrlp是一款支持对文件、缓冲区( :CtrlPBuffer )、MRU(Most Recently Used)文件( :CtrlPMRU )和标签进行模糊搜索/查找的Vim插件,也支持通过正则表达式搜索 ( -r 进行切换),同类软件还有模糊搜索插件fzf等。 地址:https://github.com/ctrlpvim/
安装插件
Plugin 'ctrlpvim/ctrlp.vim'
安装完ctrlp插件后,可以在Vim命令行模式下使用命令 :help ctrlp.txt 获取ctrlp的官方说明文档,这是个非常详细的文档,建议细读
ctrlp命令介绍
在Vim命令行模式下,可通过以下几种方式启动ctrlp:
-
Vim命令行模式下使用命令
:CtrlP
或:CtrlP
路径可以调用ctrlp并进入查找文件模式,可通过设置
let g:ctrlp_cmd = 'CtrlP'
来指定打开ctrlp的Vim命令行命令 -
Vim命令行模式下使用命令
:CtrlPBuffer
或:CtrlPMRU
可以调用ctrlp并分别进入查找缓冲区 和 查找 MRU文件模式
-
Vim命令行模式下使用命令
:CtrlPMixed
可同时搜索 文件、缓冲区 和 MRU文件 -
在Vim 普通模式下,默认按下
Ctrl+p
即可打开ctrlp搜索窗口。可通过设置let g:ctrlp_map = '<c-p>'
来修改Vim普通模式下默认打开ctrlp的Vim按键映射。 -
默认设置下,ctrlp的窗口显示在Vim窗口的底端(bottom),可以通过
g:ctrlp_match_window
选项设置窗口的位置,例如,let g:ctrlp_match_window = 'top,order:ttb,min:1,max:10,results:20'
设置ctrlp窗口显示在顶端(top),模糊搜索结果按从上到下(ttb, top to bottom)的顺序显示,高度最小为1行,最大为10行,搜索结果最多显示20行。
一旦打开ctrlp,即可输入要寻找的文件名使用ctrlp进行模糊搜索,可以使用以下命令进行操作:
- 按下
Esc
或Ctrl-c
可退出ctrlp,返回到Vim窗口中 - 按下
F5
用于刷新当前操作路径下的文件缓存,可以使用命令let g:ctrlp_cache_dir = $HOME.'/.cache/ctrlp'
设置缓存文件存放路径 - 使用
Ctrl-k
和Ctrl-j
在模糊搜索结果列表中上下移动 (当然也可以使用键盘上的上下方向键 - 使用
Ctrl-f
和Ctrl-b
在查找文件模式、查找缓冲区模式、查找MRU文件几种模式间进行切换 (cycle between modes) - 使用
Ctrl-d
在 路径匹配 和 文件名匹配 之间切换 (switch to filename search instead of full path) ,可以通过设置 let g:ctrlp_by_filename = 1 来设置默认使用 文件名匹配 模式进行模糊搜索 - 使用
Ctrl-r
在 字符串模式 和 正则表达式模式 之间切换 (switch to regexp mode) - 使用
Ctrl-t
在新的Vim标签页中打开文件 (open the selected entry in a new tab) - 使用
Ctrl-v
垂直分割窗口打开文件 - 使用
Ctrl-x
水平分割窗口打开文件 - 使用
Ctrl-p
或` 选择前或后一条历史记录 - 使用
Ctrl-y
用于当搜索的目标文件不存在时创建文件及父目录 (create a new file and its parent directories) - 使用
Ctrl-z
标记或取消标记多个文件, 标记多个文件后可以使用Ctrl-o
同时打开多个文件
括号自动补全
安装插件
Plugin 'jiangmiao/auto-pairs'
配置.vimrc文件
"设置要自动配对的符号
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"'}
"添加要自动配对的符号<>
let g:AutoPairs['<']='>'
"设置要自动配对的符号,默认为g:AutoPairs,可以通过自动命令来对不同文件类型设置不同自动匹配对符号
let b:AutoPairs = g:AutoParis
"设置插件打开/关闭的快捷键,默认为ALT+p。
let g:AutoPairsShortcutToggle = '<M-p>'
"设置自动为文本添加圆括号的快捷键,默认为ALT+e。
let g:AutoPairsShortcutFastWrap = '<M-e>'
"设置调到下一层括号对的快捷键,默认为ALT+n。
let g:AutoPairsShortcutJump = '<M-n>'
"设置撤销飞行模式的快捷键,默认为ALT+b。
let g:AutoPairsShortcutBackInsert = '<M-b>'
"把BACKSPACE键映射为删除括号对和引号,默认为1。
let g:AutoPairsMapBS = 1
"把ctrl+h键映射为删除括号对和引号,默认为1。
let g:AutoPairsMapCh = 1
"把ENTER键映射为换行并缩进,默认为1。
let g:AutoPairsMapCR = 1
"当g:AutoPairsMapCR为1时,且文本位于窗口底部时,自动移到窗口中间。
let g:AutoPairsCenterLine = 1
"把SPACE键映射为在括号两侧添加空格,默认为1。
let g:AutoPairsMapSpace = 1
"启用飞行模式,默认为0。
let g:AutoPairsFlyMode = 0
"启用跳出多行括号对,默认为1,为0则只能跳出同一行的括号。
let g:AutoPairsMultilineClose = 1
安装vim-airline
Plugin 'bling/vim-airline'
安装neocomplete
Plugin 'Shougo/neocomplete'
注意启用设置粘贴set paste的时候会自动禁用这个插件
安装neocomplete 插件需要vim的lua模块支持
let g:neocomplete#enable_at_startup = 1
"至此,neocomplete配置完成。同时,作者提供了一份neocomplete的配置,如果没有特殊需要,可以直接使用:
"Note: This option must be set in .vimrc(_vimrc). NOT IN .gvimrc(_gvimrc)!
" Disable AutoComplPop.
let g:acp_enableAtStartup = 0
" Use neocomplete.
let g:neocomplete#enable_at_startup = 1
" Use smartcase.
let g:neocomplete#enable_smart_case = 1
" Set minimum syntax keyword length.
let g:neocomplete#sources#syntax#min_keyword_length = 3
" Define dictionary.
let g:neocomplete#sources#dictionary#dictionaries = {
\ 'default' : '',
\ 'vimshell' : $HOME.'/.vimshell_hist',
\ 'scheme' : $HOME.'/.gosh_completions'
\ }
" Define keyword.
if !exists('g:neocomplete#keyword_patterns')
let g:neocomplete#keyword_patterns = {}
endif
let g:neocomplete#keyword_patterns['default'] = '\h\w*'
" Plugin key-mappings.
inoremap <expr><C-g> neocomplete#undo_completion()
inoremap <expr><C-l> neocomplete#complete_common_string()
" Recommended key-mappings.
" <CR>: close popup and save indent.
inoremap <silent> <CR> <C-r>=<SID>my_cr_function()<CR>
function! s:my_cr_function()
return (pumvisible() ? "\<C-y>" : "" ) . "\<CR>"
" For no inserting <CR> key.
"return pumvisible() ? "\<C-y>" : "\<CR>"
endfunction
" <TAB>: completion.
inoremap <expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>"
" <C-h>, <BS>: close popup and delete backword char.
inoremap <expr><C-h> neocomplete#smart_close_popup()."\<C-h>"
inoremap <expr><BS> neocomplete#smart_close_popup()."\<C-h>"
" Close popup by <Space>.
"inoremap <expr><Space> pumvisible() ? "\<C-y>" : "\<Space>"
" AutoComplPop like behavior.
"let g:neocomplete#enable_auto_select = 1
" Shell like behavior(not recommended).
"set completeopt+=longest
"let g:neocomplete#enable_auto_select = 1
"let g:neocomplete#disable_auto_complete = 1
"inoremap <expr><TAB> pumvisible() ? "\<Down>" : "\<C-x>\<C-u>"
" Enable omni completion.
autocmd FileType css setlocal omnifunc=csscomplete#CompleteCSS
autocmd FileType html,markdown setlocal omnifunc=htmlcomplete#CompleteTags
autocmd FileType javascript setlocal omnifunc=javascriptcomplete#CompleteJS
autocmd FileType python setlocal omnifunc=pythoncomplete#Complete
autocmd FileType xml setlocal omnifunc=xmlcomplete#CompleteTags
" Enable heavy omni completion.
if !exists('g:neocomplete#sources#omni#input_patterns')
let g:neocomplete#sources#omni#input_patterns = {}
endif
"let g:neocomplete#sources#omni#input_patterns.php = '[^. \t]->\h\w*\|\h\w*::'
"let g:neocomplete#sources#omni#input_patterns.c = '[^.[:digit:] *\t]\%(\.\|->\)'
"let g:neocomplete#sources#omni#input_patterns.cpp = '[^.[:digit:] *\t]\%(\.\|->\)\|\h\w*::'
" For perlomni.vim setting.
" https://github.com/c9s/perlomni.vim
let g:neocomplete#sources#omni#input_patterns.perl = '\h\w*->\h\w*\|\h\w*::'
先到这里,以后发现了什么好玩的插件再来更新。