先说点废话。
最近装了 WSL2,想着作为 Win10 内置的 Linux 系统,应该比一般的虚拟机要来得平滑一些。毕竟虚拟机还要装 Virtualbox,每次开机还要多点几下,还要等它启动。怕麻烦。。。
可能习惯问题,喜欢在 Linux 下配置开发环境(学习写代码)。总感觉 Windows 上略显磨叽了一些。也许我道行不够。碰到需要编译的东西,一套工具装起来过于繁琐,直接 sudo apt install gcc
不香吗。
可惜 WSL 没有桌面支持,装不上 Vscode。对于工具的选择,我的原则是简单够用就好,Vscode 即是目前我的最爱(非重度编码)。
开箱即用,功能满足基本需求。无非代码高亮、自动补全、查看定义、语法检查、代码格式化,再加个跳转。
于是决定在 Windows 系统上安装 Vscode,借助 Remote WSL 插件“远程”编码。可惜有 BUG,一直不能正常工作。Github 上提了 issue,没人理。无奈转向 Vim。
一开始用的补全插件是 YouCompleteMe,还要编译。虽然敲个命令就能自动执行,但光 Rust 支持就在本地给我搞了将近 1G 的文件,不太能忍。网上查了下,貌似已经很老的机制了。于是转向较新一点的 coc.nvim。据说支持各种 LSP(这个缩写。。。),也不懂,能用就行。
废话结束。
一、效果截图
二、NERDTree 文件浏览器
vim 用的自带的 8.1 版本,有内置的插件管理。一般的插件安装流程是直接将插件源代码 clone 到 ~/.vim/pack/vendor/start
路径下(没有就创建),再在 vim 中运行 :helptags ~/.vim/pack/vendor/start/someplugin/doc
命令生成帮助文档(这一步可选)。
vim 会自动检测已经下载的插件。vendor
路径下可以有 start
和 opt
两个目录,start
路径下的插件会在 vim 启动时自动加载,opt
路径下的插件则需要通过 :packadd
命令手动加载。
vendor
也可以是其他名称,同位置下也可以有多个相同结构的目录,方便对不同类型的插件分别进行管理。
省事起见,这里所有的插件都放在 ~/.vim/pack/vendor/start
下面。
NERDTree 文件浏览器插件安装:
cd ~/.vim/pack/vendor/start
git clone https://github.com/scrooloose/nerdtree
在 ~/.vimrc
文件中添加配置:
" 进入 vim 时自动开启 NERDTree
autocmd VimEnter * NERDTree | wincmd p
" 若关闭某个 buff 后 NERDTree 是仅剩的最后一个 buff,则自动关闭 NERDTree
autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif
" 使用 Ctrl+n 快捷键打开或关闭 NERDTree
nnoremap :NERDTreeToggle
更多配置选项参考 VimAwesome
三、vim-airline 与配色
安装 vim-airline 状态栏美化插件:
git clone https://github.com/vim-airline/vim-airline
关于配色,萝卜青菜各有所爱。懒得去一个一个试。
准备了两套,vim-one 深色和 gruvbox 浅色。
vim-one 插件安装:
git clone https://github.com/rakr/vim-one
添加配置:
" 深色背景
set bg=dark
" 启用 one 配色
colorscheme one
效果截图:
安装 gruvbox 插件:
git clone https://github.com/morhetz/gruvbox
修改配置文件(注释掉 colorscheme one
):
set bg=light
" colorscheme one
autocmd vimenter * ++nested colorscheme gruvbox
效果截图:
更复杂的配置可自行在 VimAwesome 搜索对应的插件,或者进入相应的 Github 主页查看。
四、coco.nvim 代码补全与语法检查
安装 nodejs >= 10.12,官网上写的是通过 curl -sL install-node.now.sh/lts | bash
命令安装。我个人建议使用 nvm 安装最新的 lts 版本。此处不赘述。
安装 coc.nvim 插件:
git clone https://github.com/neoclide/coc.nvim.git
为了得到某种编程语言的补全功能,还需要安装对应语言的 coc 扩展以及代码补全后端(LSP)。
比如 C/C++ 对应的 coc 扩展为 coc-clangd,LSP 为 clangd
。两个都需要。
安装 coc 扩展的方法非常简单,进入 vim 后运行 :CocInstall extension_name
命令即可。
比如使用 :CocInstall coc-clangd
命令安装 coc-clangd
扩展。coc 扩展我遇到的都比较小,安装非常迅速,也会单独开一个窗口显示进度信息。
coc 扩展安装完成后,打开对应的源代码文件,比如 vim test.c
,vim 就会自动在本地环境中寻找对应的 LSP(C/C++ 语言是 clangd
)。
若 clangd
此时并未安装,vim 就会提示你运行某个命令(在 vim 内部)自动安装该依赖。这里有个坑。
不知道是不是网络的问题,我复制运行了 vim 提供的命令,一直显示下载中,几个小时不见下载完成。。。
好在可以手动安装 clangd
,退出 vim 直接运行 sudo apt install clangd
即可。
此时 coc.nvim 对于 C/C++ 的补全支持即安装配置完成。
Rust 和 Python 语言支持
对于 Rust 语言,需要先安装 coc-rust-analyzer 扩展:
:CocInstall coc-rust-analyzer
这一步简单迅速。
安装 rust-src
:rustup component add rust-src
接着还必须安装针对 Rust 的 LSP(rust-analyzer
)。鉴于安装 clangd
时出现的曲折,我决定手动安装 rust-analyzer
。诡异的事情发生了。手动安装的可执行程序不被 coc 识别。
无奈下尝试 vim 中的自动安装居然成功了。。。
方法是用 vim 新建任意一个 rust 源文件(vim test.rs
),vim 会自动弹出提示,找不到 rust-analyzer
,是否自动安装,选择 Yes
即可。这里的安装过程居然异乎寻常的快。
安装完成后可能不会立即生效,会尝试创建索引。多打开几个文件试试。
至于 Python,安装 coc-pyright:
:CocInstall coc-pyright
印象中并没有做其他操作,对于 Python 的支持就自动生效了,也许是安装扩展的时候自动安装了对应的 LSP。
对于其他语言的支持,可参考 Using coc extensions。
coc.nvim 示例配置(从官方 Github 上 copy 的,主要是一些快捷键的映射,可根据需求删减。没细看):
" Set internal encoding of vim, not needed on neovim, since coc.nvim using some
" unicode characters in the file autoload/float.vim
set encoding=utf-8
" TextEdit might fail if hidden is not set.
set hidden
" Some servers have issues with backup files, see #649.
set nobackup
set nowritebackup
" Give more space for displaying messages.
set cmdheight=2
" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable
" delays and poor user experience.
set updatetime=300
" Don't pass messages to |ins-completion-menu|.
set shortmess+=c
" Always show the signcolumn, otherwise it would shift the text each time
" diagnostics appear/become resolved.
if has("nvim-0.5.0") || has("patch-8.1.1564")
" Recently vim can merge signcolumn and number column into one
set signcolumn=number
else
set signcolumn=yes
endif
" Use tab for trigger completion with characters ahead and navigate.
" NOTE: Use command ':verbose imap ' to make sure tab is not mapped by
" other plugin before putting this into your config.
inoremap
\ pumvisible() ? "\" :
\ check_back_space() ? "\" :
\ coc#refresh()
inoremap pumvisible() ? "\" : "\"
function! s:check_back_space() abort
let col = col('.') - 1
return !col || getline('.')[col - 1] =~# '\s'
endfunction
" Use to trigger completion.
if has('nvim')
inoremap coc#refresh()
else
inoremap coc#refresh()
endif
" Make auto-select the first completion item and notify coc.nvim to
" format on enter, could be remapped by other vim plugin
inoremap pumvisible() ? coc#_select_confirm()
\: "\u\\=coc#on_enter()\"
" Use `[g` and `]g` to navigate diagnostics
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
nmap [g (coc-diagnostic-prev)
nmap ]g (coc-diagnostic-next)
" GoTo code navigation.
nmap gd (coc-definition)
nmap gy (coc-type-definition)
nmap gi (coc-implementation)
nmap gr (coc-references)
" Use K to show documentation in preview window.
nnoremap K :call show_documentation()
function! s:show_documentation()
if (index(['vim','help'], &filetype) >= 0)
execute 'h '.expand('')
elseif (coc#rpc#ready())
call CocActionAsync('doHover')
else
execute '!' . &keywordprg . " " . expand('')
endif
endfunction
" Highlight the symbol and its references when holding the cursor.
autocmd CursorHold * silent call CocActionAsync('highlight')
" Symbol renaming.
nmap rn (coc-rename)
" Formatting selected code.
xmap f (coc-format-selected)
nmap f (coc-format-selected)
augroup mygroup
autocmd!
" Setup formatexpr specified filetype(s).
autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
" Update signature help on jump placeholder.
autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end
" Applying codeAction to the selected region.
" Example: `aap` for current paragraph
xmap a (coc-codeaction-selected)
nmap a (coc-codeaction-selected)
" Remap keys for applying codeAction to the current buffer.
nmap ac (coc-codeaction)
" Apply AutoFix to problem on the current line.
nmap qf (coc-fix-current)
" Map function and class text objects
" NOTE: Requires 'textDocument.documentSymbol' support from the language server.
xmap if (coc-funcobj-i)
omap if (coc-funcobj-i)
xmap af (coc-funcobj-a)
omap af (coc-funcobj-a)
xmap ic (coc-classobj-i)
omap ic (coc-classobj-i)
xmap ac (coc-classobj-a)
omap ac (coc-classobj-a)
" Remap and for scroll float windows/popups.
if has('nvim-0.4.0') || has('patch-8.2.0750')
nnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\"
nnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\"
inoremap coc#float#has_scroll() ? "\=coc#float#scroll(1)\" : "\"
inoremap coc#float#has_scroll() ? "\=coc#float#scroll(0)\" : "\"
vnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\"
vnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\"
endif
" Use CTRL-S for selections ranges.
" Requires 'textDocument/selectionRange' support of language server.
nmap (coc-range-select)
xmap (coc-range-select)
" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocAction('format')
" Add `:Fold` command to fold current buffer.
command! -nargs=? Fold :call CocAction('fold', )
" Add `:OR` command for organize imports of the current buffer.
command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport')
" Add (Neo)Vim's native statusline support.
" NOTE: Please see `:h coc-status` for integrations with external plugins that
" provide custom statusline: lightline.vim, vim-airline.
set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}
" Mappings for CoCList
" Show all diagnostics.
nnoremap a :CocList diagnostics
" Manage extensions.
nnoremap e :CocList extensions
" Show commands.
nnoremap c :CocList commands
" Find symbol of current document.
nnoremap o :CocList outline
" Search workspace symbols.
nnoremap s :CocList -I symbols
" Do default action for next item.
nnoremap j :CocNext
" Do default action for previous item.
nnoremap k :CocPrev
" Resume latest coc list.
nnoremap p :CocListResume
五、彩蛋
smile
在 vim 中运行 :smile
:smile
oooo$$$$$$$$$$$$oooo
oo$$$$$$$$$$$$$$$$$$$$$$$$o
oo$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o o$ $$ o$
o $ oo o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o $$ $$ $$o$
oo $ $ "$ o$$$$$$$$$ $$$$$$$$$$$$$ $$$$$$$$$o $$$o$$o$
"$$$$$$o$ o$$$$$$$$$ $$$$$$$$$$$ $$$$$$$$$$o $$$$$$$$
$$$$$$$ $$$$$$$$$$$ $$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$ $$$$$$$$$$$$$$ """$$$
"$$$""""$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ "$$$
$$$ o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ "$$$o
o$$" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$o
$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" "$$$$$$ooooo$$$$o
o$$$oooo$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ o$$$$$$$$$$$$$$$$$
$$$$$$$$"$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$""""""""
"""" $$$$ "$$$$$$$$$$$$$$$$$$$$$$$$$$$$" o$$$
"$$$o """$$$$$$$$$$$$$$$$$$"$$" $$$
$$$o "$$""$$$$$$"""" o$$$
$$$$o o$$$"
"$$$$o o$$$$$$o"$$$$o o$$$$
"$$$$$oo ""$$$$o$$$$$o o$$$$""
""$$$$$oooo "$$$o$$$$$$$$$"""
""$$$$$$$oo $$$$$$$$$$
""""$$$$$$$$$$$
$$$$$$$$$$$$
$$$$$$$$$$"
"$$$""""
Kill Sheep 小游戏
针对 vim 8.2 版本,可在 Windows 系统中安装 gvim 8.2。
进入 C:\Users\xxx\vimfiles\pack\vendor\start
路径下(没有就创建),clone 源代码:
git clone https://github.com/vim/killersheep.git
打开 gvim,最大化,运行 :KillKillKill
命令即可进入游戏。