D 语言是个非常好现代语言,只不过现在国内太小众了,没有中文社区也几乎没有中文资料。工具的配置大部分还是要靠自己摸索啊……
Vim 的代码补全使用的是 DCD(全称D Completion Daemon)。DCD 支持几乎所有 D 语言语义补全:内建类型,关键字,枚举,类,结构,接口,函数,包,this……通吃。当然对一些模版参数还是无能为力的。
下面已 Windows 为例介绍 Vim 使用 DCD 进行 D 语言补全的配置方法。
准备
- Vim 插件管理,推荐 Vundle
- Git
-
一款 D 语言编译器
PS.顺便推荐一个 D 语言的语法高亮:https://github.com/JesseKPhillips/d.vim
编译DCD
首先,Git 的 bin 目录和 D 语言编译器的 bin 目录要放在环境变量里。
随便找个你喜欢的文件夹
git clone https://github.com/Hackerpilot/DCD.git
cd DCD
git submodule update –init
完成之后运行 build.bat,稍等一会
编译完成后根目录会多出两个文件,dcd-client.exe 和 dcd-server.exe。这两个是我们需要的,copy 到一个你喜欢的文件夹。其他的就没用了,有强迫症的话直接删掉就好
到此 DCD 就编译好了
配置Dutyl
dutyl 是用来沟通 Vim 和 DCD 的,有了他 DCD 才能和 Vim 配合。基于的是 VimScript 编写 OmniComplete 补全引擎。顺便说一下,dutyl 还支持通过 Dscaner 做语法和风格检查
1.https://github.com/idanarye/vim-dutyl
如果用 Vundle 的话直接 Plugin 'idanarye/vim-dutyl' 然后 :PluginInstall 就好了
2.好的,如果你的 DCD 已经在环境变量里了,这一步直接略过
如果有强迫症不喜欢往 PATH 里塞很多东西的话,往下看
在 vimrc 中添加下面的语句:
call dutyl#register#tool('dcd-client','/path/to/DCD/dcd-client')
call dutyl#register#tool('dcd-server','/path/to/DCD/dcd-server')
后面的 "/path/to/DCD/dcd-*" 是你 DCD 实际所在的位置,注意是完整的路径,要加扩展名
3.DCD 已经配置好了,现在重要的是让 DCD 知道你要补全的文件在哪
把 phobos 所在目录塞到 g:dutyl_stdImportPaths 里:一般情况下这货在 dmd2/src/phobos 和 dmd2/src/druntime/import 里
let g:dutyl_stdImportPaths=['/usr/include/dlang/dmd']
4.然后我们就可以开始补全了。打开一个D buffer,命令 :DUDCDstartServer 启动 DCD 服务,然后在需要补全的地方 <C-X> <C-O> 就行了。如果不再需要补全了就 :DUDCDstopServer 关闭 DCD 服务
更多帮助可以 :h dutyl
配合其他补全插件加速补全
作为一个从 VS+VA 转过来的 Vimer,已经习惯了 VA 那种自动模式。相信除了 Vim 的作者没人会喜欢 <C-X> <C-O>
前面说了 dutyl 是一个基于 OmniComplete 的补全引擎,所以只要支持调用 omnifunc 获取补全的插件都可以和 dutyl 配合。比如 neocomplcache,AutoComplPop 或者YouCompleteMe。
配合 YouCompleteMe
YCM 需要 Vim 支持 Python。
Linux 下安装请看此帖
Windows 下我写过一个blog
安装完成就默认支持对 D 语言的补全,现在只需要按 "." 号就能激活补全引擎。当然在任何时候都可以使用 <C-Space> 打开补全列表
如果想要自定义语义补全触发按键只需要修改 g:ycm_semantic_triggers,详见YCM readme
配合 NeoComplete
dutyl 已经配置好了 omnifunc,所以我们设置 触发即可
NeoComplete 的文档中介绍了与很多语言补全插件配合的设置,我们可以借鉴一下 Python 的正则作为触发,
let g:neocomplete#force_omni_input_patterns.d='\%([^. \t]\.\|^\s*@\|^\s*import \)\w*'
这样每次输入 “.” 或者 “import” 后就会触发语意补全
当然,想要手动触发的话还需要自己映射 <C-X> <C-O>