1 Vim的麻烦之处
Vim用了很长一段时间,搭配各种插件、学习VimScript等也逐步积累了一些配置。但随着使用场景重心转移到C/C++项目上,感觉YCM(YouCompleteMe)、ctags(vim-gutentags)等插件有点力不从心,有时跳转不到正确的位置、有时没法提供想要的补全…
网上冲浪搜寻解决方案时看到Martins的这篇文章,顿时觉得豁然开朗,于是又花了一阵子折腾,结果还算比较满意。
2 NeoVim、SpaceVim
让我们一步一步进行升级,首先对于最基本的Vim,配置文件常用位置为~/.vimrc
,当然也可以通过如下方式自定义路径:
# 个人vimrc文件配置路径
export VIMINIT='source $MYVIMRC'
export MYVIMRC=$mypath/.vimrc
Neovim是在Vim的基础上派生出的编辑器,兼容大部分Vim配置,据说在性能等方面和Vim有差异(我是没啥感觉),配置文件通常在~/.config/nvim/init.vim
。如果使用SpaceVim的话,这个文件会有一行内容,我们不需要修改它:
execute 'source' fnamemodify(expand('<sfile>'), ':h').'/main.vim'
如果称Vim和NeoVim为编辑器,那么SpaceVim则更像是IDE,也就是说它默认就捆绑了各种插件、快捷键配置、显示外观等,不用自己再去一个个配置。就像官网描述的:
SpaceVim 是一个社区驱动的模块化的 Vim IDE,以模块的方式组织管理插件以及相关配置, 为不同的语言开发量身定制了相关的开发模块,该模块提供代码自动补全, 语法检查、格式化、调试、REPL 等特性。用户仅需载入相关语言的模块即可得到一个开箱即用的 Vim IDE。
SpaceVim的配置在~/.SpaceVim.d
文件夹中,比较方便建一个git仓库,我的相关文件树如下:
.
├── autoload
│ └── myspacevim.vim
├── init.toml
├── LICENSE
├── plugin
│ ├── coc.vim
│ └── defx.vim
├── Readme.md
└── UltiSnips
├── beancount.snippets
├── cmake.snippets
├── cpp.snippets
├── c.snippets
├── fortran.snippets
├── html.snippets
├── javascript.snippets
└── markdown.snippets
3 ccls、LSP
LSP(Language Server Protocol)即语言服务器协议,微软提出的一个主意,意在让 editor 和 IDE 以后能够使用一个通用的组件来做代码分析。具体可以参考这里,用过Vscode的应该都知道吧,我前一阵子才听说这个词语,真是孤陋寡闻了- -
ccls则是C/C++/ObjC language server
,针对这几个语言提供了相应的自动补全、 查找定义、交叉引用、调用树/成员树/继承树、自动格式化、符号重命名等功能,在NeoVim中的实现为coc-ccls。
4 相关配置
快速了解了相关概念后,重要的是如何根据自己的使用偏好调整配置。首先,需要详细学习SpaceVim使用文档,搞清楚和<Space>
有关的快捷键以及常用插件的使用。如果是一个老Vim用户的话,还需要重点关注如何把之前的好用配置移到SpaceVim中,通常是编辑~/.SpaceVim.d/autoload/myspacevim.vim
文件,利用myspacevim#before()
和myspacevim#after()
函数直接将原配置复制粘贴过来(需要注意两个函数的区别)。
用NAS之后习惯把所有东西只放在局域网中,git仓库也是用自建的Gogs服务而不是GitHub托管,下面还是贴一下自己现在的配置吧(凑凑字数)。
4.1 myspacevim.vim
大部分是我原来的Vim配置,小部分是沿用了Martins3大佬的配置,这里特别强调下airline
部分是我自己调整后的SpaceVim状态栏设置,删去了原版不少自认为多余之处,自己用起来还挺舒服的。
func! myspacevim#before() abort
"有时候在windows下编写的python脚本在linux下不能运行,因为^M的原因,设置格式为unix能够自动清除多余的^M
set fileformat=unix
set showmatch " 高亮显示匹配的括号
"设置标记,三个{定义为标记,可用za折叠展开
set foldenable
set foldmethod=marker
autocmd FileType c,cpp,python set foldmethod=indent nofoldenable
"解决乱码问题
set encoding=utf-8
set termencoding=utf-8
set fileencodings=utf-8,gbk,latin1
set langmenu=zh_CN.UTF-8
set helplang=cn
set ttyfast "a fast terminal connection.
"设置数字为十进制,防止<C-a><C-x>修改时出现不希望的结果
set nrformats=
"依文件类型设置自动缩进
filetype plugin on
filetype indent on
"显示当前的行号(普通模式为相对):
set ruler
set number
set relativenumber
augroup relative_numbser
autocmd!
autocmd InsertEnter * :set norelativenumber
autocmd InsertLeave * :set relativenumber
augroup END
"显示行尾多余空格与tab符号
set listchars=tab:»-,trail:■
set list
"将制表符扩展为空格
set expandtab
"设置编辑时制表符占用空格数
set tabstop=4
"设置格式化时制表符占用空格数
set shiftwidth=4
" 关闭softtabstop 永远不要将空格和tab混合输入
set softtabstop=0
"开启自动缩进
set autoindent " Indent at the same level of the previous line
"开启智能对齐
set smartindent
"设置使用 C/C++ 语言的自动缩进方式
set cindent
"设置命令行的高度
set cmdheight=1
"设置大小写不敏感/当前为大写字母时调整为敏感/自动改动字母大小写
set ignorecase
set smartcase
set infercase
set smarttab " insert tabs on the start of a line according to context
set magic
"单词自动补全功能,写博客时用,自定义词典可参考网上教程
""set dictionary+=/usr/share/dict/american-english
set dictionary+=/usr/share/dict/engspchk-dict
set completeopt+=noinsert
".Md文件也能被识别为markdown
autocmd BufNewFile,BufRead *.Md set filetype=markdown
"ejs识别为html
autocmd BufNewFile,BufRead *.ejs set filetype=html
"Scons相关脚本识别为python
autocmd BufNewFile,BufRead SConstruct set filetype=python
autocmd BufNewFile,BufRead SConscript set filetype=python
" 焦点消失的时候自动保存
au FocusLost * :wa
au FocusGained,BufEnter * :checktime
" 当文件被其他编辑器修改时,自动加载
set autowrite
set autoread
" 重新映射 leader 键
let g:mapleader = ','
" 让 leaderf 可以搜索 git 的 submodule,否则 submodule 的文件会被自动忽略
let g:Lf_RecurseSubmodules = 1
let g:table_mode_corner='|'
" 调节 window 大小
let g:winresizer_start_key = '<space>wa'
" If you cancel and quit window resize mode by `q` (keycode 113)
let g:winresizer_keycode_cancel = 113
" 让file tree 显示文件图标,需要 terminal 安装 nerd font
let g:spacevim_enable_vimfiler_filetypeicon = 1
" 让 filetree 显示 git 的状态
" let g:spacevim_enable_vimfiler_gitstatus = 1
" 默认 markdown preview 在切换到其他的 buffer 或者 vim
" 失去焦点的时候会自动关闭 preview
let g:mkdp_auto_close = 0
" 书签选中之后自动关闭 quickfix window
let g:bookmark_auto_close = 1
" vim-lsp-cxx-highlight 和这个选项存在冲突
" let g:rainbow_active = 1
" 让光标自动进入到popup window 中间
let g:git_messenger_always_into_popup = v:true
" 设置映射规则,和 spacevim 保持一致
call SpaceVim#custom#SPC('nnoremap', ['g', 'm'], 'GitMessenger', 'show commit message in popup window', 1)
call SpaceVim#custom#SPC('nnoremap', ['g', 'l'], 'FloatermNew lazygit', 'open lazygit in floaterm', 1)
" 和 sourcetrail 配合使用
"call SpaceVim#custom#SPC('nnoremap', ['a', 'a'], 'SourcetrailStartServer', 'start sourcetrail server', 1)
"call SpaceVim#custom#SPC('nnoremap', ['a', 'b'], 'SourcetrailActivateToken', 'sync sourcetrail with neovim', 1)
"call SpaceVim#custom#SPC('nnoremap', ['a', 'f'], 'SourcetrailRefresh', 'sourcetrail server', 1)
" 设置默认的pdf阅览工具
let g:vimtex_view_method = 'zathura'
let g:vimtex_syntax_conceal_default = 0
" 关闭所有隐藏设置
let g:tex_conceal = ""
" 实现一键运行各种文件,适合非交互式的,少量的代码,比如 leetcode {{{
func! QuickRun()
exec "w"
let ext = expand("%:e")
let file = expand("%")
if ext ==# "sh"
exec "!bash %"
elseif ext ==# "cpp"
exec "!clang++ % -Wall -g -std=c++17 -o %<.out && ./%<.out"
elseif ext ==# "c"
exec "!clang % -Wall -g -std=c11 -o %<.out && ./%<.out"
elseif ext ==# "java"
let classPath = expand('%:h')
let className = expand('%:p:t:r')
" echo classPath
" echo className
exec "!javac %"
exec "!java -classpath " . classPath . " " . className
elseif ext ==# "go"
exec "!go run %"
elseif ext ==# "js"
exec "!node %"
elseif ext ==# "bin"
exec "!readelf -h %"
elseif ext ==# "py"
exec "!python3 %"
elseif ext ==# "vim"
exec "so %"
elseif ext ==# "html"
exec "!microsoft-edge %"
elseif ext ==# "rs"
call CargoRun()
else
echo "Check file type !"
endif
echo 'done'
endf
"===============================插件配置======================================"
" floaterm - 浮动终端窗口
let g:floaterm_keymap_prev = '<C-p>'
let g:floaterm_keymap_new = '<C-n>'
let g:floaterm_keymap_toggle = '<F5>'
"gutentags配置,由于依靠compile_command.json总是跳转到安装目录,不方便编辑源文件,还是用ctags吧
" gutentags 搜索工程目录的标志,碰到这些文件/目录名就停止向上一级目录递归
let g:gutentags_modules = ['ctags']
let g:gutentags_project_root = ['.root', '.svn', '.git', '.hg', '.project']
let g:gutentags_ctags_exclude=['.ccls-cache','build','install']
" 所生成的数据文件的名称
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=+px']
let g:gutentags_ctags_extra_args += ['--c-kinds=+px']
" airline代替statusline,部分配置在bootsrap_after
call SpaceVim#layers#disable('core#statusline')
call SpaceVim#layers#disable('core#tabline')
" 关闭最右边栏
let g:airline#extensions#whitespace#enabled = 0
" 不显示git分支
let g:airline#extensions#branch#enabled = 0
" 去掉section B和X
let g:airline_section_b = ''
"let g:airline_section_x = ''
let g:airline_section_x = '%-0.25{getcwd()}'
endf
func! myspacevim#after() abort
"一般关闭paste模式,该模式下有的map会出问题
set nopaste
"不自动分行(但可以分行显示)
set wrap
set textwidth=0
" Search mappings: These will make it so that going to the next one in a
" search will center on the line it's found in.
nnoremap n nzzzv
nnoremap N Nzzzv
"Ctrl+Space单词补全"
"WSL系统中此快捷键不管用,故换成下面一条
"inoremap <C-@> <C-x><C-k>
inoremap <C-f> <C-x><C-k>
"保存文件
nnoremap <Leader>w :w<CR>
"选择全文
noremap <M-a> <Esc>ggVG<CR>
"退出
nnoremap qw :wq<CR>
nnoremap qq :q!<CR>
"插入模式下移动光标
inoremap <C-k> <Up>
inoremap <C-h> <Left>
inoremap <C-l> <Right>
inoremap <C-j> <Down>
"向后删除 *为向前删除,shell通用
inoremap <C-d> <Delete>
"超级用户权限编辑,出现权限不够无法保存时命令模式输入sw即可
cnoremap sw w !sudo tee >/dev/null %
"可视模式下用*和#查找选中文本
xnoremap * :<C-u>call <SID>VsetSearch()<CR>/<C-R>=@/<CR><CR>
xnoremap # :<C-u>call <SID>VsetSearch()<CR>?<C-R>=@/<CR><CR>
function! s:VsetSearch()
let temp=@s
norm! gv"sy
let @/ = '\V' . substitute(escape(@s, '/\'), '\n', '\\n','g')
let @s= temp
endfunction
"" Switching windows
noremap <C-j> <C-w>j
noremap <C-k> <C-w>k
noremap <C-l> <C-w>l
noremap <C-h> <C-w>h
"" Move visual block
vnoremap K :m '<-2<CR>gv=gv
vnoremap J :m '>+1<CR>gv=gv
"关闭高亮直到下一次查找
cnoremap hl nohlsearch<CR>
" <F3> 打开文件树
let g:vista_sidebar_position = "vertical topleft"
let g:vista_default_executive = 'coc'
let g:vista_finder_alternative_executives = 'ctags'
nnoremap <F2> :Vista!!<CR>
nnoremap <F4> :call QuickRun()<CR>
" <F5> floaterm toggle
" <F7> 打开历史记录
tnoremap <Esc> <C-\><C-n>
" 窗口间切换
"map <Tab> :wincmd w<CR>
" coc-smartf配置,press <esc> to cancel.
nmap f <Plug>(coc-smartf-forward)
nmap F <Plug>(coc-smartf-backward)
nmap ; <Plug>(coc-smartf-repeat)
nmap , <Plug>(coc-smartf-repeat-opposite)
augroup Smartf
autocmd User SmartfEnter :hi Conceal ctermfg=220 guifg=pink
autocmd User SmartfLeave :hi Conceal ctermfg=239 guifg=#504945
augroup end
"目录栏设置相对行号
autocmd FileType defx setlocal relativenumber
"同时显示git信息和line number
set signcolumn=yes
"===============================插件配置======================================"
" vim-beanCount
"path to your root beancount file
let b:beancount_root= '~/Desktop/repositories/beanCount_zcp/zcp.bean'
" default or chunks
let g:beancount_account_completion= 'default'
let g:beancount_separator_col= 10
" If non-zero, accounts higher down the hierarchy will be listed first as completions.
let g:beancount_detailed_first = 1
autocmd Filetype beancount inoremap . .<C-\><C-O>:AlignCommodity<CR>
autocmd Filetype beancount inoremap <C-o> <C-x><C-O>
" vim-airline
" 去掉LN显示
let g:airline_symbols.linenr= ''
" 加入Window编号
function! WindowNumber(...)
let builder = a:1
let context = a:2
call builder.add_section('airline_b', '%{tabpagewinnr(tabpagenr())}')
return 0
endfunction
call airline#add_statusline_func('WindowNumber')
call airline#add_inactive_statusline_func('WindowNumber')
" 用airline时`SPC num`跳转窗口失效,重新映射
noremap <Space>1 1<C-w>w
noremap <Space>2 2<C-w>w
noremap <Space>3 3<C-w>w
noremap <Space>4 4<C-w>w
endf
4.2 init.toml
SpaceVim的默认配置文件,文法和.vimrc
不一样。这里禁用了statusline
改为使用airline
,同时增加了以前Vim中经常用的插件
#=============================================================================
# Copyright (c) 2021-20xx
# Author: zcp
# License: GPLv3
#=============================================================================
# All SpaceVim option below [option] section
[options]
# 设置 SpaceVim 主题及背景,默认的主题是 gruvbox,如果你需要使用更
# 多的主题,你可以载入 colorscheme 模块
colorscheme = "gruvbox"
# colorscheme = "OceaniwcNext"
colorscheme_bg = "dark"
# colorscheme = "NeoSolarized"
# colorscheme_bg = "light"
# 背景可以取值 "dark" 和 "light"
# 启用/禁用终端真色,在目前大多数终端下都是支持真色的,当然也有
# 一小部分终端不支持真色,如果你的 SpaceVim 颜色看上去比较怪异
# 可以禁用终端真色,将下面的值设为 false
enable_guicolors = true
# statusline设置,启用时才有效
# 设置状态栏上分割符号形状,如果字体安装失败,可以将值设为 "nil" 以
# 禁用分割符号,默认为箭头 "arrow"
statusline_separator = "nil"
# statusline_separator = "bar"
# 设置顶部标签列表序号类型,有以下五种类型,分别是 0 - 4
buffer_index_type = 4
# 0: 1 ➛ ➊
# 1: 1 ➛ ➀
# 2: 1 ➛ ⓵
# 3: 1 ➛ ¹
# 4: 1 ➛
# 显示/隐藏顶部标签栏上文件类型图标,这一图标需要安装 nerd fonts,
# 如果未能成功安装这一字体,可以隐藏图标
enable_tabline_filetype_icon = true
# 是否在状态栏上显示当前模式,默认情况下,不显示 Normal/Insert 等
# 字样,只以颜色区分当前模式
enable_statusline_display_mode = false
statusline_left_sections = [
'winnr',
'filename',
'major mode',
'fileformat',
'minor mode lighters',
'version control info',
]
statusline_right_sections = [
'cursorpos',
'percentage',
'date',
'time',
]
#######################################################################
# MY OWN OPTIONS
filemanager = "defx"
autocomplete_method = "coc"
#snippet_engine = "ultisnips"
# 启动函数名称,该函数中可以使用Vim Script
# 启动函数文件位置:~/.SpaceVim.d/autoload/myspacevim.vim
# 函数 bootstrap_before 将在读取用户配置后执行,而函数 bootstrap_after 将在 VimEnter autocmd 之后执行。
bootstrap_before = "myspacevim#before"
bootstrap_after = "myspacevim#after"
# Vim兼容
# vimcompatible = true
# Vim兼容:Normal模式窗口快捷键的前缀改为X,s作为删除字符
windows_leader = 'X'
# Vim兼容:语言专用的前缀键,f、F、t、T改为搜索
enable_language_specific_leader = false
# Vim兼容:智能关闭窗口q改为录制宏
windows_smartclose = ''
# ----------------- SpaceVim 添加的各种 layers ---------------------------------
# 强化`/`搜索显示
[[layers]]
name = "incsearch"
# 计算器, 日历, 书签等小工具
[[layers]]
name = 'tools'
# 禁用 SpaceVim 的 checkers layer, 让 coc.nvim 来管理
[[layers]]
name = "checkers"
enable = false
# 版本控制
[[layers]]
name = "VersionControl"
enable-gtm-status = false
[[layers]]
name = "git"
git-plugin = "fugitive"
[[layers]]
name = "fzf"
[[layers]]
name = "lang#markdown"
[[layers]]
name = "lang#latex"
[[layers]]
name = "lang#c"
enable_clang_syntax_highlight = true
[[layers]]
name = "lang#python"
[[layers]]
name = "lang#toml"
[[layers]]
name = "lang#vim"
[[layers]]
name = "lang#sh"
[[layers]]
name = "format"
# ----------------- 添加的插件 -------------------------------------------------
# oceanic-next 主题,采用其他的主题可以删除
[[custom_plugins]]
name = "mhartington/oceanic-next"
merged = 0
# coc.nvim 核心配置,不要删除
# ~/.cache/vimfiles/repos/github.com/neoclide/coc.nvim
[[custom_plugins]]
name = 'neoclide/coc.nvim'
merge = 0
# 优化 coc 的搜索界面
[[custom_plugins]]
name = 'antoinemadec/coc-fzf'
branch = 'release'
[[custom_plugins]]
name = 'junegunn/fzf.vim'
# 快速搜索文件和 buffer
[[custom_plugins]]
name = "Yggdroot/LeaderF"
build = "./install.sh"
# 快速编辑 markdown 的表格
[[custom_plugins]]
name = 'dhruvasagar/vim-table-mode'
# 更加美观的 tagbar
[[custom_plugins]]
name = 'liuchengxu/vista.vim'
# 更加方便的调节窗口的大小
[[custom_plugins]]
name = 'simeji/winresizer'
# 为 c/cpp 提供基于 lsp 的高亮
[[custom_plugins]]
name = 'jackguo380/vim-lsp-cxx-highlight'
# 从 http://cplusplus.com/ 和 http://cppreference.com/ 获取文档
[[custom_plugins]]
name = 'skywind3000/vim-cppman'
# 利用 git blame 显示当前行的 commit message
[[custom_plugins]]
name = 'rhysd/git-messenger.vim'
lazy = 1
on_cmd = 'GitMessenger'
# 以悬浮窗口的形式打开终端
[[custom_plugins]]
name = 'voldikss/vim-floaterm'
# 显示搜索的标号
[[custom_plugins]]
name = 'google/vim-searchindex.git'
# 记账
[[custom_plugins]]
name = 'jonsmithers/vim-beancount'
# 常用snippets
[[custom_plugins]]
name = 'honza/vim-snippets'
# 用于高效操作与括号、引号或html、xml标签相关的配对符号(surrounding)
[[custom_plugins]]
name = 'tpope/vim-surround'
[[custom_plugins]]
name = 'tpope/vim-repeat'
# 文本对象
[[custom_plugins]]
name = 'kana/vim-textobj-user'
[[custom_plugins]]
name = 'kana/vim-textobj-indent'
[[custom_plugins]]
name = 'kana/vim-textobj-syntax'
[[custom_plugins]]
name = 'kana/vim-textobj-function'
[[custom_plugins]]
name = 'sgur/vim-textobj-parameter'
# ctags
[[custom_plugins]]
name = 'ludovicchabant/vim-gutentags'
5 总结
文中未提相关安装方式,是因为这篇文章已经很详细了,我就是照着它入门的;而SpaceVim、NeoVim具体的使用方式官方文档也已经说的很清楚了,下面就简单写下我自己的使用备忘录吧:
几个需要知道的概念:
| --------- | ------------------------------------------------- | | Window | A window can split into more windows | | Buffer | A buffer is a file loaded into memory for editing | | Tab/Frame | A tab could contain different file | | Tagbar | Display tags of current file | | Filetree | File browser |
卸载并回滚到原vim:
curl -sLf https://spacevim.org/install.sh | bash -s -- --uninstall
同时使用原有的vim和spacevim FAQ:Have a try with SpaceVim without overwrite vimrc?
探索快捷键的最好方式是在spacevim中按下空格键等待一秒,它会弹出有用的提示框, 亲自尝试其中的快捷键才能更加准确知道它的效果。
[SPC]
:表示空格键;[WIN]
,窗口操作,默认s(我改为了X)spc f t
:open filetreespc b b
:打开缓冲区管理页面,spc b d
关闭当前缓冲区g
| go to |g 0
| 跳到第一个tab | linkz
| fold |z a
| 触发代码折叠 | link按一下空格键,等待1秒,可以看到有用的提示信息
F2
| Open tagbarspc p /
| 模糊查找spc f o
| open file tree and locate to current directorywin g
(spc w /
) | open file and split window horizontallywin v
(spc w -
) | open file split window vertically注释代码(取消注释重复即可) | Link
|spc c l
| comment/uncomment current line
|spc c p/P
| comment/uncomment current paragraph
|spc ; [num] j
| comment num lines页面Tab管理器 | Link
|spc t t
| open tab manager
|spc w F
| open a new tab, equal tospc t t + n
|spc w o
| switch tab
|spc s c
| clear search highlight搜索 | Link
|spc s s
| Searching in current file
|spc s d
| Searching in current directory
|spc s b
| Searching in all loaded buffers
|spc s p
| Searching in current proj, equal tospc /
编程相关
|g d
| Go to function definition
|spc b f
| format code according to pep8 standard
|spc l g d
| generate docstringgit使用
|spc g s
| 查看git状态
|spc g A
| 添加所有文件
|spc g c
| commit messages,保存即提交
|spc g p
| pushspc t w
| 行尾空格检查<Leader>
y | 复制文本至系统剪切板spc s c
或者运行命令:nohlsearch
来取消搜索结果的高亮表示书签跳转(需要启用tools)
|m a
| 显示书签列表
|m c
| 清除所有书签
|m m
| 切换当前行标签状态
|m n
| 跳至下一个书签
|m p
| 跳至前一个书签
|m i
| 给当前行标签添加说明UltiSnips插件配置,
<C-l>
展开,<C-j>
下一个,<C-k>
上一个coc.nvim学习
|[g
,]g
| 跳转到coc各个诊断处
|gd
| 跳转到定义处
|gy
| 跳转到type-definition
|gi
| 跳转到implementation
|gr
| 跳转到references-used
|<Leader>rn
| 重命名变量
|<Leader>d
| 打开诊断窗口
|<Leader>o
| 查看文件outlinevim-table-mode使用:
<Leader>tm
开启table模式,输入|
开始制表,文字与|
要有空格,回车后||
会自动插入行,第一行作为标题