Gvim和Neovim共享配置安装 - Windows篇

装一台新电脑, 想把Gvim或者Neovim的所有相关软件都安装得跟以前一样还真是有很多坑. 记录一下以方便按图索骥. 目标是同一套配置可以使用在两个编辑器上. 现在Neovim的开发明显更活跃, 长期看将来是要转到Neovim上. 但现在Neovim还是有bug. 所以两个换着用直到Neovim明显超出Gvim的那一天.

Windows下安装.

下载软件.

先安装git, python3, python3的具体版本需要跟Gvim的匹配.

需要下载下列软件, 解压到C:\Users\%USERNAME%\AppData\Local\Programs, 确保所有可执行文件所在目录都被设置在系统变量Path里.

  1. gvim, 下载地址:https://github.com/vim/vim-win32-installer/releases. 下载最新版的zip包. 注意看gvim依赖的python版本. (这里没有直接使用安装包, 如果用安装包, 下面的右键菜单操作需要删除gvim的部分.)
  2. Neovim, 下载地址:https://github.com/neovim/neovim/releases/, 下载最新nightly版zip包.
  3. ripgrep, 下载地址:https://github.com/BurntSushi/ripgrep/releases. 也可以通过chocolatey来安装.
  4. Universal Ctags, 下载地址:https://github.com/universal-ctags/ctags-win32/releases.
  5. gtags, 下载地址: https://www.gnu.org/software/global/download.html.

使用下面这个registry文件, 把Gvim和Neovim都加到右键菜单里:

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
43
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\gvim]
@="Edit with Gvim"
"Icon"="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\vim\\vim82\\gvim.exe\""

[HKEY_CLASSES_ROOT\*\shell\gvim\command]
@="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\vim\\vim82\\gvim.exe\" \"%1\""

[HKEY_CLASSES_ROOT\Directory\shell\gvim]
@="Open Gvim Here"
"Icon"="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\vim\\vim82\\gvim.exe\""

[HKEY_CLASSES_ROOT\Directory\shell\gvim\command]
@="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\vim\\vim82\\gvim.exe\" \"%1\""

[HKEY_CLASSES_ROOT\Directory\Background\shell\gvim]
@="Open Gvim here"
"Icon"="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\vim\\vim82\\gvim.exe\""

[HKEY_CLASSES_ROOT\Directory\Background\shell\gvim\command]
@="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\vim\\vim82\\gvim.exe\" \"%v\""

[HKEY_CLASSES_ROOT\*\shell\nvim-qt]
@="Edit with Neovim"
"Icon"="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Neovim\\bin\\nvim-qt.exe\""

[HKEY_CLASSES_ROOT\*\shell\nvim-qt\command]
@="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Neovim\\bin\\nvim-qt.exe\" \"%1\""

[HKEY_CLASSES_ROOT\Directory\shell\nvim-qt]
@="Open Neovim Here"
"Icon"="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Neovim\\bin\\nvim-qt.exe\""

[HKEY_CLASSES_ROOT\Directory\shell\nvim-qt\command]
@="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Neovim\\bin\\nvim-qt.exe\" \"%1\""

[HKEY_CLASSES_ROOT\Directory\Background\shell\nvim-qt]
@="Open Neovim here"
"Icon"="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Neovim\\bin\\nvim-qt.exe\""

[HKEY_CLASSES_ROOT\Directory\Background\shell\nvim-qt\command]
@="\"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Neovim\\bin\\nvim-qt.exe\" \"%v\""

下载字体

我一直使用randomTheme.vim, 使每个打开的窗口的配色和字体不一样. 一个是带来新鲜感避免视觉疲劳, 一个是方便区分各个窗口打开的是什么. randomTheme.vim本身提供一些适合编程的字体:

  1. Cascadia.ttf
  2. Consolas.ttf
  3. dejavu-fonts-ttf-2.37
  4. FiraCode_2
  5. Inconsolata
  6. JetBrainsMono-1.0.3
  7. SourceCodePro
  8. Ubuntu_Mono

我还要下载两个:

  1. Monaco
  2. DejaVu

右键菜单选择安装即可.

配置

配置目录

为了使Gvim和Neovim共享一套配置. 配置文件一概使用Neovim的配置目录C:\Users\%USERNAME%\AppData\Local\nvim, 其中的配置文件有init.vimginit.vim. 然后通过下列命令为Gvim创建配置文件的符号链接.

1
2
mklink C:\Users\%USERNAME%\_vimrc C:\Users\%USERNAME%\AppData\Local\nvim\init.vim
mklink /D C:\Users\%USERNAME%\vimfiles C:\Users\%USERNAME%\AppData\Local\nvim

其中init.vim, 我自己一直维护在github私库里.

这里重点说一下Neovim和Gvim配置上有区别的几个地方, 以及如何统一:

  1. 标准路径: Neovim提供了一种方式访问标准路径, 参考help stdpath. 所以配置init.vim, 使Gvim也使用这些路径. 下面列出跟此相关的一些配置:
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
43
44
45
46
47
48
if has('nvim')
let s:cachedir = expand(stdpath('cache'))
let s:configdir = expand(stdpath('config'))
let s:datadir = expand(stdpath('data'))
else
"vim will share same folder with nvim
if has('win32')
let s:cachedir = expand('~/AppData/Local/Temp/nvim')
let s:configdir = expand('~/AppData/Local/nvim')
let s:datadir = expand('~/AppData/Local/nvim-data')
else
let s:cachedir = expand('~/.cache/nvim')
let s:configdir = expand('~/.config/nvim')
let s:datadir = expand('~/.local/share/nvim')
endif
endif

call plug#begin(s:configdir. '/plugged')
Plug 'some plugins'
...
call plug#end()

if !has('nvim')
let s:vimswap = expand(s:datadir . '/swap')
if !isdirectory(s:vimswap)
call mkdir(s:vimswap, "p", 0700)
endif
let &dir=s:vimswap
endif

if has("persistent_undo")
let s:undo_path = expand(s:configdir . '/undo')

" create the directory and any parent directories
" if the location does not exist.
if !isdirectory(s:undo_path)
call mkdir(s:undo_path, "p", 0700)
endif

if !has('nvim')
let &undodir=s:undo_path
endif
"Create file which contains undo information so you can undo previous actions even
"after you close and reopen a file.
set undofile
endif

let g:Lf_CacheDirectory = s:cachedir
  1. Python相关, 我使用的几个插件要用python, Gvim和Neovim在Python支持上完全不同. 这里只说Python3.

    • Gvim首先要求编译时有+Python3/dyn特性, 即至此动态链接(静态我在linux式了一下不成功, windows安装包也不提供静态). 然后需要设置pythonthreehome和pythonthreedll两个option. 最后linux上vim内Python的sys.path跟外面还不一样, 所以需要设置PYTHONHOME和PYTHONPATH环境变量. 配置完了需要自己用:py3 print("hello world")试试.
    • Neovim, 设置g:python3_host_prog全局变量, 用:checkhealth命令检查.

以下是我的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if has('nvim')
if has('win32')
let g:python3_host_prog=expand('~/AppData/Local/Programs/Python/Python39/python.exe')
else
let $PYTHONHOME='/usr/local/bin'
let $PYTHONPATH='/usr/local/lib/python39.zip:/usr/local/lib/python3.9:/usr/local/lib/python3.9/lib-dynload:/home/honeywell/.local/lib/python3.9/site-packages:/usr/local/lib/python3.9/site-packages'
let g:python3_host_prog='/bin/python3'
endif
else
if has('win32')
let &pythonthreehome=expand('~/AppData/Local/Programs/Python/Python39')
let &pythonthreedll=expand('~/AppData/Local/Programs/Python/Python39/python39.dll')
else
let $PYTHONHOME='/usr/local/bin'
let $PYTHONPATH='/usr/local/lib/python39.zip:/usr/local/lib/python3.9:/usr/local/lib/python3.9/lib-dynload:/home/honeywell/.local/lib/python3.9/site-packages:/usr/local/lib/python3.9/site-packages'
let &pythonthreehome=expand('/bin')
let &pythonthreedll=expand('/usr/local/lib/libpython3.9.so')
endif
endif

  1. 有很多选项Neovim无需配置, Gvim需要配置, 我列出一些:
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
"only for vim
if !has('nvim')
filetype plugin indent on
syntax on
set encoding=utf-8
set backspace=indent,eol,start
let s:vimswap = expand(s:datadir . '/swap')
if !isdirectory(s:vimswap)
call mkdir(s:vimswap, "p", 0700)
endif
let &dir=s:vimswap
"Completion mode setting
set wildmenu
set wildmode=full

set incsearch
set hlsearch

" Toggle Menu and Toolbar
" @see http://liyanrui.is-programmer.com/articles/1791/gvim-menu-and-toolbar-toggle.html
set guioptions+=b
set guioptions-=m
set guioptions-=T
map <silent> <C-F12> :if &guioptions =~# 'T' <Bar>
\set guioptions-=T <Bar>
\set guioptions-=m <bar>
\else <Bar>
\set guioptions+=T <Bar>
\set guioptions+=m <Bar>
\endif<CR>
endif

插件安装

安装其他插件之前需要先下载插件管理器, 我选了下面这款:

plug.vim

放在C:\Users\%USERNAME%\AppData\Local\nvim\autoload下面

打开Neovim或者Gvim, 运行:PlugInstall. 以下是我现在在用的兼容Neovim和Gvim的插件. (只有一个不兼容, 下节介绍)

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
call plug#begin(s:configdir. '/plugged')
Plug 'scrooloose/nerdTree'
Plug 'FuDesign2008/randomTheme.vim'
Plug 'flazz/vim-colorschemes'
Plug 'tpope/vim-surround'
Plug 'easymotion/vim-easymotion'
Plug 'Yggdroot/LeaderF'
Plug 'Yggdroot/LeaderF', { 'do': '.\install.bat' }
Plug 'ludovicchabant/vim-gutentags'
Plug 'skywind3000/gutentags_plus'
Plug 'octol/vim-cpp-enhanced-highlight'
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
Plug 'preservim/nerdcommenter'
Plug 'junegunn/vim-easy-align'
Plug 'dimasg/vim-mark'
Plug 'andymass/vim-matchup'
Plug 'kshenoy/vim-signature'
Plug 'terryma/vim-expand-region'
Plug 'jeetsukumaran/vim-indentwise'
Plug 'will133/vim-dirdiff'
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'skywind3000/vim-quickui'
Plug 'mbbill/undotree'
Plug 'mhinz/vim-signify'
call plug#end()

Vim插件修改

RandomTheme.vim插件不支持Neovim的启动, 原因是Neovim的GUI机制跟Gvim不一样, init.vim是在GUI之前加载的, 所以提供了另一个配置文件ginit.vim来配置GUI. 修改plugged\randomTheme.vim\plugin\randomtheme.vim里的函数s:SetFont成:

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
function! s:SetGuiFont(guifont)
let splitted = split(a:guifont, ':h')
if len(splitted) != 2
return
endif
let font = splitted[0]
let size = splitted[1]
if has('x11')
let g:favorite_gui_font = font . '\ ' . size
else
let g:favorite_gui_font = font . ':h' . size
endif

if has('gui_running')
" for ubuntu vim-gonme
if has('x11')
let commandStr = 'set guifont=' . font . '\ ' . size
execute commandStr
else
let commandStr = 'set guifont=' . font . ':h' . size
execute commandStr
endif
elseif has('nvim') && exists('g:GuiLoaded')
echo g:favorite_gui_font
execute ':GuiFont! ' . g:favorite_gui_font
endif
endfunction

然后再在ginit.vim里加下面一句话:

1
execute ':GuiFont! ' . g:favorite_gui_font

可以windows上完美适配NeoVim.

这个问题我提交给randomTheme.vim作者, 在issue#7里.

Python插件安装

下面两个Python插件需要安装 1. pynvim, nvim的Python支持. 2. Pygments, gtags只支持6种语言, 其他语言的tags需要这个工具.

使用pip直接安装就可以了.

1
2
pip install neovim
pip install Pygments

其他依赖

为满足插件COC的依赖, 需要额外安装javascript环境node.js, 注意也要安装neovim的插件

1
npm install neovim

Linux下安装

Linux下安装的复杂程度高一些, 而且不同发布版安装也不一样, 回头再写一篇Linux的.