vim因其丰富的插件和强大的配置功能在创建开发环境的自由度上确实非其它编辑器和IDE能比。之所以要用docker创建一个vim开发环境,因为docker轻量,简单,便于管理。在一个镜像里配置好vim后,上传到自己的仓库里,这样换台主机后不用再从头安装插件配置环境,而是直接在docker里把镜像下载下来。
考虑到最后生成的镜像体积一定要小,所以不选用ubuntu或是centos系统,而是使用轻量级linux操作系统alpine,只有几兆 大小。实际上docker hub上有基于alpine的vim镜像,jare/vim-bundle ,本文很多地方也参考了其Dockerfile的写法。这个镜像集成了很多vim插件,但是唯独YouCompleteMe会报错,而我之前已经习惯了YCM这个神器,所以重新做了一个。
1.安装vim
因为YCM需要vim支持python,并且要保证vim版本在7.4以上,所以通常需要重新编译vim。而编译需要安装build-base,make等工具,alpine使用指令apk add
下载并安装软件,类似ubuntu的apt-get install
。但是默认的源是国外网址,比较慢,所以可以修改/etc/apk/repositories
换源,我使用的是阿里云镜像地址,如下:
http://mirrors.aliyun.com/alpine/v3.6/main
http://mirrors.aliyun.com/alpine/v3.6/community
于是在Dockerfile中这么写就可以安装支持python的vim了。
FROM alpine:latest
ADD repositories /etc/apk/repositories
RUN apk update
RUN apk add build-base \
ctags \
git \
libx11-dev \
libxpm-dev \
libxt-dev \
make \
ncurses-dev \
python \
python-dev
#build vim
RUN cd /tmp \
&& git clone https://github.com/vim/vim \
&& cd /tmp/vim \
&& ./configure \
--disable-gui \
--disable-netbeans \
--enable-multibyte \
--enable-pythoninterp \
--prefix /usr \
--with-features=big \
--with-python-config-dir=/usr/lib/python2.7/config \
&& make install \
&& cp /usr/share/vim/vim80/vimrc_example.vim ~/.vimrc
最后一步我们将vimrc_example.vim拷贝到根目录下的.vimrc文件,作为我们vim的配置文件。之后对vim的一些配置都写到/root/.vimrc文件中。
2.安装YCM
首先要有一个总的流程的概念。YCM之所以有那么强大的补全和调试功能,是因为其基于clang,可以对代码文本实时地分析。我们从github上下载了YCM的源码后,可以按照官方文档上说的那样直接运行安装脚本./install.py --clang-completer
进行安装,但这种方法是直接下载编译好的libclang.so,并生成一个ycm_core,而通常情况下(除非你人品好到炸),YCM安装好了却没有基于语义补全的功能。
你可以在vim中输入YcmDebugInfo
来检查YCM是否有错误,以及输入YcmToggleLogs **stderror**.log
来查看错误日志。很可能出现的报错是:
Full error: libtinfo.so.5: cannot open shared object file: No such file or directory
这种报错就说明libclang没有安装好。
另一种方法就是不运行安装脚本,而是自己编译ycm_core,并在编译时指定自己安装的libclang。这里简书上有篇文章详细说明了这种方法,一步一步带你安装史上最难安装的 vim 插件 —— YouCompleteMe
然而不知为何,如果不运行install.py,即便自己安装了libclang,在进行编译ycm_core时依旧提示找不到libclang.so。于是我采用了一个折衷的办法,就是运行install.py之后用/usr/lib/libclang.so
代替../third_party/ycmd/libclang.so
,终于运行YCM不再报错。
于是可以在Dockerfile中这么写
#build ycm
RUN apk add clang cmake
RUN git clone --depth 1 https://github.com/Valloric/YouCompleteMe /root/.vim/bundle/YouCompleteMe \
&& cd /root/.vim/bundle/YouCompleteMe \
&& git submodule update --init --recursive \
&& ./install.py --clang-completer
RUN cp ~/.vim/bundle/YouCompleteMe/third_party/ycmd/examples/.ycm_extra_conf.py ~/.vim/ \
&& cd ~/.vim/bundle/YouCompleteMe && cp -r autoload plugin third_party python /root/.vim \
&& cp /usr/lib/libclang.so.4.0 ~/.vim/third_party/ycmd/
3 配置,清除,创建容器
配置vimrc如下:
#config .vimrc
RUN echo "let g:ycm_server_python_interpreter='/usr/bin/python2.7'" >> /root/.vimrc \
&& echo "let g:ycm_global_ycm_extra_conf='~/.vim/.ycm_extra_conf.py'" >> /root/.vimrc \
&& echo "let g:ycm_seed_identifiers_with_syntax=1" >> /root/.vimrc \
&& echo "set completeopt-=preview" >> /root/.vimrc
还要删除多余的文件以减小镜像体积。然而最后创建的镜像仍然有1个多G,显然太大了,不知道还有没有好的办法进一步减小镜像体积。
#clear
RUN rm -r /root/.vim/bundle/YouCompleteMe
RUN rm -r /tmp/vim
设置entrypoint如下:
#entrypoint
#RUN cd /usr/local/bin && touch run && echo "cd /home">>run && echo "vim $@">>run && chmod +x run
于是就使用指令docker run -ti --rm -v $(pwd):/home your_image_name
创建一个临时的YCM容器了。