Index: clang-tools-extra/docs/clangd-vim.rst =================================================================== --- /dev/null +++ clang-tools-extra/docs/clangd-vim.rst @@ -0,0 +1,209 @@ +====================== +Clangd Vim integration +====================== + +.. contents:: + +.. toctree:: + :maxdepth: 1 + +:program:`Clangd` can be used within (Neo)Vim. + +Vim LSP plugins +=============== + +There are several existing LSP plugins for (Neo)Vim, most notably: + +* `LanguageClient-neovim `_ + is probably the one getting most traction at the moment. It supports more + features than its counterparts and also works better for NeoVim users + (despite the name it also works for regular Vim). +* `vim-lsc `_ provides convenient key + bindings and has a lot of options, but lacks few important features such as + `code formatting `_ which can + be used instead to invoke + `Clang-Format `_. +* `vim-lsp `_ is another (Neo)Vim + async plugin which offers LSP integration, but it also lacks several features + like `code actions `_ ( + needed for applying Fix-Its). + +Given that `LanguageClient-neovim` supports more features at the moment, this +document will focus on setting up this plugin in your (Neo)Vim. + +Configuring `LanguageClient-neovim` +=================================== + +You can see the generic setup guide in `plugin's README +`_. +Here we will focus on a way to build a complete :program:`Clangd` setup. + +The recommended way of installing plugins is `vim-plug +`_ which offers various ``Plug`` options +used for easier plugin setup. + +.. code-block:: vim + + Plug 'autozimu/LanguageClient-neovim', { + \ 'branch': 'next', + \ 'do': 'bash install.sh', + \ } + +Next step is to specify :program:`Clangd` invokation command. The easiest way to +do that is just telling ``LanguageClient-neovim`` to run :program:`clangd` +binary (assuming it is already in the ``$PATH``): + +.. code-block:: vim + + let g:LanguageClient_serverCommands = { + \ 'cpp': ['clangd'], + \ } + +That's all, this is a complete ``LanguageClient-neovim`` setup! However, it is +recommended to use few other plugins and setup custom key bindings for better +user experience. Please refer to the `Recommended Settings` section. + +Recommended Settings +==================== + +``LanguageClient-neovim`` has multiple options for the completion management: + +* `deoplete `_ +* `ncm2 `_ +* Vim's ``omnifunc`` (used by default) + +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). You can install it via + +.. code-block:: vim + + 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. Typing +``call LanguageClient#textDocument_rename()`` each time user would like to +rename a symbol is not the best experience. Suggested way of a consistent setup +with the ` key +`_: + +.. code-block:: vim + + function SetLSPShortcuts() + nnoremap ld :call LanguageClient#textDocument_definition() + nnoremap lr :call LanguageClient#textDocument_rename() + nnoremap lf :call LanguageClient#textDocument_formatting() + nnoremap lt :call LanguageClient#textDocument_typeDefinition() + nnoremap lx :call LanguageClient#textDocument_references() + nnoremap la :call LanguageClient_workspace_applyEdit() + nnoremap lc :call LanguageClient#textDocument_completion() + nnoremap lm :call LanguageClient#LanguageClient_contextMenu() + nnoremap lh :call LanguageClient#textDocument_hover() + nnoremap ls :call LanguageClient_textDocument_documentSymbol() + 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: + +.. code-block:: vim + + Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } + Plug 'junegunn/fzf.vim' + +`echodoc `_ can handle the function +signatures displaying: + +.. code-block:: vim + + Plug 'Shougo/echodoc.vim' + + set cmdheight=2 + let g:echodoc#enable_at_startup = 1 + let g:echodoc#type = 'signature' + + +``signcolumn`` will appear each time :program:`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 + +.. code-block:: vim + + " Always draw the signcolumn. + set signcolumn=yes + + +For documentation, see `LanguageClient.txt +` +or simply call ``:help LanguageClient``. + +Troubleshooting +=============== + +If you encounter a bug and you are able to reproduce it, :program:`Clangd` +developers would appreciate a bug submission. To help diagnose the problem, you +can attach log files and the Mirror File (which stores the LSP input passed to +:prgram:`Clangd`). + +To store ``stderr`` output, you can redirect ``stderr`` to a file and use +``LanguageClient#debugInfo()`` function: + +.. code-block:: vim + + let g:LanguageClient_serverStderr = '/tmp/clangd.stderr' + + function SetLSPShortcuts() + " ... + " Previous bindings + " ... + nnoremap ll :call LanguageClient#debugInfo() + endfunction() + +Bonus: Building Global Static Index +=================================== + +:program:`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 +:program:`global-symbol-builder` tool. If have copied the +`compile_commands.json` to the source directory, call: + +.. code-block:: console + + global-symbol-builder -executor=all-TUs /path/to/project > llvm-index.yaml + +After the index is produced, you can pass it to :program:`Clangd` via +``-yaml-symbol-file``: + +.. code-block:: vim + + let g:LanguageClient_serverCommands = { + \ 'cpp': ['clangd', '-yaml-symbol-file=/path/to/llvm-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. Index: clang-tools-extra/docs/clangd.rst =================================================================== --- clang-tools-extra/docs/clangd.rst +++ clang-tools-extra/docs/clangd.rst @@ -108,6 +108,14 @@ | Gen. Getters/Setters | No | No | +-------------------------------------+------------+----------+ + +Vim Integration +=============== + +For more information on how to setup :program:`Clangd` for :program:`vim`, +please see `Clangd Vim integration page +`_. + Getting Involved ==================