-
Notifications
You must be signed in to change notification settings - Fork 273
Clangd
Clangd is an implementation of the Language Server Protocol leveraging Clang. Clangd’s goal is to provide language “smartness” features like code completion, find references, etc. for clients such as C/C++ Editors.
Most package managers and major distributions provide a way to install tools from clang-tools-extra which includes Clangd. If you can't find instructions for your workspace below, consider checking Installing Clangd section.
macOS Homebrew:
brew install --with-toolchain llvm
For Arch Linux you can just install Clang package which comes with
clang-tools-extra
:
pacman -Syu clang
Debian-based Linux distributions provide clang-tools package (e.g. Debian package and Ubuntu package):
apt-get install clang-tools
let g:LanguageClient_serverCommands = {
\ 'cpp': ['clangd'],
\ }
LanguageClient-neovim
has multiple options for the completion management:
For best experience, it is advised to use deoplete
. This is one of the most
advanced completion manager which is very flexible and has numerous nice-to-have
features such as snippets integration (if you are a
UltiSnips user please proceed to
UltiSnips Integration).
You can install it via
if has('nvim')
Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
else
Plug 'Shougo/deoplete.nvim'
Plug 'roxma/nvim-yarp'
Plug 'roxma/vim-hug-neovim-rpc'
endif
let g:deoplete#enable_at_startup = 1
Also, by default LanguageClient-neovim
comes without key bindings. Since it is
easier to use key bindings for the source code navigation, it is advised to set up
a custom set of shortcuts. Suggested way of a consistent setup with the <leader> key:
function SetLSPShortcuts()
nnoremap <leader>ld :call LanguageClient#textDocument_definition()<CR>
nnoremap <leader>lr :call LanguageClient#textDocument_rename()<CR>
nnoremap <leader>lf :call LanguageClient#textDocument_formatting()<CR>
nnoremap <leader>lt :call LanguageClient#textDocument_typeDefinition()<CR>
nnoremap <leader>lx :call LanguageClient#textDocument_references()<CR>
nnoremap <leader>la :call LanguageClient_workspace_applyEdit()<CR>
nnoremap <leader>lc :call LanguageClient#textDocument_completion()<CR>
nnoremap <leader>lh :call LanguageClient#textDocument_hover()<CR>
nnoremap <leader>ls :call LanguageClient_textDocument_documentSymbol()<CR>
nnoremap <leader>lm :call LanguageClient_contextMenu()<CR>
endfunction()
augroup LSP
autocmd!
autocmd FileType cpp,c call SetLSPShortcuts()
augroup END
This will ensure that LSP shortcuts are enabled only for source files in C++ or
C. If you use other language servers for LanguageClient-neovim
, just add
more filetypes to the autocmd
.
Another great addition to the setup is FZF
integration. It will enable user to use fuzzy matching for something like
searching through workspace or document symbols. For FZF
,
LanguageClient-neovim
will take care of the configuration. All user has to
do is to install the plugin:
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'
echodoc can handle the function signatures displaying:
Plug 'Shougo/echodoc.vim'
set cmdheight=2
let g:echodoc#enable_at_startup = 1
let g:echodoc#type = 'signature'
signcolumn
will appear each time Clangd sends a warning or
provides a diagnostic and the text will be shifted by one column each time
signcolumn
is triggered. To prevent this shift and always show the
signcolumn
, use
" Always draw the signcolumn.
set signcolumn=yes
For documentation, see LanguageClient.txt
or simply call :help LanguageClient
.
If you encounter a bug and you are able to reproduce it, Clangd developers would appreciate a bug submission. Please use LLVM Bugzilla for the bug reports. To help diagnose the problem, you can attach log files and the Mirror File (which stores the LSP input passed to Clangd).
To store stderr
output, you can redirect stderr
to a file and use
LanguageClient#debugInfo()
function:
let g:LanguageClient_serverStderr = '/tmp/clangd.stderr'
function SetLSPShortcuts()
" ...
" Previous bindings
" ...
nnoremap <leader>ll :call LanguageClient#debugInfo()<CR>
endfunction()
Clangd can provide global completion when given a global static index. This index is not rebuilt during the editing process which means that if a significant part of the codebase is changed you would have to rebuild it to reflect these changes.
To build the global static index, you can use experimental clangd-indexer tool. If have copied the compile_commands.json to the source directory, call:
clangd-indexer -executor=all-TUs /path/to/project > index.yaml
After the index is produced, you can pass it to Clangd via
-yaml-symbol-file
:
let g:LanguageClient_serverCommands = {
\ 'cpp': ['clangd', '-yaml-symbol-file=/path/to/index.yaml',],
\ }
The global static index infrastructure is experimental, so please be aware that you might encounter some bugs. If you do, please submit a bug report to help make the infrastructure better.
If you are interested in Clangd development or have any questions, consider using clangd-dev Mailing List.