diff options
| -rw-r--r-- | .github/workflows/vimdoc.yml | 54 | ||||
| -rw-r--r-- | doc/lspconfig.txt | 387 | ||||
| -rw-r--r-- | scripts/vimdocgen.lua | 25 |
3 files changed, 466 insertions, 0 deletions
diff --git a/.github/workflows/vimdoc.yml b/.github/workflows/vimdoc.yml new file mode 100644 index 00000000..8039f234 --- /dev/null +++ b/.github/workflows/vimdoc.yml @@ -0,0 +1,54 @@ +name: vimdoc + +on: + push: + branches: + - master + +jobs: + vimdocgen: + runs-on: [ubuntu-latest] + steps: + - uses: actions/checkout@v2 + - run: date +%F > todays-date + - name: Restore cache for today's nightly. + uses: actions/cache@v2 + with: + path: build + key: ${{ runner.os }}-appimage-${{ hashFiles('todays-date') }} + + - name: Setup neovim nightly and install plugins + run: | + test -d build || { + mkdir -p build + wget https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage + chmod +x nvim.appimage + mv nvim.appimage ./build/nvim + } + mkdir -p ~/.local/share/nvim/site/pack/vendor/start + git clone --depth 1 https://github.com/mjlbach/babelfish.nvim ~/.local/share/nvim/site/pack/vendor/start/babelfish.nvim + git clone --depth 1 https://github.com/nvim-treesitter/nvim-treesitter ~/.local/share/nvim/site/pack/vendor/start/nvim-treesitter + ln -s $(pwd) ~/.local/share/nvim/site/pack/vendor/start + + - name: Build parser + run: | + export PACKPATH=$HOME/.local/share/nvim/site + ./build/nvim -u ~/.local/share/nvim/site/pack/vendor/start/babelfish.nvim/scripts/init.lua --headless -c 'TSInstallSync markdown' -c 'qa' + - name: Generating docs + run: | + export PATH="${PWD}/build/:${PATH}" + export PACKPATH=$HOME/.local/share/nvim/site + ./build/nvim -u ~/.local/share/nvim/site/pack/vendor/start/babelfish.nvim/scripts/init.lua --headless -c 'luafile ./scripts/vimdocgen.lua' -c 'qa' + - name: Commit changes + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMMIT_MSG: | + [docgen] Update README.md + skip-checks: true + run: | + git config user.email "actions@github" + git config user.name "Github Actions" + git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git + git add README.md + # Only commit and push if we have changes + git diff --quiet && git diff --staged --quiet || (git commit -m "${COMMIT_MSG}"; git push origin HEAD:${GITHUB_REF}) diff --git a/doc/lspconfig.txt b/doc/lspconfig.txt new file mode 100644 index 00000000..202b81a0 --- /dev/null +++ b/doc/lspconfig.txt @@ -0,0 +1,387 @@ +============================================================================== +1. nvim-lspconfig *lspconfig-nvim-lspconfig* + + +Collection of common configurations for Neovim's built-in [language server client](https://neovim.io/doc/user/lsp.html). +The configurations are supported on a best-effort basis, and rely on +contributions from regular users to stay up-to-date. +This repo handles automatically launching, initializing, and configuring +language servers that are installed on your system. +============================================================================== +2. Install *lspconfig-install* + + +* Requires [Neovim HEAD/nightly](https://github.com/neovim/neovim/releases/tag/nightly) (v0.5 prerelease). The configs in this repo + assume that you are using the latest [Neovim HEAD/nightly build](https://github.com/neovim/neovim/releases/tag/nightly). + Update Neovim and nvim-lspconfig before reporting an issue. +* nvim-lspconfig is just a plugin. Install it like any other Vim plugin, e.g. with [vim-plug](https://github.com/junegunn/vim-plug): + ``` + :Plug 'neovim/nvim-lspconfig' + ``` +============================================================================== +3. Quickstart *lspconfig-quickstart* + + +1. Install a language server, e.g. [pyright](CONFIG.md#pyright) via `npm i -g pyright` +2. Install `nvim-lspconfig` via your plugin manager +3. Add the language server setup to your init.vim. The server name must match those found in the table of contents in [CONFIG.md](CONFIG.md) + +> + lua << EOF + require'lspconfig'.pyright.setup{} + EOF +< + + +4. Open a file that is placed in a directory recognized by the server +(see server configuration in [CONFIG.md](CONFIG.md); e.g., for [pyright](CONFIG.md#pyright), this is +any directory containing ".git", "setup.py", "setup.cfg", "pyproject.toml", +or "requirements.txt") +5. See [Keybindings and completion](#Keybindings-and-completion) for mapping useful functions and enabling +omnifunc completion +6. Try `:LspInfo` to see the status of active and configured language servers. +============================================================================== +4. Usage *lspconfig-usage* + + +**All provided examples are in Lua,** see `:help :lua-heredoc` to use Lua from +your init.vim, or the quickstart above for an example of a lua heredoc. +Each config provides a `setup()` function to initialize the server with +reasonable default initialization options and settings, as well as some +server-specific commands. This is invoked in the following form, where +`<server>` corresponds to the language server name in [CONFIG.md](CONFIG.md). +`setup()` takes optional arguments <config> , each of which overrides the +respective part of the default configuration. The allowed arguments are +detailed [below](#setup-function). + +> + require'lspconfig'.<server>.setup{<config>} +< + + +============================================================================== +5. Defaults *lspconfig-defaults* + + +To use the defaults, just call `setup()` with an empty `config` parameter. For +the `gopls` config, that would be: + +> + require'lspconfig'.gopls.setup{} +< + + +============================================================================== +6. Overriding defaults *lspconfig-override-defaults* + + +To set some config properties at `setup()` , specify their keys. For example to +change how the "project root" is found, set the `root_dir` key: + +> + local lspconfig = require'lspconfig' + lspconfig.gopls.setup{ + root_dir = lspconfig.util.root_pattern('.git'); + } +< + + +The [documentation](CONFIG.md) for each config lists default values and +additional optional properties. For a more complicated example overriding the +`name` , `log_level` , `message_level` , and `settings` of texlab: + +> + local lspconfig = require'lspconfig' + lspconfig.texlab.setup{ + name = 'texlab_fancy'; + settings = { + latex = { + build = { + onSave = true; + } + } + } + } +< + + +============================================================================== +7. Custom config *lspconfig-custom-config* + + +To configure a custom/private server, just +1. load the lspconfig module: `local lspconfig = require('lspconfig')`, +2. Define the config: `lspconfig.configs.foo_lsp = { … }` +3. Call `setup()`: `lspconfig.foo_lsp.setup{}` + +> + local lspconfig = require'lspconfig' + local configs = require'lspconfig/configs' + -- Check if it's already defined for when reloading this file. + if not lspconfig.foo_lsp then + configs.foo_lsp = { + default_config = { + cmd = {'/home/ashkan/works/3rd/lua-language-server/run.sh'}; + filetypes = {'lua'}; + root_dir = function(fname) + return lspconfig.util.find_git_ancestor(fname) or vim.loop.os_homedir() + end; + settings = {}; + }; + } + end + lspconfig.foo_lsp.setup{} +< + + +============================================================================== +8. Overriding defaults *lspconfig-* + + +If you want to change default configs for all servers, you can override +default_config like this. In this example, we additionally add a check for +log_level and message_level which can be passed to the server to control the +verbosity of "window/logMessage". + +> + local lspconfig = require'lspconfig' + lspconfig.util.default_config = vim.tbl_extend( + "force", + lspconfig.util.default_config, + { + autostart = false, + handlers = { + ["window/logMessage"] = function(err, method, params, client_id) + if params and params.type <= vim.lsp.protocol.MessageType.Log then + vim.lsp.handlers["window/logMessage"](err, method, params, client_id) + end + end; + ["window/showMessage"] = function(err, method, params, client_id) + if params and params.type <= vim.lsp.protocol.MessageType.Warning.Error then + vim.lsp.handlers["window/showMessage"](err, method, params, client_id) + end + end; + } + } + ) +< + + +============================================================================== +9. Per-server documentation *lspconfig-server-documentation* + + +See [CONFIG.md](CONFIG.md) for documentation and configuration of individual +language servers. This document contains installation instructions for each +language server, and is auto-generated from the documentation in the lua +source. Do not submit PRs modifying CONFIG.md directly; CONFIG.md will be +overwritten by docgen +**You do not need to copy settings or init_options from this configuration into +your config** +============================================================================== +10. The wiki *lspconfig-wiki* + + +The following maps most of the standard functions to keybindings, and maps +omnicomplete to use the lsp.omnifunc. See `:help lsp` for more details + +> + lua << EOF + local nvim_lsp = require('lspconfig') + local on_attach = function(client, bufnr) + local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end + local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end + + buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') + + -- Mappings. + local opts = { noremap=true, silent=true } + buf_set_keymap('n', 'gD', '<Cmd>lua vim.lsp.buf.declaration()<CR>', opts) + buf_set_keymap('n', 'gd', '<Cmd>lua vim.lsp.buf.definition()<CR>', opts) + buf_set_keymap('n', 'K', '<Cmd>lua vim.lsp.buf.hover()<CR>', opts) + buf_set_keymap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts) + buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts) + buf_set_keymap('n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts) + buf_set_keymap('n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts) + buf_set_keymap('n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts) + buf_set_keymap('n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts) + buf_set_keymap('n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts) + buf_set_keymap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts) + buf_set_keymap('n', '<space>e', '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics()<CR>', opts) + buf_set_keymap('n', '[d', '<cmd>lua vim.lsp.diagnostic.goto_prev()<CR>', opts) + buf_set_keymap('n', ']d', '<cmd>lua vim.lsp.diagnostic.goto_next()<CR>', opts) + buf_set_keymap('n', '<space>q', '<cmd>lua vim.lsp.diagnostic.set_loclist()<CR>', opts) + + -- Set some keybinds conditional on server capabilities + if client.resolved_capabilities.document_formatting then + buf_set_keymap("n", "<space>f", "<cmd>lua vim.lsp.buf.formatting()<CR>", opts) + elseif client.resolved_capabilities.document_range_formatting then + buf_set_keymap("n", "<space>f", "<cmd>lua vim.lsp.buf.range_formatting()<CR>", opts) + end + + -- Set autocommands conditional on server_capabilities + if client.resolved_capabilities.document_highlight then + vim.api.nvim_exec([[ + hi LspReferenceRead cterm=bold ctermbg=red guibg=LightYellow + hi LspReferenceText cterm=bold ctermbg=red guibg=LightYellow + hi LspReferenceWrite cterm=bold ctermbg=red guibg=LightYellow + augroup lsp_document_highlight + autocmd! * <buffer> + autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight() + autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references() + augroup END + ]], false) + end + end + + -- Use a loop to conveniently both setup defined servers + -- and map buffer local keybindings when the language server attaches + local servers = { "pyright", "rust_analyzer", "tsserver" } + for _, lsp in ipairs(servers) do + nvim_lsp[lsp].setup { on_attach = on_attach } + end + EOF +< + + +============================================================================== +11. The wiki *lspconfig-the-wiki* + + +Please see the [wiki](https://github.com/neovim/nvim-lspconfig/wiki) for +additional topics, including: +* [Installing language servers automatically](https://github.com/neovim/nvim-lspconfig/wiki/Installing-language-servers-automatically) +* [Snippets support](https://github.com/neovim/nvim-lspconfig/wiki/Snippets-support) +* [Project local settings](https://github.com/neovim/nvim-lspconfig/wiki/Project-local-settings) +* [Recommended plugins for enhanced language server features](https://github.com/neovim/nvim-lspconfig/wiki/Language-specific-plugins) +and more. +============================================================================== +12. Manual control *lspconfig-manual-control* + + +If you would like to manually managing starting language servers, but still +have new buffers within a root directory autoattach to running servers, pass +`autostart = false` to your `.setup{}` call for a language server and call +`:lua require('lspconfig').language_server_name.autostart()`. +This function can also be used to restart a workspace after stopping a language +server with `:lua vim.lsp.stop_client(client_id)`. +============================================================================== +13. setup() function *lspconfig-setup()-function* + + +Only the following arguments can be passed to the setup function: + +> + lspconfig.SERVER.setup{config} + + The `config` parameter has the same shape as that of + |vim.lsp.start_client()|, with these additions and changes: + + {root_dir} + Required for some servers, optional for others. + Function of the form `function(filename, bufnr)`. + Called on new candidate buffers being attached-to. + Returns either a root_dir or nil. + + If a root_dir is returned, then this file will also be attached. You + can optionally use {filetype} to help pre-filter by filetype. + + If a root_dir is returned which is unique from any previously returned + root_dir, a new server will be spawned with that root_dir. + + If nil is returned, the buffer is skipped. + + See |lspconfig.util.search_ancestors()| and the functions which use it: + - |lspconfig.util.root_pattern(pattern1, pattern2...)| is a variadic function which + takes string patterns as arguments, and finds an ancestor + which contains one of the files matching the pattern. + Each pattern can be a specific filename, such as ".git", or a glob. + See `:help glob` for allowed patterns. This is equivalent to + coc.nvim's "rootPatterns" + - Related utilities for common tools: + - |lspconfig.util.find_git_root()| + - |lspconfig.util.find_node_modules_root()| + - |lspconfig.util.find_package_json_root()| + + {name} + Defaults to the server's name. + + {filetypes} + Set of filetypes to filter for consideration by {root_dir}. + May be empty. + Server may specify a default value. + + {autostart} + Whether to automatically start a language server when a matching filetype is detected. + Defaults to true. + + {settings} + Map with case-sensitive keys corresponding to `workspace/configuration` + event responses. + We also notify the server *once* on `initialize` with + `workspace/didChangeConfiguration`. + If you change the settings later on, you must emit the notification + with `client.workspace_did_change_configuration({settings})` + Example: `settings = { keyName = { subKey = 1 } }` + + {on_attach} + `function(client, bufnr)` Runs the on_attach function from the client's + config if it was defined. Useful for doing buffer-local setup. + + {on_new_config} + `function(new_config, new_root_dir)` will be executed after a new configuration has been + created as a result of {root_dir} returning a unique value. You can use this + as an opportunity to further modify the new_config or use it before it is + sent to |vim.lsp.start_client()|. If you set a custom `on_new_config`, ensure that + `new_config.cmd = cmd` is present within the function body. +< + + +============================================================================== +14. Debugging *lspconfig-debugging* + + +The two most common points of failure are +1. The language server is not installed. You should be able to run the `cmd` +defined in each lua module from the command line. +2. Not triggering root detection. The language server will only start if it +is opened in a directory, or child directory, containing a file which signals +the *root* of the project. Most of the time, this is a `.git` folder, but each server +defines the root config in the lua file. +:LspInfo provides a handy overview of your active and configured language +servers. Note, that it will not report any configuration changes applied in +`on_new_config`. +Before reporting a bug, check your logs and the output of `:LspInfo`. Add the +following to your init.vim to enable logging + +> + lua << EOF + vim.lsp.set_log_level("debug") + EOF +< + + +Attempt to run the language server, and open the log with: + +> + :lua vim.cmd('e'..vim.lsp.get_log_path()) +< + + +Most of the time, the reason for failure is present in the logs. +============================================================================== +15. Contributions *lspconfig-contributions* + + +If you are missing a language server on the list in [CONFIG.md](CONFIG.md) , +contributing a new configuration for it would be appreciated. You can follow +these steps: +1. Read [CONTRIBUTING.md](CONTRIBUTING.md). +2. Choose a language from [the coc.nvim wiki](https://github.com/neoclide/coc.nvim/wiki/Language-servers) or + [emacs-lsp](https://github.com/emacs-lsp/lsp-mode#supported-languages). +3. Create a new file at `lua/lspconfig/SERVER_NAME.lua`. + - Copy an [existing config](https://github.com/neovim/nvim-lspconfig/blob/master/lua/lspconfig/) + to get started. Most configs are simple. For an extensive example see + [texlab.lua](https://github.com/neovim/nvim-lspconfig/blob/master/lua/lspconfig/texlab.lua). +4. Ask questions on our [Discourse](https://neovim.discourse.group/c/7-category/7) or in [Neovim Gitter](https://gitter.im/neovim/neovim). +vim:tw=78:ts=8:ft=help:norl:
\ No newline at end of file diff --git a/scripts/vimdocgen.lua b/scripts/vimdocgen.lua new file mode 100644 index 00000000..9e1d060d --- /dev/null +++ b/scripts/vimdocgen.lua @@ -0,0 +1,25 @@ +local docgen = require('babelfish') + +local docs = {} + +docs.generate = function() + local metadata = { + input_file = "./README.md", + output_file = "./doc/lspconfig.txt", + project_name = "lspconfig", + header_aliases = { + ["Example: using the defaults"] = {"Defaults", "defaults"}, + ["Example: override some defaults"] = {"Overriding defaults", "override-defaults"}, + ["Example: custom config"] = {"Custom config", "custom-config"}, + ["Example: override default config for all servers"] = {"Overriding defaults", ""}, + ["Individual server settings and initialization options"] = { "Per-server documentation", "server-documentation"}, + ["Keybindings and completion"] = {"The wiki", "wiki"}, + ["Manually starting (or restarting) language servers"] = {"Manual control", "manual-control"} + } + } + docgen.generate_readme(metadata) +end + +docs.generate() + +return docs |
