prabirshrestha / vim-lsp

async language server protocol plugin for vim and neovim
MIT License
3.06k stars 301 forks source link

Disable capabilities of individual language servers #1505

Open JaRoSchm opened 8 months ago

JaRoSchm commented 8 months ago

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.

sullivan-sean commented 1 month ago

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 commented 1 month ago

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

JaRoSchm commented 1 month ago

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

mattn commented 1 month ago

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
sullivan-sean commented 1 month ago

Even better! thanks

JaRoSchm commented 1 month ago

Thank you and even without changes!

JaRoSchm commented 1 month ago

@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?