Vim is a powerful text editor that I like to use for its flexibility and customizability. One of the most useful features of Vim is its ability to easily install plugins to gain functionality, here navigating through code sources using the clangd language server. In this article, I will explain how to configure Vim for easy code source browsing with clangd.
compile_commands.json
Depending on your build system, it might be very easy to create a compile_commands.json to be used by clang tools. If you are using cmake, it is as easy as defining the flag CMAKE_EXPORT_COMPILE_COMMANDS.
direnv
If you are not using direnv already, I highly recommand it: it enables setting and cleaning environnement variables as you change directories in a console.
Here is an .envrc file to put at the root of your source directory, that will automatically set the CLANGD_FLAGS used by clangd to find the appropriate compile-commands.
export CLANGD_FLAGS="--compile-commands-dir=$PWD/path_to_compile_commands_dir/".vimrc
" Add clangd completion, please set CLANGD_FLAGS with direnv
Plugin 'prabirshrestha/vim-lsp'
" https://github.com/prabirshrestha/vim-lsp/blob/e74bd3c986484845a4b87e5aa013773d52030a75/doc/vim-lsp.txt#LL218C27-L218C58
" If you are using vim set `let g:lsp_use_native_client = 1` and make sure you
let g:lsp_use_native_client = 1
let g:lsp_diagnostics_enabled = 1
let g:lsp_diagnostics_virtual_text_prefix = "> "
let g:lsp_inlay_hints_enabled = 1
let g:lsp_preview_float = 0 " disable float, as it is hard for focusing
" selectively override settings when a buffer is compatible with lsp
function! s:on_lsp_buffer_enabled() abort
" setlocal omnifunc=lsp#complete
" setlocal signcolumn=yes
" set foldmethod=expr
" \ foldexpr=lsp#ui#vim#folding#foldexpr()
" \ foldtext=lsp#ui#vim#folding#foldtext()
" if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif
" nmap <buffer> gd <plug>(lsp-definition)
" nmap <buffer> gs <plug>(lsp-document-symbol-search)
" nmap <buffer> gS <plug>(lsp-workspace-symbol-search)
" 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)
" nnoremap <buffer> <expr><c-f> lsp#scroll(+4)
" nnoremap <buffer> <expr><c-d> lsp#scroll(-4)
" let g:lsp_format_sync_timeout = 1000
" autocmd! BufWritePre *.rs,*.go call execute('LspDocumentFormatSync')
" refer to doc to add more commands
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
augroup lsp_float_colours
autocmd!
if !has('nvim')
autocmd User lsp_float_opened
\ call setwinvar(lsp#document_hover_preview_winid(),
\ '&wincolor', 'PopupWindow')
else
autocmd User lsp_float_opened
\ call nvim_win_set_option(
\ lsp#document_hover_preview_winid(),
\ 'winhighlight', 'Normal:PopupWindow')
endif
augroup end
let g:lsp_hover_ui = 'preview'
" see :he pclose for help on shortcuts to close the preview window
Plugin 'prabirshrestha/asyncomplete-lsp.vim'
Plugin 'piec/vim-lsp-clangd'
let g:lsp_clangd_ignore_warning = 0
"export CLANGD_FLAGS="--compile-commands-dir=$PWD/build"Now, you can do :Lsp<tab> to get a list of what commands one can use. I really like K to display information about functions, or variables in the preview window. One can also use LspDefinition to jump to definition when vanilla tags is not enough.
By following these simple steps, you can configure Vim for easy code source browsing with clangd. With clangd, you can quickly and easily navigate through your code, find the information you need, and stay productive.