0%

vi/vim命令学习

一、基础配置和命令

1. 常用命令和快捷键(vi适用部分命令)

1.1. normal模式

  • i: 在光标当前位置插入,进入编辑模式
  • a: 在光标后面插入,进入编辑模式
  • Esc: 退出编辑模式
  • Shift + z, Shift + z: 保存并退出
  • Shift + z, Shift + q: 不保存退出
  • h: 左移光标
  • l: 右移光标
  • j: 下移光标
  • k: 上移光标
  • w: 标点分割,下一个字首
  • e: 标点分割,下一个字尾
  • b: 标点分割,上一个字首
  • Shitf + w: 空格分割,下一个字首
  • Shift + e: 空格分割,下一个字尾
  • Shift + b: 空格分割,上一个字首
  • 0: 跳至行首,不管有无缩进,就是跳到第0个字符
  • [n]|: 跳至第n列
  • f[x]: 跳至下一个x字符
  • Shift + ^: 跳至行首的第一个字符
  • Shift + $: 跳至行尾
  • gg: 移到文件首行
  • G: 移到文件末行
  • gd: 跳转到符号定义,当前函数
  • gD: 跳转到符号定义,整个文件
  • Ctrl + u / PageUp: 向上翻页
  • Ctrl + d / PageDown: 向下翻页
  • x / Del: 删除光标后面的字符
  • u: 撤销
  • Ctrl + r: 重做
  • Shift + *: 向下查找并高亮光标所在单词
  • Shift + #: 向上查找并高亮光标所在单词
  • :noh: 取消高亮
  • Ctrl + o: 调回上次光标位置
  • Ctrl + i: 跳到下一次光标位置
  • /<xxx>: 当前文件搜索字符串,看设置决定是否区分大小写
  • /\c<xxx>: 当前文件搜索字符串,不区分大小写
  • /\C<xxx>: 当前文件搜索字符串,区分大小写
  • n: 跳到下一个搜索位置
  • N: 跳到上一个搜索位置
  • :<xxx>: 跳转当前文件行号
  • :w: 保存更改
  • :q: 退出当前窗口
  • :q!: 不保留更改退出当前窗口
  • :qa: 退出所有窗口
  • :x: 有改动就写入文件并退出(相当于:wq),没有改动直接退出不改动文件
  • v: 进入选择模式
  • Ctrl + v: 进入块选择模式
  • g, f: 跳转到光标所在的文件
  • p: 粘贴vim剪贴板
  • yy: 复制当前一行
  • diw: 剪切当前单词
  • daw: 剪切当前单词包括前导或后导空格(基于位置分析)
  • dip: 剪切当前段(前后有空行)
  • dap: 剪切当前段包括前导或后导空行(基于位置分析)
  • dd: 剪切当前一行
  • :f: 显示当前文件路径
  • Ctrl + g: 显示当前文件路径
  • (n)>>: 当前行缩进n个tab,默认1个tab
  • (n)<<: 当前行少缩进n个tab,默认1个tab

替换命令

  • :s/abc/def: 当前行第一个abc替换成def
  • :s/abc/def/g: 当前行所有abc替换成def
  • :%s/abc/def: 在整个文档中将abc替换成def
  • :5,15s/abc/def/g: 在5到15行中将abc替换成def
  • 可以使用正则,规则和sed一样
  • :%s/^/def/g: 每行行首添加def
  • :%s/$/def/g: 每行行尾添加def

1.2. visual模式

  • y: 复制选中的文本
  • d: 剪切选中的文本
  • iw: 选中当前单词
  • aw: 选中当前单词包括前导或后导空格(基于位置分析)
  • ip: 选中当前段(前后有空行)
  • ap: 选中当前段包括前导或后导空行(基于位置分析)
  • Shift + }: 跳到下一个空行
  • Shift + {: 跳到上一个空行

1.3. replace模式

  • r: 替换当前光标下字符,直接输入即可替换,输入完自动退出到normal模式
  • R: 进入replace模式,输入会直接向后替换,不是插入,类似于按了insert键,esc退出replace模式

2. leader键

  • vim默认的leader键为\

3. 编码

  1. encoding:VIM 使用的字符编码格式,包括 VIM 的 buffer (缓冲区)、菜单文本、消息文本等。可在~/.vimrc 中改变它的值,如果打开的文件编码与该属性配置的编码不同,那么VIM会将编码自动转换到这种编码然后再显示。
  2. fileencoding:VIM 当前编辑的文件的字符编码方式,VIM保存文件时也会将文件保存为这种字符编码方式 (不管是否新文件都如此);如果它的值与encoding不一样,那么保存的时候VIM会自动把文件内容由encoding的编码转换为fileencoding配置编码再保存。而读取文件的时候,该选项的值会自动同步为fileencodings配置的有效编码。
  3. fileencodings:此项目配置的是一个编码列表,止Vim在读取文件的时候,会按照它所列出的字符编码方式逐一探测即将打开的文件的字符编码方式,并且将 fileencoding 设置为最终探测到的字符编码方式。因此最好将 Unicode 编码方式放到这个列表的最前面。
  4. termencoding:VIM 所工作的终端 (或者 Windows 的 Console 窗口) 的字符编码方式。这个选项在 Windows 下对我们常用的 GUI 模式的 gVim 无效,而对 Console 模式的 Vim 而言就是 Windows 控制台的代码页,并且通常我们不需要改变它。

配置

1
set fileencodings=utf-8,gb2312,gbk,gb18030 	" 自动从这些编码识别文件编码

命令

  • :set fileencoding=utf-8: 将文件用utf-8保存
  • :e ++enc=gbk: 使用gbk重新打开文件
  • :w ++enc=utf-8: 使用utf-8保存文件

4. 格式

配置

1
set fileformats=unix,dos	" 自动识别unix和dos格式打开

命令

  • :set fileformat=unix: 将文件以unix保存

5. 读取和保存

配置

1
2
3
set autoread        " 外部改动自动读取
set autowriteall " 和autowrite类似,不过支持跳转命令保存
set noswapfile " 不创建临时文件,防止被提交上去

6. 高亮

取消高亮

1
2
set nohlsearch
set noh

7. 行号

1
2
set number     " 显示行号
set nonumber " 取消显示行号

8. tab缩进

8.1. 配置

1
2
3
4
5
6
7
8
set tabstop=4           " 4个空格识别成tab,读到的\t解释成4个空格
set softtabstop=4 " tab输入为4个空格宽度
set shiftwidth=4 " 换行时的自动缩进列数
set expandtab " 输入tab转成空格
set noexpandtab " 输入tab不转成空格
set autoindent " 自动缩进
set smartindent " 智能缩进
filetype indent on " 不同文件使用不同缩进

8.2. 转换命令

tab转空格

1
2
3
:set tabstop=4           " 4个空格识别成tab,读到的\t解释成4个空格
:set expandtab " 输入tab转成空格
:%retab! " 对当前缓冲区重新tab,!保证除行首同样转换

空格转tab

1
2
3
:set tabstop=4           " 4个空格识别成tab,读到的\t解释成4个空格
set noexpandtab " 输入tab不转成空格
:%retab! " 对当前缓冲区重新tab,!保证除行首同样转换

9. 状态栏

1
2
3
4
5
set laststatus=2    " 显示状态栏
set ruler " 显示鼠标所在行数在状态栏
set cursorline " 高亮光标所在行
" 配置状态栏显示格式
set statusline=%w%n:%f%m\ %r%=Ln:%l/%L,Col:%c%V\ \ %{(&fenc==\"\"?&enc:&fenc).((exists(\"+bomb\")\ &&\ &bomb)?\"\ BOM\":\"\")}\ \ %{&ff}\ \ %Y\ [%P]

10. 代码配色

1
2
syntax on           " 代码配色
colorscheme xxx " 配色方案采用xxx

系统配色方案

1
2
3
4
~|⇒ ls /usr/share/vim/vim74/colors
blue.vim delek.vim evening.vim murphy.vim README.txt slate.vim
darkblue.vim desert.vim koehler.vim pablo.vim ron.vim torte.vim
default.vim elflord.vim morning.vim peachpuff.vim shine.vim zellner.vim

添加配色方案

1
2
git clone https://github.com/xxx
mv xxx/colors ~/.vim/colors

推荐配色方案

  • molokai: https://github.com/tomasr/molokai.git

11. vimg 全局搜索

命令

  • :vimgrep /xxx/ % :搜索xxx,在当前文件
  • :vimgrep /xxx/ % | copen :搜索xxx,在当前文件,打开quickfix
  • :vimgrep /xxx/ ./xxx/xxx/*/*.* :搜索xxx,在xxx/xxx/下的一级子目录所有文件
  • :vimgrep /xxx/ ./xxx/xxx/**/*.* :搜索xxx,在xxx/xxx/下的所有目录下的所有文件
  • :vimgrep /xxx/j ./xxx/xxx/**/*.* :搜索xxx,在xxx/xxx/下的所有目录下的所有文件,j不跳转

配置

1
2
3
4
5
6
set hlsearch    " 高亮搜索结果
set incsearch " 输入字符串实时跳转到搜索结果
set ignorecase " 忽略大小写,一般不设置

" 配置快捷键 <leader>f 全局搜索当前光标下单词
nmap <leader>f yiw:vimg /\c<C-r>"/j **/*.* \| copen

12. quickfix

  • :cn: 跳转下一个定义
  • :cp: 条状上一个定义
  • :copen: 打开quickfix
  • :[n]cc: 跳转到第n行的quickfix
  • :[n]cn: 跳转向下n行的quickfix
  • :[n]cp: 跳转向上n行的quickfix

13. 折叠

配置

1
2
3
set foldenable          " 开启折叠
set foldlevel=999 " 设置折叠级别为999,也就是不自动折叠
set foldmethod=indent " 使用按照缩进折叠的模式

快捷键

  • z + c: 折叠
  • z + o: 不折叠

从m行到n行折叠

  • :set foldmethod=manual: 设置折叠方式为手工折叠
  • :(m),(n)fo: m行到n行折叠

14. 标签页

命令和快捷键

  • :tabnew: 打开一个新标签
  • :tabc: 关闭当前的tab
  • :tabo 关闭所有其他的tab
  • :tabs 查看所有打开的tab
  • :tabn或者gt: 下一个标签
  • :tabp或者g, Shift + t: 上一个标签
  • n, gt: 跳转到第几个标签

配置

1
2
" ctrl + n 打开新标签页
nmap <C-n> :tabnew<cr>

15. 缓冲区

命令和快捷键

  • :ls: 查看当前所有缓冲区

16. 自建命令

配置

1
command -nargs=0 xxx xxx

其中nargs定义如下,默认为-nargs=0

1
2
3
4
5
-nargs=0    # No arguments
-nargs=1 # One argument
-nargs=* # Any number of arguments
-nargs=? # Zero or one argument
-nargs=+ # One or more arguments

示例

1
command -nargs=0 JsFormat call JsBeautify()

17. 分屏

  • :vs: 横向分屏
  • :split: 纵向分屏
  • Ctrl + w, (n), Shift + >: 横向扩充窗口大小n,默认为1
  • Ctrl + w, (n), Shift + <: 横向减少窗口大小n,默认为1
  • Ctrl + w, (n), Shift + +: 纵向扩充窗口大小n,默认为1
  • Ctrl + w, (n), Shift + -: 纵向减少窗口大小n,默认为1
  • Ctrl + w, =: 横向纵向平分窗口大小
  • Ctrl + w, h: 跳转到左侧窗口
  • Ctrl + w, l: 跳转到右侧窗口
  • Ctrl + w, j: 跳转到上侧窗口
  • Ctrl + w, k: 跳转到下侧窗口
  • :res, N: 调整当前屏高度
  • :vertical res, N: 调整当前屏宽度
  • Ctrl + w, Shift + K: 调整分屏,将当前屏作为上半部分
  • Ctrl + w, Shift + J: 调整分屏,将当前屏作为下半部分
  • Ctrl + w, Shift + H: 调整分屏,将当前屏作为左半部分
  • Ctrl + w, Shift + L: 调整分屏,将当前屏作为右半部分

18. 文件比对

命令和快捷键

  • :diffthis: 当前文件加入对比,分屏多个文件后,对要比对的文件执行命令就会进行diff对比
  • dp: 当前差异块应用到另一个文件
  • do: 当前差异块应用到本文件
  • :[range]diffput: 第几行应用到另一个文件,range可以是单个行号或者逗号分隔的行号
  • :[range]diffget: 第几行应用到另一个文件,range同上
  • ]c: 跳转下一个差异块
  • [c: 跳转上一个差异块

19. 计算器

  • 没错,没看错,vim自带计算器,可以在写东西时方便插入表达式结果
  • 插入模式或者命令模式,输入Ctrl + r, =就可以输入你的表达式,回车会把结果插入到文本或者命令中
  • 比如需要计算sin,输入sin(30°)=<C-r>=sin(3.1415926/6)<cr>可以得到sin(30°)=0.5
  • 当前系统时间输入date: <C-r>=strftime('%Y-%m-%d %H:%M:%S')<cr>

20. 自建快捷键

20.1. 查看快捷键映射

1
:map xxx

示例

1
:map <leader>c

21. vim中的正则表达式

  • \|: 代表或,需要加转义
  • \<aaa\>: 代表单词开头和结尾,也就是仅匹配aaa整个单词,前后不能存在字母

22. 设置颜色

22.1. 实例

1
2
3
" NONE代表无色,也就是透明
:hi CursorLine cterm=NONE ctermbg=240
:hi CursorColumn cterm=NONE ctermbg=240

22.2. 标识

  • CursorLine: 光标所在行
  • CursorColumn: 光标所在列
  • Normal: normal状态
  • Visual: 被visual模式下选择的文本

23. 系统剪贴板

  • 使用系统剪贴板需要先查看vim是否支持clipboard
1
2
3
=> vim --version | grep clipboard
+clipboard +keymap +printer +vertsplit
+eval -mouse_jsbterm -sun_workshop +xterm_clipboard
  • 然后设置一个快捷键,在visual模式下,ctrl y复制到系统剪贴板
1
2
" ctrl y copy to system clipboard at visual mode
vnoremap <C-y> "+y

小技巧

1) 多行缩进

  1. v进入VISUAL状态
  2. 选中多行
  3. (n), Shift + >缩进n次,默认1;(n), Shift + <缩退n次,默认1

2) 多行编辑

多行删除

  1. Ctrl + v进入V-BLOCK模式
  2. 选中一整块
  3. d删除

多行插入

  1. Ctrl + v进入V-BLOCK模式
  2. 上下移动光标,到最后要插入的一行
  3. Shift + i插入,输入要添加的字符
  4. Esc退出编辑模式就会自动添加,不过要等几秒处理时间

3) 粘贴不乱缩进

  1. :set paste进入粘贴模式
  2. 粘贴将不会自动缩进
  3. :set nopaste退出粘贴模式

4) 查看值上一次被谁改动

  1. :verbose set xxx: 查看xxx上一次是在什么地方被改动

二、配置vimIde的各项插件

1. 插件安装统一方法

下载

1
2
3
4
5
git clone https://github.com/xxx ~/.vim/bundle/xxx
cd ~/.vim/bundle/xxx # 到目录查看
git tag # 查看版本号
git checkout xxxx # 切换到需要的版本
rm -rf .git* # 删除.git目录释放空间,也可以保留用于升级

配置

.vimrc里面添加

1
set rtp+=~/.vim/bundle/xxx

2. 文件树插件 NERDTree

https://github.com/scrooloose/nerdtree.git

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
" 设置打开文件树的快捷键为F10,并且打开时打开当前文件所在位置
func TreeToggle()
if !filereadable(expand("%"))
NERDTreeToggle
return
endif
if g:NERDTree.IsOpen()
NERDTreeToggle
else
NERDTreeFind
endif
endfunc
map <F10> :call TreeToggle()<cr>
" 显示隐藏文件
let g:NERDTreeShowHidden=1
" start neartree when vim start
autocmd VimEnter * NERDTree
" point cursor at buffer window
autocmd VimEnter * wincmd w

快捷键

  • Shift + c: 切换当前目录为工作目录
  • cd: 切换光标所在目录为vim所在路径
  • Shift + i: 显示和不显示隐藏文件
  • r: 递归刷新光标所在目录
  • Shift + r: 递归刷新根节点所在目录
  • m: 编辑当前目录
  • s: 横向分屏打开文件
  • i: 纵向分屏打开文件
  • o: 打开文件
  • g, s: 横向分屏打开文件,光标还在nerdtree
  • g, i: 纵向分屏打开文件,光标还在nerdtree
  • g, o: 打开文件,光标还在nerdtree
  • x: 收起光标所在的父目录
  • p: 跳转到当前的父目录
  • Shift + j: 同级最后一个
  • Shift + k: 同级第一个
  • Ctrl + j: 同级下一个
  • Ctrl + k: 同级上一个

3. C/C++格式化 clang-format

https://github.com/rhysd/vim-clang-format.git

配置

vim

1
let g:clang_format#auto_format_on_insert_leave=1  " 在离开编辑模式时自动格式化

clang-format

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 以Google的格式化为基准,后面是自定义配置
BasedOnStyle: Google
# 缩进宽度4
IndentWidth: 4
# tab宽度4
TabWidth: 4
# 将头文件排序
SortIncludes: true
# public和private顶格写
AccessModifierOffset: -4
# 尾随注释对齐
AlignTrailingComments: true
# 连续声明的变量对齐
AlignConsecutiveDeclarations: true
# 行换行最长120字符
ColumnLimit: 120
# 允许短函数放到一行,None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All
AllowShortFunctionsOnASingleLine: Empty
# 函数调用的参数要么在同一行,要么各占一行
BinPackArguments: false
# 函数声明的参数要么在同一行,要么各占一行
BinPackParameters: false

4. 标签树 tagbar

https://github.com/preservim/tagbar

配置

  • 需要ctags的支持,自行安装
  • 小技巧查看ctags
1
2
" F9作为tagbar的快捷键
map <F9> :TagbarToggle<CR>

快捷键

  • Shift + *: 展开所有标签内容
  • =: 折叠所有标签内容
  • o: 展开/折叠当前光标所在标签
  • p: 预览定义位置,光标还处于tagbar

5. 代码提示 tabnine

https://github.com/zxqfl/tabnine-vim.git

  • 不过tabnine太耗性能了,毕竟什么语言都能提示
  • 可以直接安装YCM,比较专一,js、c/c++、rust、go、java、python

6. 多行注释插件 nerdcommenter

https://github.com/scrooloose/nerdcommenter.git

配置

1
2
3
4
5
let g:NERDSpaceDelims = 1
let g:NERDCreateDefaultMappings = 0
" 使用<leader>空格设置或取消注释
nmap <leader><space> <Plug>NERDCommenterToggle
vmap <leader><space> <Plug>NERDCommenterToggle

7. 自动补全括号 auto-pairs

https://github.com/jiangmiao/auto-pairs.git

8. nerdtree的git插件 nerdtree-git-plugin

https://github.com/Xuyuanp/nerdtree-git-plugin.git

9. 文件搜索 fzf

https://github.com/junegunn/fzf.vim.git

安装

fzf依赖于shell工具fzf,所以要安装fzf才可以使用vim插件

1
2
3
git clone https://github.com/junegunn/fzf.git           # 克隆fzf到本地
sudo mv fzf /opt/ # 移动fzf到opt目录
/opt/fzf/install # 安装fzf到本地

配置

1
2
3
4
5
6
7
8
9
" fzf-vim
set rtp+=/opt/fzf " 添加fzf软件支持
set rtp+=~/.vim/bundle/fzf.vim " 添加fzf的vim插件支持
" 仿vscode,ctrl+p查找全局文件打开
map <c-p> :GitFiles<cr>
" ctrl+f,查找当前文件内容
map <c-f> :BLines<cr>
" 'Ctrl + b',查找当前打开的文件
map <leader>b :Buffers<cr>

快捷键

  • :FZF: 模糊搜索当前目录下及子目录的文件
  • :BLines: 模糊搜索当前文件中某一行字段
  • :Buffers: 模糊搜索历史打开过的文件
  • :GitFiles: 查找被git跟踪的文件
  • :GitFiles?: 查找git中检测到的改动的文件

搜索框快捷键

  • Ctrl + j/k: 上下选择
  • Ctrl + x: 水平分屏打开
  • Ctrl + v: 垂直分屏打开
  • Ctrl + t: 在tab页打开

10. 裁剪尾部空格 vim-trailing-whitespace

https://github.com/bronson/vim-trailing-whitespace.git

1
2
" 写入缓冲区前自动裁剪尾部空格
autocmd BufWritePre * FixWhitespace

11. quickfix分屏预览 vim-preview

https://github.com/greyblake/vim-preview.git

配置

1
2
3
4
" 小写p打开预览窗口
autocmd FileType qf nnoremap <silent><buffer> p :PreviewQuickfix<cr>
" 大写P关闭预览窗口
autocmd FileType qf nnoremap <silent><buffer> P :PreviewClose<cr>

12. 代码标签跳转 vim-gutentags和gutentags-plus

https://github.com/ludovicchabant/vim-gutentags
https://github.com/skywind3000/gutentags_plus

ctags/cscope和gtags/gscope的理解

  • ctags是最普通的标签生成跳转工具,生成的tags文件是适配vim的tags功能的,只能跳转定义,不能查找引用
  • cscope是为了查找引用的工具,生成的是cscope.out文件,可以查找定义查找引用
  • gtags是ctags的增强版,可以查找引用查找定义,生成的是三个G开头的文件,增强功能是可以查找引用
  • gscope是cscope的增强版,和gtags搭配,可以使用gtags的三个文件来进行引用查找
  • gscope和cscope最大的区别是,改了工程文件,cscope需要重启来重新加载文件,而gscope和gtags不用,可以增量更新

安装

从官网下载global安装包
https://www.gnu.org/software/global/download.html

1
2
3
4
5
6
7
8
9
10
# 安装依赖库
sudo apt install gcc make libncurses5-dev libncursesw5-dev
# 解压global到/opt目录
tar -xzvf globalxxx.tar.gz
mv globalxxx /opt/global
# 编译安装
cd /opt/global
./configure
make
sudo make install

配置

  • 由于gtags和gscope可以增量更新tags文件,那不用想,肯定用
  • cscope直接弃用
  • ctags不能直接弃用,因为和vim深度匹配,但是gtags可以包含它的功能
  • 那么就只用ctags来生成系统函数的标签,工程目录的标签全部交给gtags和gscope来监管
  • 当前就出现,如果工程内查找,使用vim-gutentags的快捷键
  • 如果需要看系统函数原型,使用ctags的快捷键Ctrl + ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
" gutentags
set rtp+=~/.vim/bundle/vim-gutentags
set cscopetag " use cscope for tags command
set cscopeprg='gtags-cscope' " replace cscope with gtags-cscope
let g:gutentags_auto_add_gtags_cscope=0 " disable gutentags auto add gtags_cscope, use plus plugin to do this
let g:gutentags_define_advanced_commands = 1 " enable gutentags use advanced commands
let g:gutentags_modules=['gtags_cscope'] " enable gtags module
let g:gutentags_project_root = ['.root'] " define project root dir/file name for gutentags
let g:gutentags_add_default_project_roots = 0 " won't add default roots, only use root dir/file user add
" let g:gutentags_ctags_extra_args = ['--fields=+niazS', '--extra=+q', '--c++-kinds=+px', '--c-kinds=+px'] " ctags extra args
let g:gutentags_cache_dir = expand('~/.cache/tags') " put tags out of project

nmap <leader>d yiw:GscopeFind g <C-R>"<cr> :2cc<cr> :cclose<cr>

" gutentags_plus
set rtp+=~/.vim/bundle/gutentags_plus

快捷键

  • <leader>d: 跳转函数定义点
  • <leader>cg: 函数定义地方,输出到quickfix
  • <leader>cs: 符号引用地方,输出到quickfix
  • <leader>cc: 函数调用地方,输出到quickfix
  • <leader>ci: 文件包含地方,输出到quickfix
  • <leader>cf: 文件路径,输出到quickfix

踩坑记

1) gutentags: ctags job failed, returned: 122

  • 查看~/.vim/bundle/vim-gutentags/plat/unix/下的脚本是否都有可执行权限,没有就加一下就好了

13. python格式化 auto-pep8

安装

需要安装autopep8

1
sudo pip install autopep8

14. YCM代码提示插件 YouCompleteMe

从github下载zip包
https://github.com/ycm-core/YouCompleteMe

1
2
3
4
5
6
7
# 安装相关依赖库
sudo apt install cmake libclang-dev
# 编译YCM
cd ~/.vim/bundle/YouCompleteMe
# 四个选项分别对应,使用本地libclang(否则会去下载),c/c++代码提示,js代码提示,go代码提示,根据需求自己删
# 不管选什么一定支持python代码提示,其他还支持java、rust、c#
python install.py --system-libclang --clang-completer --ts-completer --go-completer

Youcompleteme要求vim使用python(3.5.+)编译

配置

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
" YouCompleteMe
set rtp+=~/.vim/bundle/YouCompleteMe
let g:ycm_global_ycm_extra_conf='~/.vim/.ycm_extra_conf.py'
" 跳转快捷键
" nnoremap <c-k> :YcmCompleter GoToDeclaration<CR>|
" nnoremap <c-h> :YcmCompleter GoToDefinition<CR>|
" nnoremap <c-j> :YcmCompleter GoToDefinitionElseDeclaration<CR>|
" 语法关键字补全
let g:ycm_seed_identifiers_with_syntax=1
" 开启 YCM 基于标签引擎
let g:ycm_collect_identifiers_from_tags_files=1
" 在注释输入中也能补全
let g:ycm_complete_in_comments=1
" 在字符串输入中也能补全
let g:ycm_complete_in_strings=1
" 注释和字符串中的文字也会被收入补全
let g:ycm_collect_identifiers_from_comments_and_strings=1
" 禁用语法检查
let g:ycm_show_diagnostics_ui=0
" input two character to trigger complete
let g:ycm_semantic_triggers={ 'c,cpp,python,java,go,erlang,perl,cs,lua,javascript': ['re!\w{2}'] }
" don't show preview window when input complete
" let g:ycm_add_preview_to_completeopt=0
" close preview window when leave iw_nsertmode
" let g:ycm_autoclose_preview_window_after_insertion=1
  • 代码提示需要设定头文件位置,需要配置.ycm_extra_conf.py文件
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
# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-fexceptions',
'-DNDEBUG',
# THIS IS IMPORTANT! Without a "-std=<something>" flag, clang won't know which
# language to use when compiling headers. So it will guess. Badly. So C++
# headers will be compiled as C headers. You don't want that so ALWAYS specify
# a "-std=<something>".
# For a C project, you would set this to something like 'c99' instead of
# 'c++11'.
'-std=c++11',
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x',
'c++',
'-isystem',
'/usr/include/c++/9',
'-isystem',
'/usr/include',
]

15. go插件 vim-go

https://github.com/fatih/vim-go

  • 路径配置好后,需要安装go的几个依赖库
  • 打开一个go文件,执行下面命令
1
:GoInstallBinaries

16. 注释生成插件 DoxygenToolkit.vim

https://github.com/babaybus/DoxygenToolkit.vim.git

17. 全局搜索插件 ack.vim

https://github.com/mileszs/ack.vim.git

  • vimg太慢了,ack调用的是grep命令,比较快

配置

1
2
3
4
5
6
7
8
9
10
" 高亮搜索的文本
let g:ackhighlight = 1
" search current file
nmap <leader>f yiw:Ack!<space>-i<space><C-R>"<space>%
" search all file
nmap <leader>F yiw:Ack!<space>-i<space><C-R>"<space>**/*.*
" search current file
vmap <leader>f y:Ack!<space>-i<space><C-R>"<space>%
" search all file
vmap <leader>F y:Ack!<space>-i<space><C-R>"<space>**/*.*

选项

  • -t TYPE: 搜索某个类型的文件,具体类型代表哪些后缀可以用ack --help-types查看
  • -t noTYPE: 排除某个类型文件
  • -i: 忽略大小写

常用type

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cc           .c .h .xs
hh .h
cpp .cpp .cc .cxx .m .hpp .hh .h .hxx
hpp .hpp .hh .h .hxx
go .go
js .js
json .json
python .py; First line matches /^#!.*\bpython/
html .htm .html .xhtml
make .mk; .mak; makefile; Makefile; Makefile.Debug; Makefile.Release; GNUmakefile
shell .sh .bash .csh .tcsh .ksh .zsh .fish; First line matches /^#!.*\b(?:ba|t?c|k|z|fi)?sh\b/
toml .toml
xml .xml .dtd .xsd .xsl .xslt .ent .wsdl; First line matches /<[?]xml/
yaml .yaml .yml
lua .lua; First line matches /^#!.*\blua(jit)?/

使用

1
2
3
4
5
6
7
8
9
10
" 全局搜索js文件中的user字段,不自动打开文件
:Ack! -i -t js 'USER'
" 在a/b/c目录搜索js文件中的user字段,不自动打开文件
:Ack! -i -t js 'USER' a/b/c
" 在a/b/c和b/c/d目录搜索js文件中的user字段,不自动打开文件
:Ack! -i -t js 'USER' a/b/c b/c/d
" 全局搜索文件中的user字段,只搜索c源文件,不搜索头文件,不自动打开文件
:Ack! -i -t cc -T hh 'USER'
" 全局搜索文件中的user字段,在c代码和js代码中搜索,不自动打开文件
:Ack! -i -t cc -t js 'USER'

18. 状态栏增强插件 vim-airline

https://github.com/vim-airline/vim-airline.git
https://github.com/vim-airline/vim-airline-themes.git

  • 想在状态栏显示git需要安装vim-fugitive

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
" 设置主题
let g:airline_theme='badwolf'
" 统计空格数量,不需要就关了
let g:airline#extensions#whitespace#enabled = 0
" 展示tab栏
let g:airline#extensions#tabline#enabled = 1
" 显示buffer编号
let g:airline#extensions#tabline#buffer_nr_show = 1
" 不显示git分支名,默认显示
let g:airline#extensions#branch#enabled = 0
" 有些字体不支持箭头之类的符号,防止乱码,使用最普通的符号替代
let g:airline_left_sep = '>'
let g:airline_left_alt_sep = '|>'
let g:airline_right_sep = '<'
let g:airline_right_alt_sep = '<|'

19. 代码静态扫描插件 ale

https://github.com/dense-analysis/ale

19.1. 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
" vim-ale
set rtp+=~/.vim/bundle/ale
" 禁用部分ale检查
let g:ale_pattern_options = {
\ '\.min\.js$': {
\ 'ale_enabled': 0,
\ },
\ '\.json$': {
\ 'ale_enabled': 0,
\ },
\}
" 部分语言指定检查lint
let g:ale_linters = {
\ 'python': ['pylint'],
\ 'cpp': ['clangtidy'],
\ 'c': ['clangtidy'],
\}
let g:ale_cpp_clangtidy_extra_options = "--config-file=/home/xxx/.clang-tidy"
let g:ale_c_clangtidy_extra_options = "--config-file=/home/xxx/.clang-tidy"

ale_linters可选

  • c: clangtidy
  • cpp: clangtidy
  • python: pylint

20. 全局搜索插件 CtrlSF

https://github.com/dyng/ctrlsf.vim.git

  • 一款类似sublime的全局搜索插件
  • 默认不使用正则表达式,需要加-R
  • 默认不区分大小写,需要区分加-S
  • 不知道为什么默认不搜索hpp结尾的文件,所以直接使用:CtrlSF xxx **/*.*来搜索所有文件
  • 想要特定后缀文件:CtrlSF xxx **/*.{cpp,h,hpp}

自定义配置

1
2
3
4
5
6
" normal下,对当前单词当前文件搜索和全局搜索
nmap <leader>f yiw:CtrlSF<space><C-R>"<space>%
nmap <leader>F yiw:CtrlSF<space><C-R>"<space>**/*.*
" visual下,对当前选中文本当前文件搜索和全局搜索
vmap <leader>f y:CtrlSF<space><C-R>"<space>%
vmap <leader>F y:CtrlSF<space><C-R>"<space>**/*.*

用法

搜索命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
" 1. Search in a specific sub-directory
:CtrlSF {pattern} /path/to/dir

" 2. Search case-insensitively
:CtrlSF -I foo

" 2. Search case-sensitively
:CtrlSF -S Foo

" 3. Search with regular expression
:CtrlSF -R {regex}

" 4. Show result with specific context setting
:CtrlSF -A 3 -B 1 {pattern}

" 5. Search with specify filetype
:CtrlSF -T {filetype} {pattern}

快捷键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Maps by default in CtrlSF window:
<Enter>, <o>, <2-LeftMouse> Open file which contains the line under cursor.
<C-O> Open file in a horizontally split window.
<p> Open a preview window to view file.
<P> Open a preview window to view file and switch focus to it.
<O> Like <o>, but always leave CtrlSF window open.
<T> Like <t>, but focus CtrlSF window instead of opened new tab.
<q> Quit CtrlSF. Also close preview window if any.
<C-C> Stop running asynchronous searching.
<C-J> Move cursor to next match.
<C-K> Move cursor to previous match.

Maps by default in preview window:
<q> Quit preview mode.

其他命令

  • :CtrlSFToggle: 重新打开上次搜索的窗口
  • :CtrlSFUpdate: 重新搜索当前搜索词
  • :CtrlSFCloseq: 关闭搜索结果窗口
  • :CtrlSFStop: 停止当前搜索

21. 打印函数 echodoc

https://github.com/Shougo/echodoc.vim

配置

1
2
let g:echodoc#enable_at_startup=1
let g:echodoc#type='floating'

22. 显示缩进线 indentLine

  • 使用此插件需要设置下面参数,会导致json文件和markdown文件显示不完全(比如少了双引号)
  • 自己看情况是否需要
1
let g:indentLine_conceallevel = 2

23. 和git交互 vim-fugitive

https://github.com/tpope/vim-fugitive

小技巧和踩坑记

1. 删除键(backspace)不可用

  • vim插入模式下,backspace键没有反应,是因为vim默认的backspace行为为空
  • 配置.vimrc,插入set backspace=indent,eol,start
    • indent 前面有缩进删除到缩进位置
    • eol 行头删除一行
    • start 删除此次插入前的字符

2. vi兼容模式

  • vi兼容模式下编辑模式,上下左右会变成ABCD换行
  • 需要在vimrc里面设置成set nocp不兼容模式

3. 16进制查看编辑

  • 在normal模式输入:!xxd转换到16进制查看编辑
  • 编辑完输入:!xxd -r进行保存