> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/serenityOS/serenity/llms.txt
> Use this file to discover all available pages before exploring further.

# Vim, Emacs, and Other Editors

> Configure terminal-based editors for SerenityOS development

SerenityOS can be developed using various terminal-based editors with clangd integration for code comprehension.

<Tabs>
  <Tab title="Vim">
    ## Vim Configuration

    Vim can be configured with the [YouCompleteMe](https://github.com/ycm-core/YouCompleteMe) plugin to provide code completion.

    ### Setup

    <Steps>
      <Step title="Install YouCompleteMe">
        Follow the [installation instructions](https://github.com/ycm-core/YouCompleteMe#installation) for your platform.
      </Step>

      <Step title="Whitelist Configuration File">
        Add the following to your `.vimrc` file:

        ```vim theme={null}
        let g:ycm_extra_conf_globlist = ['~/serenity/.ycm_extra_conf.py']
        ```

        This whitelists the configuration file included in the SerenityOS repository.
      </Step>
    </Steps>

    ### Features

    With YouCompleteMe configured, you'll have:

    * Code completion
    * Jump to definition
    * Error/warning diagnostics
    * Semantic highlighting
  </Tab>

  <Tab title="Neovim">
    ## Neovim Configuration

    Neovim can be configured with [COC-clangd](https://github.com/clangd/coc-clangd) for code completion and [git-blame](https://github.com/f-person/git-blame.nvim) for inline git information.

    <Note>
      Make sure you've run `Meta/serenity.sh run` at least once before configuring Neovim.
    </Note>

    ### Install vim-plug

    See [https://github.com/junegunn/vim-plug](https://github.com/junegunn/vim-plug) for installation instructions.

    ### Install coc.nvim

    <Steps>
      <Step title="Add Plugin to init.vim">
        The config file is at `~/.config/nvim/init.vim` or `$XDG_CONFIG_HOME/nvim/init.vim`.

        Add the plugin:

        ```vim theme={null}
        Plug 'neoclide/coc.nvim', { 'branch': 'release' }
        ```
      </Step>

      <Step title="Install Plugin">
        Run inside nvim:

        ```vim theme={null}
        :PlugInstall
        ```
      </Step>
    </Steps>

    ### Install coc-clangd

    <Steps>
      <Step title="Install via CocInstall">
        ```vim theme={null}
        :CocInstall coc-clangd
        ```
      </Step>

      <Step title="Install clangd (if needed)">
        If you don't have clangd installed:

        ```vim theme={null}
        :CocCommand clangd.install
        ```

        This installs a separate clangd version just for neovim.

        <Note>
          This guide is tested with clangd version 14.0.6 and 15.0.6.
        </Note>
      </Step>
    </Steps>

    ### Configure coc-clangd

    Edit `~/.config/nvim/coc-settings.json` or run `:CocConfig`:

    ```json theme={null}
    {
        "clangd.fallbackFlags": ["-std=c++26"],
        "clangd.arguments": ["--query-driver=${workspaceFolder}/Toolchain/Local/**/*"],
        "semanticTokens.enable": true,
        "inlayHint.subSeparator": "︴",
        "inlayHints.enableParameter": true,
        "clangd.inlayHints.sep": "⇝"
    }
    ```

    <Warning>
      * If you had another C++ language server configured, remove it first to avoid conflicts
      * If you configured `clangd` as a languageServer in `coc-settings.json`, remove it to avoid running clangd twice
      * `clangd.inlayHints.sep` breaks on clangd 15.0.6
    </Warning>

    ### Formatting

    Install the formatter plugin:

    ```vim theme={null}
    Plug 'mhartington/formatter.nvim'
    ```

    Configure in Lua to use clang-format for C++ files:

    ```lua theme={null}
    require("formatter").setup{
        filetype = {
            cpp = {
                require("formatter.filetypes.cpp").clangformat
            }
        }
    }
    ```

    ### Git Blame (Optional)

    <Steps>
      <Step title="Add Plugin">
        ```vim theme={null}
        Plug 'f-person/git-blame.nvim'
        ```
      </Step>

      <Step title="Install Plugin">
        ```vim theme={null}
        :PlugInstall
        ```
      </Step>
    </Steps>

    ### Complete init.vim Configuration

    <Accordion title="View complete init.vim excerpt">
      ```vim theme={null}
      "IMPORTANT: the leader key for <leader> keycombos
      let mapleader = "\\"

      "BEGIN: git blame (optional)
      hi GitBlame guifg=#7b7b7b
      let g:gitblame_date_format = '%d.%m.%y %H:%M'
      let g:gitblame_highlight_group = 'GitBlame'
      let g:gitblame_message_when_not_committed = 'You: Uncommitted changes'
      let g:gitblame_message_template = '   <author> (<committer>), <date> <sha> • <summary>'
      "END: git blame

      "BEGIN: coc
      "inline hints (depending on clangd version one or another gets used)
      hi CocHintVirtualText guifg=#84afe0
      hi CocInlayHint guifg=#84afe0 guibg=#393939
      hi CocInlayHintParameter guifg=#84afe0 guibg=#393939
      hi CocInlayHintType guifg=#89ddff guibg=#393939

      "semantic highlighting
      hi CocSemMethod guifg=#bfaa87 gui=bold
      hi CocSemFunction guifg=#bfaaf7 gui=bold
      hi CocSemParameter guifg=#a9bfd1 gui=underline
      hi CocSemVariable guifg=#8edbdb
      hi CocSemProperty guifg=#23ce6d
      hi link CocSemEnumMember Constant
      hi link CocSemEnum CocSemClass
      hi Constant guifg=#f78c6c
      hi CocSemClass guifg=#89ddff
      hi Statement guifg=#c792ea
      hi Type guifg=#db954a


      "remap keys for applying refactor code actions (on warnings) (\re)
      nmap <silent> <leader>re <Plug>(coc-codeaction-refactor)
      xmap <silent> <leader>r  <Plug>(coc-codeaction-refactor-selected)
      nmap <silent> <leader>r  <Plug>(coc-codeaction-refactor-selected)

      "outline for file (\o)
      nmap <silent><nowait> <leader>o :<C-u>CocList outline<cr>

      "goto definition etc.
      nmap <silent> gd <Plug>(coc-definition)
      nmap <silent> gt <Plug>(coc-type-definition)
      nmap <silent> gi <Plug>(coc-implementation)
      nmap <silent> gr <Plug>(coc-references)

      "coc rename (\rn)
      nmap <leader>rn <Plug>(coc-rename)

      "prev or next error
      nmap <silent> [g <Plug>(coc-diagnostic-prev)
      nmap <silent> ]g <Plug>(coc-diagnostic-next)

      "confirm coc-suggestion with enter
      imap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm() : "\<CR>"

      "ctrl+space for completion
      imap <silent><expr> <c-space> coc#refresh()

      "show documentation with ctrl+k
      nmap <silent><c-k> :call ShowDocumentation()<CR>

      "show documentation if it's available
      function! ShowDocumentation()
        if CocAction('hasProvider', 'hover')
          call CocActionAsync('doHover')
        else
          call feedkeys('K', 'in')
        endif
      endfunction

      "coc-clangd switch between header and source
      nmap <silent>gs :CocCommand clangd.switchSourceHeader vsplit<CR>
      "END: coc
      ```
    </Accordion>

    ### Configure .clangd

    Configure `.clangd` as explained in [ClangdConfiguration](ClangdConfiguration.md).
  </Tab>

  <Tab title="Emacs">
    ## Emacs Configuration

    Emacs can be configured with `lsp-mode` and `clangd` for excellent SerenityOS development support.

    ### clangd Setup

    The official clangd extension provides C++ comprehension. See [ClangdConfiguration](ClangdConfiguration.md) for configuration details.

    There are several ways to specify which clangd to use:

    * **Default**: `lsp-mode` will find and use your system `clangd` (easiest, but may be outdated)
    * **Manual path**: Specify any clangd binary with `lsp-clangd-binary-path`
    * **Managed installation**: Use `lsp-install-server` to let `lsp-mode` manage the installation

    ### lsp-mode Configuration

    ```lisp theme={null}
    (use-package lsp-mode
      :hook ((c++-mode) . lsp-deferred)
      :commands lsp
      :config
      ;; clangd arguments, refer to ClangdConfiguration.md for what other arguments may be needed.
      (setq lsp-clients-clangd-args '("-j=4" "-background-index" "--log=error" "--clang-tidy" "--enable-config"))
      ;; Optionally, set the location of clangd -- See above for options.
      (setq lsp-clangd-binary-path "/usr/bin/clangd"))
    ```

    ### clang-format Integration

    There are multiple packages for auto-formatting with clang-format:

    * [format-all-mode](https://github.com/lassik/emacs-format-all-the-code)
    * [clang-format-plus](https://github.com/SavchenkoValeriy/emacs-clang-format-plus)

    #### Alternative: Use lsp-mode for Formatting

    You can format without additional packages by using `lsp-mode`. Create `.dir-locals.el` in the project root:

    ```lisp theme={null}
    ((c++-mode
      (eval add-hook 'before-save-hook #'lsp-format-buffer nil t)))
    ```

    This automatically formats C++ files on save.
  </Tab>

  <Tab title="Helix">
    ## Helix Configuration

    Helix comes with support for `clangd` and `clang-format` out of the box!

    ### Setup

    See [ClangdConfiguration](ClangdConfiguration.md) for how to configure clangd.

    To configure clangd command-line arguments, create `.helix/languages.toml` in the project root:

    ```toml theme={null}
    [language-server.serenity]
    command = "clangd"
    # clangd arguments, refer to ClangdConfiguration.md for what may be needed.
    args = []

    [[language]]
    name = "cpp"
    language-servers = ["serenity"]
    ```

    ### Features

    Helix provides out of the box:

    * Code completion via clangd
    * Jump to definition
    * Find references
    * Automatic formatting with clang-format
    * Syntax highlighting
    * Error diagnostics
  </Tab>
</Tabs>

## Common clangd Configuration

All editors using clangd should configure it according to [ClangdConfiguration](ClangdConfiguration.md) for optimal SerenityOS development support.
