vim-lsp icon indicating copy to clipboard operation
vim-lsp copied to clipboard

Disable capabilities of individual language servers

Open JaRoSchm opened this issue 1 year ago • 7 comments

Hi, would it be possible to add an option for each language server to disable certain capabilities? This would be helpful if one uses multiple language servers for one language. This is supported by neovim and an example of an application can be found here, which is exactly the problem I have atm.

JaRoSchm avatar Oct 20 '23 09:10 JaRoSchm

Added an additional option in the fork here https://github.com/sullivan-sean/vim-lsp to override the lsp#get_server_capabilities function. It also exposes the default implementation of this function so that you can modify the capabilities that are returned from the init request.

It returns an object that is internal to vim-lsp so it's best to deepcopy when overriding this function if you plan to mutate in a way that matters.

Here is what I have in my .vimrc using the fork to disable certain capabilities to avoid clashing goto actions:

function! s:get_server_capabilities(server_name) abort
    let l:capabilities = deepcopy(lsp#default_get_server_capabilities(a:server_name))
    " Disable links for pyright langserver to avoid duplicate entries
    if a:server_name ==# 'pyright-langserver'
      for l:key in ['definitionProvider', 'declarationProvider', 'referencesProvider']
        if has_key(l:capabilities, l:key)
          call remove(l:capabilities, l:key)
        endif
      endfor
    endif
    return l:capabilities
endfunction

let g:lsp_get_server_capabilities = [function('s:get_server_capabilities')]

sullivan-sean avatar May 14 '24 00:05 sullivan-sean

Very happy to upstream some variation of this if you'd like to support this kind of functionality @prabirshrestha

sullivan-sean avatar May 14 '24 00:05 sullivan-sean

Thank you for working on this! I will try later to see if this fits my needs.

JaRoSchm avatar May 14 '24 09:05 JaRoSchm

You can handle them capabilities like below (without any modifications).

function! s:on_lsp_buffer_enabled() abort
  let l:capabilities = lsp#get_server_capabilities('pyright-langserver')
  if !empty(l:capabilities)
    let l:capabilities.definitionProvider = v:false
    let l:capabilities.declarationProvider = v:false
    let l:capabilities.referencesProvider = v:false
  endif
endfunction


augroup vim-lsp
  au!
  autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled()
augroup END

mattn avatar May 14 '24 14:05 mattn

Even better! thanks

sullivan-sean avatar May 14 '24 17:05 sullivan-sean

Thank you and even without changes!

JaRoSchm avatar May 14 '24 17:05 JaRoSchm

@mattn I just tried your proposed solution like this:

if executable('pylsp')
    " pip install python-language-server
    au User lsp_setup call lsp#register_server({
        \ 'name': 'pylsp',
        \ 'cmd': {server_info->['pylsp']},
        \ 'allowlist': ['python'],
        \ 'workspace_config': {'pylsp': {'plugins':
                \ {'pycodestyle': {'maxLineLength': 88}}
                \ }},
        \ })
endif

function! s:on_lsp_buffer_enabled() abort
    setlocal signcolumn=yes
    if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif
    nmap <buffer> gd <plug>(lsp-definition)
    nmap <buffer> gr <plug>(lsp-references)
    nmap <buffer> gi <plug>(lsp-implementation)
    nmap <buffer> gt <plug>(lsp-type-definition)
    nmap <buffer> <leader>rn <plug>(lsp-rename)
    nmap <buffer> [g <plug>(lsp-previous-diagnostic)
    nmap <buffer> ]g <plug>(lsp-next-diagnostic)
    nmap <buffer> K <plug>(lsp-hover)
    nmap <buffer> <leader>df <plug>(lsp-document-format)
    nmap <buffer> <leader>ca <plug>(lsp-code-action)

    let g:BASH_Ctrl_j = 'off'
    inoremap <buffer> <expr><c-j> lsp#scroll(+4)
    inoremap <buffer> <expr><c-k> lsp#scroll(-4)
    nnoremap <buffer> <expr><c-j> lsp#scroll(+4)
    nnoremap <buffer> <expr><c-k> lsp#scroll(-4)
    " refer to doc to add more commands
endfunction

augroup vim-lsp
  au!
  autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled()
augroup END

function! s:on_lsp_buffer_enabled() abort
  let l:capabilities = lsp#get_server_capabilities('pylsp')
  if !empty(l:capabilities)
    let l:capabilities.diagnosticProvider = v:false
  endif
endfunction

augroup lsp_install
    au!
    " call s:on_lsp_buffer_enabled only for languages that has the server registered.
    autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled()
augroup END

However, I still get diagnostics from pylsp. I tried to put the solution you proposed at different position in the config but this did not help. What did I get wrong?

JaRoSchm avatar May 23 '24 07:05 JaRoSchm