I finally decided to give LSP a try in my Vim for the purpose of getting completion in Lua. I kinda hate that decision by now, but there are some results to show and I want to document all the shit I had to deal with along with a working configuration.
Prerequisites
Vim version 8 or newer.
Installed vim-lsp and Sumneko Lua Language Server. The SlackBuild for the latter was accepted by https://slackbuilds.org.
Working setup for Slackware 15.0
For your vimrc
:
" don't start the server until LspEnable command (defined below) let g:lsp_auto_enable = 0 " don't need random things popping up and disrupting anything let g:lsp_diagnostics_enabled = 0 let g:lsp_document_code_action_signs_enabled = 0 " don't distract by highlighting matching symbols automatically let g:lsp_document_highlight_enabled = 0 " not using folding, no need to have it enabled let g:lsp_fold_enabled = 0 " default is the value of 'ignorecase', which didn't mean to affect completion let g:lsp_ignorecase = v:false " don't wait for completion too long let g:lsp_completion_resolve_timeout = 100 " untitled buffer is likely to be in an inappropriate place for the server to " create workspace let g:lsp_untitled_buffer_enabled = 0 if executable('lua-language-server') command -nargs=0 LspEnable call lsp#enable() autocmd User lsp_setup call lsp#register_server({ \ 'name': 'lua-language-server', \ 'cmd': {server_info -> ['lua-language-server']}, \ 'workspace_config': { \ 'Lua' : { \ 'workspace.userThirdParty': [$HOME.'/.vim/rcs/lls'], \ 'workspace.library': [$HOME.'/.vim/rcs/lls/vifm/library'], \ 'completion.keywordSnippet': 'Disable', \ 'Lua.runtime.version': 'Lua 5.4', \ } \ }, \ 'allowlist': ['lua'], \ }) endif function! s:on_lsp_buffer_enabled() abort setlocal omnifunc=lsp#complete endfunction augroup lsp_install autocmd! autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled() augroup END
Some details
allowlist
is a doubly stupid name for a list of filetypes for which the given
server should be activated.
'lua-language-server'
in cmd
key is a command, you can add more arguments
there, for example:
\ 'cmd': {server_info -> ['lua-language-server', '--loglevel=trace']},
The whole construct there is a lambda with server_info
being a parameter name.
The configuration of vim-lsp is limited to completion only, although :Lsp*
commands should still be available. Will extend the configuration if needed,
there are code navigation and other features that might be useful.
Usage
You can put custom third-party libraries to ~/.vim/rcs/lls
(edit path to your
liking; use a repo like this). The issue is that the server
will not use them automatically, will annoy you with prompts about whether a
particular third-party library is needed and will create .luarc.json
files to
save the settings. If you don’t want that, you can set workspace.library
setting as above to include specific libraries you want to have enabled all the
time.
Resolved issues
Starting the server
--logpath
and --metapath
have bad defaults for Linux, they try to use
directories next to the binary (like on Windows), so one needs to to point
these paths to some other (writable) location to start the server (--logpath
)
and have completion for Lua’s builtins (--metapath
). This can be solved
during packaging.
Passing parameters to the server
Make sure to not mess up parameter names! If you do, the server won’t complain
as it simply ignores unknown parameters. Also --param=value
form must be
used, --param value
doesn’t work!
Configuring the server
The Wiki page describing available settings has this warning:
All of these settings should be prefixed with
Lua.
, e.g.Lua.completion.enable
orLua.diagnostics.globals
when editing a configuration file.
You might think this doesn’t apply to workspace configuration passed by the client as I did, but it does!
Configuring the client
Based on another page from the Wiki I thought that
Lua: workspace.userThirdParty
and Lua.workspace.userThirdParty
in the
configuration are always equivalent, but at least for vim-lsp they aren’t.
Configuration of vim-lsp must look like this:
\ 'workspace_config': { \ 'Lua' : { \ 'workspace.userThirdParty': [ $HOME.'/.vim/rcs/lls' ], \ } \ },
And NOT like this:
\ 'workspace_config': { \ 'Lua.workspace.userThirdParty': [ $HOME.'/.vim/rcs/lls' ], \ },
Reported issues
Using --configpath
creates a recursive inotify which can easily exhaust
inotify resource (GitHub issue). After figuring out the part
about “Lua.” prefix I dropped --configpath
, so inotify isn’t used for config
for me, but the issue is still there.
Remaining issues
Completion includes keywords while I didn’t ask for it. Sometimes
there is also text completion, which I don’t want to see on hitting
Ctrl-XCtrl-O because there are separate mappings for that.
Snippets were also initially included, but setting completion.keywordSnippet
got rid of them.
If I open a Lua file in several instances of Vim, the server will be launched multiple times. I thought there will be only one server at most.
There is a builtin option to not enable LSP automatically, but no command to do it manually, WTF?
Was it worth the trouble?
Not sure about that, but maybe it will get better.