golang, gopls, lsp, vim, editor
About gopls
この記事はもともと reveal.js のスライドとして公開していた内容を、記事として書き起こしたものです
これからの Go のコード補完について。
プログラミングにコード補完は欠かせない
gocode から gopls へ。
gocode の話については mattn さんの記事 が面白いです。
gocode
コード補完用の daemon が走り、unix domain socket を通じてエディタはコードの内容を渡す。vim-goの場合
1gocode -sock unix -f vim ...
gocode の変遷(オリジナル)

gocode の変遷(go 1.10 対応)

gocode の変遷(go mod 対応)

bingo
language server protocol 対応 github.com/saibing/bingo

golsp
Go チームがついに標準化へ動き始めた。golang.org/x/tools/cmd/golsp
しかし、その後、gopls へ rename…
そして今! gopls
go please と読むそうだ。まだ alpha (!!!)
そもそも language server protocol (lsp) とは
language server protocol (json RPC) を使って、コード補完やフォーマット、rename に対応。
1{
2 "jsonrpc":"2.0",
3 "method":"workspace/configuration",
4 "params":{"items":[
5 {"scopeUri":"file:///Users/amasuda/go/src/github.com/go-zen-chu/observable-server","section":"gopls"},
6 {"scopeUri":"file:///Users/amasuda/go/src/github.com/go-zen-chu/observable-server",
7 "section":"gopls-/Users/amasuda/go/src/github.com/go-zen-chu/observable-server"}
8 ]},
9 "id":2
10}
gopls の設定を json rpc で行っている。
gopls と editor

vim-go からの利用
vim-go ではデフォルトで gopls が有効化されている。下記のような関数
1function! go#lsp#Completion(fname, line, col, handler) abort
2 call go#lsp#DidChange(a:fname)
3 let l:lsp = s:lspfactory.get()
4 let l:msg = go#lsp#message#Completion(a:fname, a:line, a:col)
5 let l:state = s:newHandlerState('completion')
6 let l:state.handleResult = funcref('s:completionHandler', [function(a:handler, [], l:state)], l:state)
7 let l:state.error = funcref('s:completionErrorHandler', [function(a:handler, [], l:state)], l:state)
8 return l:lsp.sendMessage(l:msg, l:state)
9endfunction
vim-go で gopls を debug mode & tcp で起動する。
1let g:go_debug = ['lsp']
2let g:go_gocode_socket_type = 'tcp'
tcp mode で gopls を起動すると、localhost でデバッグ用の UI が見られる。
1$ lsof -iTCP -sTCP:LISTEN
2COMMAND PID USER FD TYPE NODE NAME
3vim 68987 amasuda 3u IPv4 TCP localhost:49470 (LISTEN)
4gopls 69001 amasuda 7u IPv4 TCP localhost:49469 (LISTEN)
そして、prometheus exporter も立っている
2020年は… gopls!
FIN