Ale: Map <C-]> to :ALEGoToDefinition if an LSP is active

Created on 9 Jun 2018  路  6Comments  路  Source: dense-analysis/ale

If an LSP server is active, it would be nice to map <C-]> to :ALEGoToDefinition, because it's presumably more accurate than Vim's default Ctag implementation, if the user even generates ctags..

Most helpful comment

For reference, in case anyone else wants a solution. This is how I solved it:

function ALELSPMappings()
    let l:lsp_found=0
    for l:linter in ale#linter#Get(&filetype) | if !empty(l:linter.lsp) | let l:lsp_found=1 | endif | endfor
    if (l:lsp_found)
        nnoremap <buffer> <C-]> :ALEGoToDefinition<CR>
        nnoremap <buffer> <C-^> :ALEFindReferences<CR>
    else
        silent! unmap <buffer> <C-]>
        silent! unmap <buffer> <C-^>
    endif
endfunction
autocmd BufRead,FileType * call ALELSPMappings()

All 6 comments

ALE won't define any mappings itself. You can define a mapping yourself.

@w0rp, are there any hooks when an LSP is loaded/unloaded to set the mapping conditionally?

Probably wouldn't want it mapped without an LSP active.

I recommend creating a buffer-local mapping in an ftplugin file, for a filetype you run LSP linters for. Completion can cause an LSP linter to be started, so you should set up a keybind even when the LSP linter isn't active.

For reference, in case anyone else wants a solution. This is how I solved it:

function ALELSPMappings()
    let l:lsp_found=0
    for l:linter in ale#linter#Get(&filetype) | if !empty(l:linter.lsp) | let l:lsp_found=1 | endif | endfor
    if (l:lsp_found)
        nnoremap <buffer> <C-]> :ALEGoToDefinition<CR>
        nnoremap <buffer> <C-^> :ALEFindReferences<CR>
    else
        silent! unmap <buffer> <C-]>
        silent! unmap <buffer> <C-^>
    endif
endfunction
autocmd BufRead,FileType * call ALELSPMappings()

For reference, in case anyone else wants a solution. This is how I solved it:

function ALELSPMappings()
  let l:lsp_found=0
  for l:linter in ale#linter#Get(&filetype) | if !empty(l:linter.lsp) | let l:lsp_found=1 | endif | endfor
  if (l:lsp_found)
      nnoremap <buffer> <C-]> :ALEGoToDefinition<CR>
      nnoremap <buffer> <C-^> :ALEFindReferences<CR>
  else
      silent! unmap <buffer> <C-]>
      silent! unmap <buffer> <C-^>
  endif
endfunction
autocmd BufRead,FileType * call ALELSPMappings()

You did an excellent job!
I have slightly modified your code to make it work better (also check if the lsp is executable).

function ALELSPMappings()
    let lsp_found=0
    for linter in ale#linter#Get(&filetype)
        if !empty(linter.lsp) && ale#lsp_linter#CheckWithLSP(bufnr(''), linter)
            let lsp_found=1
        endif
    endfor
    if (lsp_found)
        nnoremap <buffer> K :ALEDocumentation<cr>
        nnoremap <buffer> gr :ALEFindReferences<cr>
        nnoremap <buffer> gd :ALEGoToDefinition<cr>
        nnoremap <buffer> gy :ALEGoToTypeDefinition<cr>
        nnoremap <buffer> gh :ALEHover<cr>

        setlocal omnifunc=ale#completion#OmniFunc
    endif
endfunction

Just be aware that ale#lsp_linter#CheckWithLSP is not documented and could be changed or removed at any time, but ale#linter#Get is documented and shouldn't have any breaking changes without at least you being warned about it long before it's changed.

Was this page helpful?
0 / 5 - 0 ratings