目的
很多时候,用nvim开发不同语言(如全栈开发者经常用的javascript, php, python, less, go等),想做自动补全的话,就要安装一堆的语言相关.如果都安装在工作电脑上,会感觉雍肿,留下垃圾文件等问题.而docker化后可解决这些问题.
实现
- 使用基于alpine:3.8的image, 初始大小仅4.4M
- Dockerfile内容
FROM alpine:3.8
# prepare tools
COPY buildtool/ /build/
ADD root /
# install
RUN /build/install && \
/build/add_user && \
/build/cleanup
ENTRYPOINT ["/sbin/tini","--"]
CMD ["/bin/sh"]
- buildtool/install
#!/bin/sh
set -e
. /build/config
apk add --update $RUNTIME_PKGS
apk add $BUILD_DEP_PKGS
apk add $INSTALL_PKGS
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo "Asia/Shanghai" > /etc/timezone
# == python language
pip3 install --upgrade neovim jedi python-language-server
# == typescript language
npm config -g set registry https://registry.npm.taobao.org
npm install -g typescript typescript-language-server
# == css/less language
npm install -g vscode-css-languageserver-bin
# == docker language
npm install -g dockerfile-language-server-nodejs
npm install -g eslint eslint-plugin-vue
# == php language
# step1: install composer
curl -sS https://getcomposer.org/installer | php
chmod a+x composer.phar
mv composer.phar /bin/composer
#使用中国镜像
/bin/composer config -g repo.packagist composer https://packagist.phpcomposer.com
#step2: php language server(可通过neovim plugin安装)
#ref: https://github.com/prabirshrestha/vim-lsp/wiki/Servers-PHP
- buildtool/config
## Run time dependencies ##
RUNTIME_PKGS="bind-tools"
BUILD_DEP_PKGS="tzdata"
INSTALL_PKGS="curl wget axel linux-headers build-base bash tini tree neovim neovim-doc git nodejs \
php7 php7-xmlwriter php7-ctype php7-curl php7-dom php7-gd php7-iconv php7-intl php7-json php7-openssl php7-mcrypt php7-xml php7-simplexml php7-zip php7-mbstring php7-session php7-zlib php7-phar php7-tokenizer \
python3 python3-dev sudo python the_silver_searcher the_silver_searcher-bash-completion"
- buildtool/adduser 目的是将host机上的user和当前用户设置为一样; 这样就可以将home目录直接mount进container里.
#! /bin/sh
USER_GROUP=你的group
USER_GID=你的gid, 可用 id -g 查看
USER=你的name
USER_UID=你的uid
echo "add user:${USER}"
addgroup -g ${USER_GID} ${USER_GROUP}
adduser -u ${USER_UID} -G ${USER_GROUP} -D -s /bin/sh ${USER}
- 编绎
docker build -t mine/neovim:0.1 .
插件安装
- 根据个人习惯,安装插件.
- 首先必须的Plug插件管理器
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
- 其它插件
Plug 'xolox/vim-colorscheme-switcher' "换colorscheme利器
Plug 'flazz/vim-colorschemes' "各种colorscheme大杂烩
Plug 'roxma/vim-paste-easy'
Plug 'easymotion/vim-easymotion' "精确移动
" ==== vim-lsp related 自动补全语法相关 ====
Plug 'prabirshrestha/async.vim'
Plug 'prabirshrestha/vim-lsp'
Plug 'prabirshrestha/asyncomplete.vim'
Plug 'prabirshrestha/asyncomplete-lsp.vim'
Plug 'prabirshrestha/asyncomplete-buffer.vim'
Plug 'prabirshrestha/asyncomplete-file.vim'
Plug 'ryanolsonx/vim-lsp-typescript'
Plug 'ryanolsonx/vim-lsp-python'
Plug 'prabirshrestha/asyncomplete-tscompletejob.vim'
Plug 'leafgarland/typescript-vim' "typescript 语法,tscompletejob依赖此项
Plug 'yami-beta/asyncomplete-omni.vim'
Plug 'felixfbecker/php-language-server', {'do': 'composer install && composer run-script parse-stubs'}
au User lsp_setup call lsp#register_server({
\ 'name': 'php-language-server',
\ 'cmd': {server_info->['php', expand('~/.vim/plugged/php-language-server/bin/php-language-server.php')]},
\ 'whitelist': ['php'],
\ })
if executable('go-langserver')
au User lsp_setup call lsp#register_server({
\ 'name': 'go-langserver',
\ 'cmd': {server_info->['go-langserver', '-mode', 'stdio']},
\ 'whitelist': ['go'],
\ })
endif
if executable('docker-langserver')
au User lsp_setup call lsp#register_server({
\ 'name': 'docker-langserver',
\ 'cmd': {server_info->[&shell, &shellcmdflag, 'docker-langserver --stdio']},
\ 'whitelist': ['dockerfile'],
\ })
endif
启动设置
每次从image开始启动打开nvim太慢了.严重影响体验.解决办法就是让neovim的container跑在后台,用的时候打开neovim; 设置启动脚本如下:
#!/bin/bash
exist=`docker ps -a|grep neovim`
if [[ ! "$exist" =~ .*neovim.* ]] ; then
echo "docker neovim not exist"
docker run -d -t -v $HOME:/home/njs --user $USER --name neovim mine/neovim:0.1 sh -c 'crond -f'
fi
docker exec -it --user $USER neovim bash -c "cd $PWD; nvim"
将脚本nv路径放到$PATH, 启动.
入坑指南
似乎大功告成,但是图样图森破, 会遇到以下坑.
- nvim启动时,窗口会默认为 80x24的小窗口.
经过很长时间摸索,发现和环境变量LINES和ROWS有关.在container里,这两个变量缺失.解决办法就是resize.
NAME
resize - set environment and terminal settings to current xterm window size
再mount时X11后,还可以让container支持gui; 改进启动脚本nv如下:
docker exec -e DISPLAY -e TERM -e COLUMNS=$COLUMNS -e LINES=$LINES -it --user $USER neovim sh -c "cd $PWD; resize; nvim"
- 复制粘贴问题. 在host上, 用"+y复制,但是在nvim里是不行的, 因为nvim在container里.解决办法是利用xclip; 先改启动脚本nv, 将x11的socket mount进去, 使container支持GUI.
docker run -d -t -v $HOME:/home/你的名字 -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -e TERM --user 你的名字 --name neovim mine/neovim:0.1 sh -c 'crond -f'
然后在nvim里,选中文字后,执行:
:'<,'>w !xclip -selection clipboard
做成快捷映射
vnoremap <leader><leader>y :'<,'>w !xclip -selection clipboard<cr>
我的leader key为空格,按下 空格空格y, 复制完成.