tabnine是一个在GPT-2的基础上构建的AI自动补全插件,它可以做到基于语义补全,详细见杀手级AI补代码工具问世,支持23种语言及5种主流编辑器,程序员沸腾了。我在安装使用遇到了诸多问题。

  1. Plug安装插件hang住
  2. 安装完插件,vim闪退
  3. brew更新vim失败
  4. Semantic Completion遇到问题
  5. 安装配置cquery

第一个问题 - 安装插件

Plug 'zxqfl/tabnine-vim' " AI自动补全

PlugInstall后遇到了第一个问题,一直hang住:

+ tabnine-vim: remote: Compressing objects: 100% (4496/4496), done.

会不会是Plug的问题?于是我尝试手动安装插件,发现是tabnine-vim比较大而且网络很差导致需要长时间clone仓库,而PlugInstall的过程中没有显示下载进度,所以看起来像是hang住了。为了便于管理,我还是用PlugInstall挂一晚上安装成功。

第二个问题 - 尝试使用

安装完tabnine-vim后用vim打开一个文件,vim闪退并报类似下面的错误:

Vim: Caught deadly signal SEGV
Error detected while processing function 81_PollServerReady[7]..81_Pyeval:Vim: Finished.

line 4:
Exception MemoryError: MemoryError() in <module 'threading' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.pyc'> ignored

有点懵逼,在tabnine-vim的issue页看到了这个issue:Vim: Caught deadly signal SEGV #12,这个用户在更新macOS到Mojave 10.14后也遇到了这个问题,于是他选择将vim切换为neovim,并关闭了issue(颇有我的做事风格)。

emmmm虽然没有解决问题,但好歹知道了应该是Mojave 10.14与vim的问题。

第三个问题 - 更新Vim

我找到了这个博客:Vim 报错:Caught deadly signal SEGV,可能是因为某些插件运行需要vim支持lua等,但当前vim版本不支持,需要更新vim:

» brew install vim

更新失败,报了个Error:

Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink share/man/de/man1/ex.1
/usr/local/share/man/de/man1 is not writable.

再次懵逼,看起来好像是权限相关的问题,这个issue与我的情况很像:Error: The brew link step did not complete successfully#10

可能是由于一些软件通过非Homebrew安装(比如.pkg安装程序,make install等),造成的/usr/local不是Homebrew期望的user-writable权限。可以用brew doctor列出目录中没有由Homebrew链接的/usr/local/[a-z]*文件。

修复Error log中的/usr/local/share/man/de/man1的用户权限:

» sudo chown $USER:admin /usr/local/share/man/de/man1
# 这里 $USER 需要手动修改为用户名,因为sudo会将其替换为 root

重新链接vim:

» brew link vim
Linking /usr/local/Cellar/vim/8.1.1800... 163 symlinks created

然后第二个问题也消失了。

第四个问题 - 开始使用TabNine

装好后迫不及待上手试试,autocomplete显示如下:

  1 #inc
~    include
~    TabNine was unable to start the cpp semantic completion backend.
~    The command tried was: `cquery --init={"cacheDirectory": "${project_root}/.cquery_cache"}`
~    This means you need to install the backend manually.
~    For help, see tabnine.com/semantic.
~    Or, type TabNine::no_sem to disable semantic completion for C/C++.
~    (TabNine works well even without semantic completion.)

上面提示cpp的semantic completion并没有启用,需要手动安装cquery后端。

官网tabnine.com/semantic上说明TabNine与语言无关,它需要依赖其他语言服务器(提供语言服务通信Language Server Protocol,LSP)来提供semantic completion:

TabNine is language agnostic, so it relies on other software to provide semantic completions. Any server which implements the Language Server Protocol can be used as a source of semantic completions.

于是为了能用上semantic completion,需要先安装配置C++的语言服务器,cquery。

第五个问题 - 安装配置cquery

LSP是什么

这里有着较为详细的解释:代码编辑器系列 #1 架构与解耦。简单的说,代码编辑器(Vim类)把代码编辑与代码分析解耦,编辑器只负责编辑,而代码分析交给另一个程序,这种策略所采用的协议叫做Language Server Protocol(LSP)。LSP Server并不是http Server 那样的常驻后台服务,而是一个个命令行程序,由编辑器(也就是客户端)启动,通过管道发送 JSON RPC 命令同 LSP Server 交流,退出编辑器,LSP 服务端也就关闭了。

安装配置

我大致按照参考了这个:Vim 8 中 C/C++ 符号索引:LSP 篇

首先安装LSP服务端cquery,这个很简单,brew一下就好了。

brew install cquery

其次要安装LanguageClient-neovim,LanguageClient-neovim是Vim用于支持LSP的插件。

Plug 'autozimu/LanguageClient-neovim', {'branch': 'next', 'do': 'bash install.sh'}

按照上面那篇知乎专栏进行配置:

" LSP
let g:LanguageClient_loadSettings = 1
let g:LanguageClient_diagnosticsEnable = 0
let g:LanguageClient_settingsPath = expand('/Users/barriery/.vim/languageclient.json')
let g:LanguageClient_selectionUI = 'quickfix'
let g:LanguageClient_diagnosticsList = v:null
let g:LanguageClient_hoverPreview = 'Never'
let g:LanguageClient_serverCommands = {}
let g:LanguageClient_serverCommands.c = ['cquery']
let g:LanguageClient_serverCommands.cpp = ['cquery']
noremap <leader>rd :call LanguageClient#textDocument_definition()<cr>
noremap <leader>rr :call LanguageClient#textDocument_references()<cr>
noremap <leader>rv :call LanguageClient#textDocument_hover()<cr>

配置中涉及到一个额外的 languageclient.json 文件,内容就是指定下 cache 目录:

{
    "initializationOptions": {"cacheDirectory": "/tmp/.cquery_cache"}
}

最后打开TabNine的配置文件(<TabNine::config_dir>/ExampleTabNine.toml,可以新建一个toml文件对默认配置进行覆盖),找到c++语言服务器配置进行修改:

[language.cpp]
command = "/usr/local/bin/cquery"
args = ["--init={\"cacheDirectory\": \"/tmp/.cquery_cache\"}"]

现在就可以愉快的用TabNine辣(马耶炒鸡好用):

Deep TabNine演示

还有一个问题是,本地版模型需要的算力比较大,可以看到写个最简单的程序左上角CPU就飙到80+%,风扇呼呼得响。心疼电脑的话还是用云端模型叭(哭唧唧):

TabNine Cloud

Addition

  1. 我在TabNine官网上发现了这句话:

    The Vim client for TabNine is based on YouCompleteMe.

    而问题二与问题三是YouCompleteMe引起的。

  2. 可以安装Neofetch,可以在终端输出系统信息,利于在网上寻求帮助:

» neofetch
                    'c.          barriery@barrierys-MBP
                 ,xNMM.          ----------------------
               .OMMMMo           OS: macOS Mojave 10.14.5 18F203 x86_64
               OMMM0,            Host: MacBookPro15,1
     .;loddo:' loolloddol;.      Kernel: 18.6.0
   cKMMMMMMMMMMNWMMMMMMMMMM0:    Uptime: 1 day, 9 hours, 34 mins
 .KMMMMMMMMMMMMMMMMMMMMMMMWd.    Packages: 48 (brew)
 XMMMMMMMMMMMMMMMMMMMMMMMX.      Shell: zsh 5.3
;MMMMMMMMMMMMMMMMMMMMMMMM:       Resolution: 1680x1050
:MMMMMMMMMMMMMMMMMMMMMMMM:       DE: Aqua
.MMMMMMMMMMMMMMMMMMMMMMMMX.      WM: Quartz Compositor
 kMMMMMMMMMMMMMMMMMMMMMMMMWd.    WM Theme: Blue (Dark)
 .XMMMMMMMMMMMMMMMMMMMMMMMMMMk   Terminal: iTerm2
  .XMMMMMMMMMMMMMMMMMMMMMMMMK.   Terminal Font: Monaco 13
    kMMMMMMMMMMMMMMMMMMMMMMd     CPU: Intel i7-8750H (12) @ 2.20GHz
     ;KMMMMMMMWXXWMMMMMMMk.      GPU: Intel UHD Graphics 630, Radeon Pro 555X
       .cooc,.    .,coo:.        Memory: 9582MiB / 16384MiB