reversed(top()) code tags rss about

Using Sumneko Lua Language Server in Vim via vim-lsp

November 21, 2022
[vim] [issue] [howto] [lua]

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 or Lua.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.