如何在Linux上使用VIM进行.Net Core开发 导入一个通用的vimrc 安装模块管理工具pathogen.vim 安装mono 安装vim.nox 安装OmniSharp 安装OmniSharp需要的其他组件 添加自定义的配置 .Net Core 2.0支持 开发示例

如何在Linux上使用VIM进行.Net Core开发
导入一个通用的vimrc
安装模块管理工具pathogen.vim
安装mono
安装vim.nox
安装OmniSharp
安装OmniSharp需要的其他组件
添加自定义的配置
.Net Core 2.0支持
开发示例

对于在Linux上开发.Net Core的程序员来说, 似乎都缺少一个好的IDE.
Windows上有Visual Studio, Mac上有Visual Studio for Mac, 难道Linux只有Visual Studio Code了吗?
Linux上有两个最好的编辑器: VIM和Emacs, 哪个更好不是这一篇的主题, 这一篇的主题是如何在Linux上简单的构建一个比较好用的.Net Core开发环境.

以下的内容面向的是刚接触VIM的新手, 如果你完全未接触过, 可以去找一些入门的文章看看.
以下使用的环境是 Ubuntu 16.04 LTS + .Net Core 2.0 preview 2.

如果你是新手, 并且你的vimrc(vim的配置文件)空空如也, 请导入下面这个vimrc.
这个配置文件启用了智能缩进和改善了快捷键等等, 强烈推荐新手一开始使用它.
地址: https://github.com/amix/vimrc

git clone --depth=1 git://github.com/amix/vimrc.git ~/.vim_runtime
sh ~/.vim_runtime/install_basic_vimrc.sh

安装模块管理工具pathogen.vim

跟众多IDE中一样, vim可以模块化管理功能.
管理工具除了pathogen外还有Vundle等, 但pathogen是最简单的, 安装完以后把插件放在"~/.vim/bundle"下即可.
地址: https://github.com/tpope/vim-pathogen

mkdir -p ~/.vim/autoload ~/.vim/bundle
curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim
echo -e "
execute pathogen#infect()" >> ~/.vimrc

安装mono

虽然这篇文章介绍的是.Net Core开发, 但是C#的智能语法提示插件基于mono,所以必须先安装mono.
ubuntu 16.04自带的mono版本比较低, 需要从官方安装, 步骤如下:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb http://download.mono-project.com/repo/ubuntu xenial main" | sudo tee /etc/apt/sources.list.d/mono-official.list
sudo apt-get update
sudo apt-get install mono-devel

安装vim.nox

ubuntu 16.04上的vim默认不带python支持, 而omnisharp-vim要求python支持, 所以需要另外安装一个vim.nox.

sudo apt-get install vim.nox-py2
sudo update-alternatives --set vi /usr/bin/vim.nox-py2
sudo update-alternatives --set vim /usr/bin/vim.nox-py2

安装OmniSharp

OmniSharp用于动态解析C#的语法, 为语法分析和补全提示等功能提供支持, Visual Studio Code中用的也是它.
地址: https://github.com/OmniSharp/omnisharp-vim

cd ~/.vim/bundle
git clone https://github.com/OmniSharp/omnisharp-vim.git
cd omnisharp-vim
git submodule update --init --recursive
cd server
xbuild
cd ~/.vim/bundle/omnisharp-vim/omnisharp-roslyn
./build.sh

安装OmniSharp需要的其他组件

OmniSharp只提供了语言服务, 还需要安装其他组件来实现智能提示等功能.

dispatch.vim

用于后台启动OmniSharp的语言服务
地址: https://github.com/tpope/vim-dispatch

cd ~/.vim/bundle
git clone https://github.com/tpope/vim-dispatch

CtrlP

用于查找和定位类型
地址: https://github.com/ctrlpvim/ctrlp.vim

cd ~/.vim/bundle
git clone https://github.com/ctrlpvim/ctrlp.vim

syntastic

用于实现语法检查
地址: https://github.com/vim-syntastic/syntastic

cd ~/.vim/bundle
git clone https://github.com/vim-syntastic/syntastic

vim-deus

替换默认的配色
地址: https://github.com/ajmwagar/vim-deus

cd ~/.vim/bundle
git clone https://github.com/ajmwagar/vim-deus

添加自定义的配置

创建我们自己使用的配置文件

mkdir -p ~/.vim/bundle/myconf/plugin
vi ~/.vim/bundle/myconf/plugin/myconf.vim

添加以下的部分到myconf.vim中, 更多配置可以参考omnisharp-vim中的README.
粘贴前需要使用":set paste"防止粘贴的内容触发快捷键.

" 让omnisharp使用roslyn
let g:OmniSharp_server_type = 'v1'
let g:OmniSharp_server_type = 'roslyn'
let g:OmniSharp_prefer_global_sln = 1

" 设置omnisharp
let g:OmniSharp_timeout = 1
set noshowmatch
set completeopt=longest,menuone,preview
let g:syntastic_cs_checkers = ['code_checker']
set updatetime=500
augroup omnisharp_commands
    autocmd!
    autocmd FileType cs call s:SetCSharpOptions()
    setlocal omnifunc=OmniSharp#Complete
    fun! s:SetCSharpOptions()
        autocmd BufEnter,TextChanged,InsertLeave *.cs SyntasticCheck
        autocmd BufWritePost *.cs call OmniSharp#AddToProject()
        autocmd CursorHold *.cs call OmniSharp#TypeLookupWithoutDocumentation()
        " 设置快捷键
        " F12转到定义
        nnoremap <F12> :OmniSharpGotoDefinition<cr>
        nnoremap gd :OmniSharpGotoDefinition<cr>
        " Ctrl+F12转到实现
        nnoremap <C-F12> :OmniSharpFindImplementations<cr>
        nnoremap fi :OmniSharpFindImplementations<cr>
        " F11查找使用
        nnoremap <F11> :OmniSharpFindUsages<cr>
        nnoremap fu :OmniSharpFindUsages<cr>
        nnoremap ft :OmniSharpFindType<cr>
        nnoremap fs :OmniSharpFindSymbol<cr>
        nnoremap fm :OmniSharpFindMembers<cr>
        nnoremap fx  :OmniSharpFixIssue<cr>
        nnoremap fxu :OmniSharpFixUsings<cr>
        nnoremap tt :OmniSharpTypeLookup<cr>
        nnoremap dc :OmniSharpDocumentation<cr>
        nnoremap <C-Up> :OmniSharpNavigateUp<cr>
        nnoremap <C-Down> :OmniSharpNavigateDown<cr>
        nnoremap gc :OmniSharpGetCodeActions<cr>
        vnoremap gcv :call OmniSharp#GetCodeActions('visual')<cr>
        " F2重命名
        nnoremap <F2> :OmniSharpRename<cr>
        nnoremap rl :OmniSharpReloadSolution<cr>
        nnoremap cf :OmniSharpCodeFormat<cr>
        nnoremap tp :OmniSharpAddToProject<cr>
        nnoremap ss :OmniSharpStartServer<cr>
        nnoremap sp :OmniSharpStopServer<cr>
        nnoremap th :OmniSharpHighlightTypes<cr>
        " F1切换buffer
        nnoremap <F1> :buffers<CR>:buffer
        " F5编译+运行
        nnoremap <F5> :make<CR>
        " Enter选择提示内容+显示文档
        inoremap <expr><Enter> pumvisible() ? "<C-Y><Esc>:OmniSharpDocumentation<CR>a" : "<Enter>"
        " Tab切换提示内容
        inoremap <expr><Tab> pumvisible() ? "<C-n>" : "<Tab>"
        " (选择提示内容+显示文档
        inoremap <expr>( pumvisible() ? "<Esc>:OmniSharpDocumentation<CR>a(" : "("
        " 添加多行注释
        inoremap /// ///<Space><summary><CR><CR></summary><Esc>kA<Space>
        " 设置即时提示
        set completeopt+=menu
        set completeopt+=menuone
        set completeopt+=noinsert
        autocmd InsertCharPre * call s:TypeComplete()
        fun! s:TypeComplete()
            if pumvisible() && v:char !~ '.'
                return ''
            endif
            if v:char =~ '(K|.)'
                call feedkeys("<C-x><C-o>", 'n')
            endif
        endfun
    endfun
augroup END

" 定义有多行时不提示Enter继续
set cmdheight=2

" 转到定义时不询问保存
set hidden

" 开启256色支持
set t_Co=256

" 显示行号
set number

" 替换默认的配色
colorscheme deus

.Net Core 2.0支持

如果系统同时如果安装了.Net Core 2.0 preview 2, 可能会导致Omnisharp的语言服务启动失败, 可以用下面的办法解决.

cp -i ~/.nuget/packages/runtime.ubuntu.16.04-x64.runtime.native.System/1.0.1/runtimes/ubuntu.16.04-x64/native/System.Native.so ~/.vim/bundle/omnisharp-vim/omnisharp-roslyn/artifacts/publish/OmniSharp/default/net46/libSystem.Native.so
cp -i /usr/share/dotnet/sdk/2.0.0-preview2-006497/Sdks/Microsoft.NET.Sdk/tools/net46/NuGet.*.dll ~/.vim/bundle/omnisharp-vim/omnisharp-roslyn/artifacts/publish/OmniSharp/default/net46/

另外由于omnisharp的目前的一个bug(#309), 还需要执行以下的命令

cd ~/.vim/bundle/omnisharp-vim/omnisharp-roslyn/artifacts/scripts
ln -s OmniSharp Omnisharp

如果仍然无法得到智能提示, 可以手动启动语言服务确认是否出错.

~/.vim/bundle/omnisharp-vim/omnisharp-roslyn/artifacts/scripts/OmniSharp -p 2000 -s ~/NewProject/NewProject.sln

开发示例

首先创建一个项目

mkdir NewProject
cd NewProject
dotnet new console
dotnet new sln
dotnet sln add NewProject.csproj

然后生成一个Makefile, 这样可以支持":Make"或者"F5"时编译运行

echo -e "PHONY: run
run:
	dotnet run
" > Makefile

最后使用vim打开代码文件即可

vim Program.cs

效果(静态图)

如何在Linux上使用VIM进行.Net Core开发
导入一个通用的vimrc
安装模块管理工具pathogen.vim
安装mono
安装vim.nox
安装OmniSharp
安装OmniSharp需要的其他组件
添加自定义的配置
.Net Core 2.0支持
开发示例

效果(gif)

如何在Linux上使用VIM进行.Net Core开发
导入一个通用的vimrc
安装模块管理工具pathogen.vim
安装mono
安装vim.nox
安装OmniSharp
安装OmniSharp需要的其他组件
添加自定义的配置
.Net Core 2.0支持
开发示例

教程就到此为止了, 需要更多功能可以查看omnisharp-vim的官方Github.