SpaceVim使用教程

SpaceVim使用教程

SpaceVim是一个模块化的Vim/Neovim配置集合,可以快速配置一个较为好用的vim环境。

推荐刚使用vim的新手使用SpaceVim提供的环境,而有能力自己配置vim的使用自己的vim环境。我并不认为SpaceVim是一个很好的vim配置,因为有很多细节你并不了解,你并不能很好地使用它,而且虽然官方的文档看起来比较全,但是文档内容的质量并不是很高,有很多误导的地方,可能要踩不少坑。至少作为一个基本的vim环境,SpaceVim是提供了,可以借鉴之以搭建自己个性化的vim环境。

SpaceVim的github地址 SpaceVim官方中文文档 SpaceVim可用模块

入门指南

这里只讲在Linux使用SpaceVim,而且vim最好在Linux环境下使用。

详细的文档请参考:SpaceVim使用文档

SpaceVim安装

安装SpaceVim之前,请先检查一些配置:

  1. git版本
    git --version,确定git已正确安装
  2. python版本
    python -Vpython2 -Vpython3 -V,检查python安装情况,推荐python3
  3. vim或neovim
    vimnvim,确保能够打开,推荐使用nvim.appimage

默认同时为vim和neovim安装SpaceVim:

curl -sLf https://spacevim.org/cn/install.sh | bash

只为vim或者neovim单独安装SpaceVim:

curl -sLf https://spacevim.org/cn/install.sh | bash -s -- --install vim
curl -sLf https://spacevim.org/cn/install.sh | bash -s -- --install neovim

卸载SpaceVim:

curl -sLf https://spacevim.org/cn/install.sh | bash -s -- --uninstall

你可以用wget下载安装脚本,然后在终端运行,我推荐使用neovim,只为nvim安装就行了。

SpaceVim快捷键

有关vim的快捷键请自行学习,这里仅可能会列出部分vim快捷键。

  • <C-[a-z]>: Ctrl开头的组合键
  • <A-[a-z]>: Alt开头的组合键
  • <S-[a-z]>: Shift开头的组合键,代替输入大写字母键
快捷键 功能描述
SPC 空格键,SpaceVim默认前缀键
Window 默认是's',SpaceVim默认窗口前缀键
Leader 默认是'\',Vim/Neovim默认前缀键
g 附加命令前缀键
z 附加命令前缀键
<F2> 打开关闭符号表Tagbar
<F3> 打开关闭文件树Nerdtree
<F7> 打开关闭撤销树
Leader y 复制已选中的文本至系统剪切板
Leader p 粘贴系统剪切板文字至当前位置之后
Leader <S-p> 粘贴系统剪切板文字至当前位置之前
Nerdtree: jk Nerdtree中上下移动光标
Nerdtree: lh Nerdtree中打开文件(夹)或移至父目录并关闭
Nerdtree: <CR> Nerdtree中,切换目录或打开文件
Nerdtree: N Nerdtree中在光标位置新建文件
Nerdtree: r Nerdtree中刷新文件树结点
Nerdtree: . 切换显示隐藏文件
Ex: <C-a> 命令行模式下,移动光标至行首
TabManager: q 关闭tab管理器
TabManager: o 切换tab页
TabManager: r 重命名tab页
TabManager: n 新建有名tab页
TabManager: x 删除tab页
TabManager: yy 复制tab页
TabManager: p 粘贴tab页
SPC tt 打开tab管理器
SPC sc 取消搜索结果的高亮显示
SPC t<S-w> 切换折行显示
SPC t8 高亮所有超过80列的字符
SPC xgt 使用谷歌翻译当前单词
SPC n+SPC n- 光标下数字自增或自减并进入快捷状态
SPC ; 进入注释操作模式,可使用动作
SPC cl 注释/反注释当前行
SPC cs 使用完美格式注释
SPC [1-9] 跳至指定序号的窗口
Leader [1-9] 跳至指定序号的tab页
g r 跳至前一个tab页
Window v 水平分屏
Window g 垂直分屏
Window t 新建tab页
Window o 关闭其他窗口
Window q 关闭当前缓冲区,可用于关闭tab页
Ctrl-<方向键> 按方向切换窗口
SPC wd 删除一个窗口
SPC w. 启用窗口临时快捷键,方便调整窗口
SPC <Tab> 两切换至前一缓冲区
SPC b. 启用缓冲区临时快捷键,方便操作缓冲区
SPC bb 通过模糊搜索工具进行缓冲区切换
SPC bd 删除当前缓冲区,但保留编辑窗口
SPC bc 删除其它已保存的缓冲区
SPC bp 切换至前一个缓冲区,排除特殊插件的缓冲区
SPC bR 从磁盘重新读取当前缓冲区所对应的文件
SPC bY 将整个缓冲区复制到系统剪切板
SPC bN 新建空白缓冲区
Leader f 模糊搜索快捷键
SPC s/ 在工程中使用默认工具实时检索代码
SPC pf 在当前工程中查找文件
SPC p/ 在当前工程中搜索文本内容
SPC ff 在当前文件所在文件夹搜索文件
SPC fR 重命名当前文件
SPC as 打开启动界面
SPC fvd 打开SpaceVim的用户配置文件
SPC hl 显示所有模块
SPC h 帮助信息快捷键
SPC Tn 切换至下一个随机主题,需要载入主题模块
SPC qq 快速关闭vim/nvim

tab页的管理推荐使用TabManager,快捷键SPC tt打开。
注意:SpaceVim2.0-dev的tab页管理有bug.
关闭tab页的快捷键是"SPC qt",但是可能有问题,vim命令是":tabc"

C/C++的配置

可以查阅官方文档,但并不全: 使用Vim搭建C/C++开发环境

配置文件是"~/.SpaceVim.d/init.toml",快捷键SPC fvd打开此文件。

注意:"SPC"键是空格键,"Leader"键是'\'键。

请先安装libclang和clang-format以提供语法高亮和代码格式化。

C/C++模块

1
2
3
4
# 开启clang模式高亮
[[layers]]
name = "lang#c"
enable_clang_syntax_highlight = true

语言快捷键以"SPC l"为前缀,基础语法高亮基于正则表达式,上述开启了clang模式高亮,这一功能需要vim/neovim支持python并且安装了libclang.

自动补全

1
2
3
4
5
6
7
8
9
10
[[layers]]
name = "lsp"
enabled_clients = ['clangd']
filetypes = [
"c",
"cpp"
]
[layers.override_cmd]
c = ["clangd"]
cpp = ["clangd"]

自动补全由autocomplete模块提供,配合lsp模块并开启语言服务器以提供较好的补全。

clangd是SpaceVim默认的C/C++语言服务器,请下载github的clangd并在Linux终端解压,把可执行文件的目录加入PATH路径,确保可以直接执行clangd命令。

注意:在wsl里面PATH路径设置请在windows系统环境变量里面添加。

代码格式化

启用format模块就行了,快捷键"SPC bf",异步执行clang-format命令。

1
2
[[layers]]
name = "format"

Java的配置

可以查阅官方文档,但并不全: 使用Vim搭建Java开发环境

Java模块

1
2
3
4
[[layers]]
name = "lang#java"
# 使用谷歌java代码格式化并采用AOSP样式(4空格缩进)
java_formatter_jar = "~/.SpaceVim.d/google-java-format-1.15.0-all-deps.jar --aosp"

同样,语言专有的快捷键以"SPC l"为前缀。

自动补全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[[layers]]
name = "lsp"
filetypes = [
"java"
]
[layers.override_cmd]
# Java的语言服务器采用eclipse.jdt.ls
java = [
"java",
"-Declipse.application=org.eclipse.jdt.ls.core.id1",
"-Dosgi.bundles.defaultStartLevel=4",
"-Declipse.product=org.eclipse.jdt.ls.core.product",
"-Dlog.protocol=true",
"-Dlog.level=NONE",
"-noverify",
"-Xmx1G",
"-jar",
"~/.SpaceVim.d/javalsp/plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar",
"-configuration",
"~/.SpaceVim.d/javalsp/config_linux",
"-data",
"~/.SpaceVim.d/javalsp/.cache/javalsp"
]

java的自动补全同样是lsp模块提供语言服务支持,这需要下载eclipse.jdt.ls.

请将下载的压缩包解压到"~/.SpaceVim.d/javalsp",并新建"~/.SpaceVim.d/javalsp/.cache/javalsp"文件夹。上述路径配置请自行检查。

代码格式化

下载google-java-format

配置详见Java模块,快捷键同样是"SPC bf".

交叉索引工具使用

交叉索引是阅读代码的利器,通常代码有许多交叉引用,阅读需要在代码中间跳来跳去。常用的交叉索引工具有ctags和cscope,但是这两个都不在更新维护了。我建议使用universal-ctags代替ctags,使用global代替cscope,这些是目前还在维护的工具。

使用快捷键F2可以打开Tagbar窗口以浏览符号索引。

ctags

这里只讲universal-ctags,推荐从源码编译并安装。ctags只是简单的tags工具,并没有交叉索引功能,这个工具支持大多数语言,可以建立工程的符号索引,用于Tagbar工具(一个vim插件)。

先安装一些工具:sudo apt install autoconf automake pkg-config

安装universal-ctags到用户目录:

1
2
3
4
5
6
git clone https://github.com/universal-ctags/ctags.git
cd ctags
./autogen.sh
./configure --prefix=$HOME/.local
make
make install

注意:git命令运行需要ssl验证,可能要绕过ssl,在bashrc文件中加入一行"export GIT_SSL_NO_VERIFY=1"即可。

在ubuntu系统中,可以使用checkinstall工具(apt安装)进行打包,将最后一个命令"make install"替换为"checkinstall"并根据提示操作即可。

ctags的详细使用请自行阅读相关文档,这里只是用作Tagbar建立索引的工具。请确保可以在命令行正常运行"ctags --help"命令。

mdctags

mdctags的github地址

mdctags是markdown的索引工具,因为ctags不支持md文件,其安装如下:

1
2
3
4
git clone https://github.com/wsdjeg/mdctags.rs.git
cd ./mdctags.rs
cargo build --release
cp ./target/release/mdctags ~/.local/bin/

编译需要cargo软件包(用apt安装即可)。

配置mdctags以使Tagbar支持md文件,在Tagbar加载之前执行以下脚本:

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
let g:tagbar_type_markdown = {
\ 'ctagsbin' : 'mdctags',
\ 'ctagsargs' : '',
\ 'kinds' : [
\ 'a:h1:0:0',
\ 'b:h2:0:0',
\ 'c:h3:0:0',
\ 'd:h4:0:0',
\ 'e:h5:0:0',
\ 'f:h6:0:0',
\ ],
\ 'sro' : '::',
\ 'kind2scope' : {
\ 'a' : 'h1',
\ 'b' : 'h2',
\ 'c' : 'h3',
\ 'd' : 'h4',
\ 'e' : 'h5',
\ 'f' : 'h6',
\ },
\ 'scope2kind' : {
\ 'h1' : 'a',
\ 'h2' : 'b',
\ 'h3' : 'c',
\ 'h4' : 'd',
\ 'h5' : 'e',
\ 'h6' : 'f',
\}
\}

对于SpaceVim来说,只要在myspacevim.vim文件的myspacevim#before()函数中,插入上述代码即可。

global

GNU Global是一个源代码交叉索引工具,用于替代cscope,并可以支持常见的主流语言。

编译global

安装global之前,先安装ctags,可以安装pygments以支持更多语言:

pip install --user pygments

首先下载GNU Global源码, 命令如下:

1
2
3
4
5
6
wget https://ftp.gnu.org/pub/gnu/global/global-6.6.8.tar.gz
tar -xvzf global-6.6.8.tar.gz
cd global-6.6.8
./configure --with-universal-ctags=$HOME/.local/bin/ctags --prefix=$HOME/.local
make
make install

配置global与SpaceVim

需要进行一些配置:

"~/.bashrc"中添加:

1
2
export GTAGSLABEL=native-pygments
export GTAGSCONF=${HOME}/.local/share/gtags/gtags.conf

在SpaceVim的配置文件init.toml中添加:

1
2
3
[[layers]]
name = "gtags"
gtagslabel = "native-pygments"

global本身支持6种语言,通过ctags做后端可以支持大部分语言,而通过pygments可以支持更多的语言,推荐使用pygments以提供global原生支持以外的解析。

在SpaceVim中使用global

确保你能在命令行运行"global --help"命令,并正确配置global.

快捷键 说明
SPC mgc 创建当前项目的gtags数据库
SPC mgd 查询光标处符号的定义
SPC mgr 查询光标处符号的引用
SPC mgg 查询光标处文字
SPC mgs 查询光标处符号
SPC mgu 更新gtags数据库

注意:你的项目应该被SpaceVim识别,即SpaceVim能找到项目的根目录。

project_rooter_patterns = [".git/", "_darcs/", ".hg/", ".bzr/", ".svn/", ".root"]

上述,配置在init.toml的"[options]"里面,定义了项目根目录下应该有的文件夹(以'/'字符结尾)或文件(没有'/'字符),确保项目根目录有上述之一。

init.toml的配置

安装了SpaceVim之后,打开vim/nvim,会要求你选择界面,有两种:

  • basic mode: 基础模式,几乎所有的终端都可以使用。
  • power mode: 高级模式,需要终端支持真彩色且安装终端字体

推荐的终端字体是:SaurceCodePro Nerd Font Mono

如果字体显示错误,可以使用其他字体,比如:"Ubuntu Mono"

vim兼容模式

推荐设置按键与vim兼容,并启用vim脚本:

[options]
# 启用vim兼容模式
# vimcompatible = true

# 设定与vim兼容的按键
# 连续按两个按键即可
windows_leader = "=s"
windows_smartclose = "=q"
# 关闭语言专有快捷键的特殊前缀,但还是可以用"SPC l"
enable_language_specific_leader = false

# 启用vim脚本
bootstrap_before = "myspacevim#before"
bootstrap_after = "myspacevim#after"

为了使用SpaceVim的[Window]前缀键,不能设置vimcompatible=true.

加入其他插件

可以禁用内置插件,例如:

1
2
3
[options]
# 禁用此插件,因为编译此插件比较麻烦
disabled_plugins = ["markdown-preview.nvim"]

可以加入其他vim插件,例如:

1
2
3
4
# 使用vim版的markdown预览插件
[[custom_plugins]]
repo = "iamcco/markdown-preview.vim"
merged = false

有些模块是默认启用的,可以禁用某些模块,例如:

1
2
3
[[layers]]
name = "shell"
enable = false

详细的模块配置可参考:可用模块

模糊搜索

模糊搜索模块有:denite, unite, leaderf, ctrlp, fzf.
详细查阅:模糊搜索

启用模糊搜索,在init.toml中添加:

1
2
3
# 模糊搜索工具
[[layers]]
name = "denite"

myspacevim.vim的配置

SpaceVim提供了两种启动函数:bootstrap_beforebootstrap_after.在"~/.SpaceVim.d/autoload"里面存放vim脚本即可,例如"myspacevim.vim"文件。

这个脚本和vimrc的配置是一样的,只是所有配置都在两个函数里进行。

  • myspacevim#before()
    在载入用户配置时执行,即SpaceVim各模块初始化之前执行
  • myspacevim#after()
    在触发vimEnter事件时执行,即SpaceVim初始化之后执行

基本配置

在myspacevim#after()函数里面添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"   关闭按键延迟显示
set timeoutlen=200
" 命令模式下显示键入的指令
set showcmd
" 自动折行
set wrap
" 折行在指定符号处,不会在单词内部折行
set linebreak
" 设定tab键的显示方式和行末的空格显示方式
set listchars=tab:>-,trail:·
set list

" 方便光标在中文字符移动
nnoremap <A-l> 5l
nnoremap <A-h> 5h
nnoremap <A-j> 5j
nnoremap <A-k> 5k
" 定义输入tab键的方式
inoremap <A-t> <CR>a<Esc>d0:s/a/\t/<CR>:noh<CR>i<Left><Backspace><Right>

mdformat功能

借由pandoc来实现markdown文件的格式化,在vim脚本中加入函数:

1
2
3
4
5
6
7
8
9
function! myspacevim#mdformat() abort
" let l:cur = getcurpos()
write! ++enc=utf-8 ~/md.cache
silent !pandoc -f gfm -t gfm ~/md.cache -o ~/md.cache
normal ggdG
read ++enc=utf-8 ~/md.cache
silent !rm ~/md.cache
" call cursor(l:cur)
endfunction

在myspacevim#after()函数里面,定义快捷键"Leader mf"以方便md格式化:

call SpaceVim#mapping#def('nnoremap', '<Leader>mf', ':call myspacevim#mdformat()<cr>', '', '', 'markdown format')

中文翻译及输入法的配置

chinese模块

启用SpaceVim的chinese模块即可,在init.toml中添加:

1
2
3
# 启用中文翻译和vim中文文档
[[layers]]
name = "chinese"

vim的中文文档,输入命令":help@cn"即可打开。

中文翻译需要配置一下快捷键,在myspacevim.vim的myspacevim#after()中添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"   中文翻译插件快捷键
call SpaceVim#mapping#def('nnoremap', '<Leader>tc', ':Translate<cr>',
\ '', '', 'Translate in cmdline')
call SpaceVim#mapping#def('vnoremap', '<Leader>tc', ':Translate<cr>',
\ '', '', 'Translate in cmdline')
call SpaceVim#mapping#def('nnoremap', '<Leader>tw', ':TranslateW<cr>',
\ '', '', 'Translate in popwindow')
call SpaceVim#mapping#def('vnoremap', '<Leader>tw', ':TranslateW<cr>',
\ '', '', 'Translate in popwindow')
call SpaceVim#mapping#def('nnoremap', '<Leader>tr', 'viw:<c-u>TranslateR<cr>',
\ '', '', 'Translate and replace')
call SpaceVim#mapping#def('vnoremap', '<Leader>tr', ':TranslateR<cr>',
\ '', '', 'Translate and replace')
call SpaceVim#mapping#def('nnoremap', '<Leader>tx', ':TranslateX<cr>',
\ '', '', 'Translate content in clipboard')
call SpaceVim#mapping#def('nnoremap', '<Leader>te', ':TranslateW --target_lang=en<cr>',
\ '', '', 'Translate to English with popwindow')
call SpaceVim#mapping#def('nnoremap', '<Leader>tz', 'viw:<c-u>TranslateR --target_lang=en<cr>',
\ '', '', 'Translate to English and replace')

fcitx模块

如果你使用的输入法是fcitx,那么SpaceVim默认启用fcitx模块,但是会报错:
fcitx.vim: socket /tmp/fcitx=socket error: [Error 2 ] No such file or directory

这是因为fcitx.vim不知道你的fcitx-socket文件路径,只要在bashrc文件中添加:
export FCITX_SOCKET=/tmp/fcitx-socket-:0

然后重启系统就可以解决此问题。

如果使用的输入法是fcitx5,那么SpaceVim不会启用fcitx模块,我认为这算一个bug,fcitx.vim模块是支持fcitx5的,但是在配置文件'.SpaceVim/autoload/SpaceVim/layers/edit.vim'中可以看到有一个if executable('fcitx')的判断。

fcitx.vim模块在fcitx输入法下使用python实现(需要建立socket),而在fcitx5输入法下只能使用fcitx5-remote实现。

要使fcitx5在vim中可以自动切换,可以在myspacevim.vim中添加两个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function! myspacevim#Fcitx2en() abort
if system('fcitx5-remote') == 2
let b:inputtoggle = 1
call system('fcitx5-remote -c')
endif
endfunction
function! myspacevim#Fcitx2zh() abort
try
if b:inputtoggle == 1
call system('fcitx5-remote -o')
let b:inputtoggle = 0
endif
catch /inputtoggle/
let b:inputtoggle = 0
endtry
endfunction

然后,在myspacevim.vim的myspacevim#after()中添加:

1
2
3
4
5
6
if !(executable('fcitx')) && executable('fcitx5-remote')
" 退出插入模式时禁用输入法
autocmd InsertLeave * call myspacevim#Fcitx2en()
" 进入插入模式时启用输入法
autocmd InsertEnter * call myspacevim#Fcitx2zh()
endif

使用此模块是因为在vim里面切换中英文输入状态比较麻烦,此模块可以自动帮助你切换,从插入模式回到普通模式会自动切换到无输入法状态,进入插入模式会切换到上次的状态。

但是此模块只能在图形界面上使用,因此,使用qterminal运行一个终端以打开vim/nvim才能使用此模块,推荐在"~/.bashrc"文件中添加一行:alias vi='qterminal -e nvim'

然后创建"~/.local/bin/qterminal",内容如下:

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
#!/bin/bash

# qterminal -e args...
# to fixed the escape space character bug, this script was writen.

# qterminal -E args...
# support escape characters to run command.

# fixed this bug with space-replace of $'\x1' as $'\x20'

if [ "`echo -n qterminal $* | egrep -w "\-e|\-\-execute"`" ]; then
unset opts args
args=("$@")
i=0
until [ "${args[$i]}" = "-e" -o "${args[$i]}" = "--execute" ]
do
opts[$i]="${args[$i]}"
i=`expr $i + 1`
done
i=`expr $i + 1`
shift $i
unset args
i=0
for arg in "$@"
do
args[$i]=${arg//$'\x20'/$'\x1'}
i=`expr $i + 1`
done
/usr/bin/qterminal "${opts[@]}" -e $HOME/.local/bin/qterminal -E "${args[@]}"
elif [ "$1" = "-E" ]; then
shift
unset args
i=0
for arg in "$@"
do
args[$i]=${arg//$'\x1'/$'\x20'}
i=`expr $i + 1`
done
"${args[@]}"
else
/usr/bin/qterminal "$@"
fi

需注意的是,"export PATH=${HOME}/.local/bin:$PATH"需要在"~/.bashrc"设置。这样,可以使用vi命令快捷启用qterminal并打开nvim,而且可以添加参数打开多个文件。


SpaceVim使用教程
https://blog.siantao.top/手册/SpaceVim/SpaceVim使用教程/
作者
玉水仙楊
发布于
2022年5月1日
许可协议