From 52a4bc45488cb1f626b02be5512cd0301cd48cb8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 27 Apr 2025 13:40:46 -0700 Subject: docs: lsp, emoji, startup #33446 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maria José Solano --- runtime/lua/vim/_meta/options.lua | 12 ++++++++++-- runtime/lua/vim/fs.lua | 25 +++++++++++++------------ runtime/lua/vim/lsp.lua | 36 ++++++++++++++++++++++++------------ runtime/lua/vim/lsp/buf.lua | 3 +-- runtime/lua/vim/lsp/client.lua | 4 +++- runtime/lua/vim/lsp/log.lua | 23 ++++++++++++++++++++++- 6 files changed, 73 insertions(+), 30 deletions(-) (limited to 'runtime/lua/vim') diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 1e0e40a3a3..b06334ba31 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -2084,6 +2084,15 @@ vim.bo.et = vim.bo.expandtab --- - 'exrc' can execute any code; editorconfig only specifies settings. --- - 'exrc' is Nvim-specific; editorconfig works in other editors. --- +--- To achieve project-local LSP configuration: +--- 1. Enable 'exrc'. +--- 2. Place LSP configs at ".nvim/lsp/*.lua" in your project root. +--- 3. Create ".nvim.lua" in your project root directory with this line: +--- +--- ```lua +--- vim.cmd[[set runtimepath+=.nvim]] +--- ``` +--- --- This option cannot be set from a `modeline` or in the `sandbox`, for --- security reasons. --- @@ -6442,8 +6451,7 @@ vim.o.stc = vim.o.statuscolumn vim.wo.statuscolumn = vim.o.statuscolumn vim.wo.stc = vim.wo.statuscolumn ---- When non-empty, this option determines the content of the status line. ---- Also see `status-line`. +--- Sets the `status-line`. --- --- The option consists of printf style '%' items interspersed with --- normal text. Each status line item is of the form: diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index 8862afc760..1a99627347 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -6,7 +6,7 @@ --- --- >lua --- if vim.uv.fs_stat(file) then ---- vim.print("file exists") +--- vim.print('file exists') --- end --- < @@ -19,21 +19,21 @@ local sysname = uv.os_uname().sysname:lower() local iswin = not not (sysname:find('windows') or sysname:find('mingw')) local os_sep = iswin and '\\' or '/' ---- Iterate over all the parents of the given path. +--- Iterate over all the parents of the given path (not expanded/resolved, the caller must do that). --- --- Example: --- --- ```lua --- local root_dir --- for dir in vim.fs.parents(vim.api.nvim_buf_get_name(0)) do ---- if vim.fn.isdirectory(dir .. "/.git") == 1 then +--- if vim.fn.isdirectory(dir .. '/.git') == 1 then --- root_dir = dir --- break --- end --- end --- --- if root_dir then ---- print("Found git repository at", root_dir) +--- print('Found git repository at', root_dir) --- end --- ``` --- @@ -55,7 +55,7 @@ function M.parents(start) start end ---- Return the parent directory of the given path +--- Gets the parent directory of the given path (not expanded/resolved, the caller must do that). --- ---@since 10 ---@generic T : string|nil @@ -234,16 +234,17 @@ end --- Examples: --- --- ```lua ---- -- list all test directories under the runtime directory ---- local test_dirs = vim.fs.find( ---- {'test', 'tst', 'testdir'}, ---- {limit = math.huge, type = 'directory', path = './runtime/'} +--- -- List all test directories under the runtime directory. +--- local dirs = vim.fs.find( +--- { 'test', 'tst', 'testdir' }, +--- { limit = math.huge, type = 'directory', path = './runtime/' } --- ) --- ---- -- get all files ending with .cpp or .hpp inside lib/ ---- local cpp_hpp = vim.fs.find(function(name, path) +--- -- Get all "lib/*.cpp" and "lib/*.hpp" files, using Lua patterns. +--- -- Or use `vim.glob.to_lpeg(…):match(…)` for glob/wildcard matching. +--- local files = vim.fs.find(function(name, path) --- return name:match('.*%.[ch]pp$') and path:match('[/\\]lib$') ---- end, {limit = math.huge, type = 'file'}) +--- end, { limit = math.huge, type = 'file' }) --- ``` --- ---@since 10 diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index a117217f17..55a5ab6cf4 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -282,15 +282,16 @@ end --- If not provided, then the client will attach to all filetypes. --- @field filetypes? string[] --- ---- Directory markers (.e.g. '.git/') where the LSP server will base its workspaceFolders, ---- rootUri, and rootPath on initialization. Unused if `root_dir` is provided. +--- Directory markers (.e.g. '.git/') where the LSP server will base its workspaceFolders, rootUri, +--- and rootPath on initialization. Unused if `root_dir` is provided. --- @field root_markers? string[] --- ---- Directory where the LSP server will base its workspaceFolders, rootUri, and ---- rootPath on initialization. If a function, it is passed the buffer number ---- and a callback argument which must be called with the value of root_dir to ---- use. The LSP server will not be started until the callback is called. ---- @field root_dir? string|fun(bufnr: integer, cb:fun(root_dir?:string)) +--- [lsp-root_dir()]() Directory where the LSP server will base its workspaceFolders, rootUri, and +--- rootPath on initialization. The function form receives a buffer number and `on_dir` callback, +--- which must be called to provide root_dir as a string. LSP will not be activated for the buffer +--- unless `on_dir` is called; thus a `root_dir()` function can dynamically decide whether to +--- activate (or skip) LSP per-buffer. See example at |vim.lsp.enable()|. +--- @field root_dir? string|fun(bufnr: integer, on_dir:fun(root_dir?:string)) --- --- Predicate used to decide if a client should be re-used. Used on all --- running clients. The default implementation re-uses a client if name and @@ -538,16 +539,27 @@ local function lsp_enable_callback(bufnr) end end ---- Enable an LSP server to automatically start when opening a buffer. ---- ---- Uses configuration defined with `vim.lsp.config`. +--- Auto-starts LSP when a buffer is opened, based on the |lsp-config| `filetypes`, `root_markers`, +--- and `root_dir` fields. --- --- Examples: --- --- ```lua ---- vim.lsp.enable('clangd') +--- vim.lsp.enable('clangd') +--- vim.lsp.enable({'luals', 'pyright'}) +--- ``` +--- +--- Example: To _dynamically_ decide whether LSP is activated, define a |lsp-root_dir()| function +--- which calls `on_dir()` only when you want that config to activate: --- ---- vim.lsp.enable({'luals', 'pyright'}) +--- ```lua +--- vim.lsp.config('lua_ls', { +--- root_dir = function(bufnr, on_dir) +--- if not vim.fn.bufname(bufnr):match('%.txt$') then +--- on_dir(vim.fn.getcwd()) +--- end +--- end +--- }) --- ``` --- ---@since 13 diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index e6ffc8360e..aac9965f42 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -1211,8 +1211,7 @@ local function on_code_action_results(results, opts) vim.ui.select(actions, select_opts, on_user_choice) end ---- Selects a code action available at the current ---- cursor position. +--- Selects a code action (LSP: "textDocument/codeAction" request) available at cursor position. --- ---@param opts? vim.lsp.buf.code_action.Opts ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index a362287570..cd78bab3e8 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -63,7 +63,9 @@ local validate = vim.validate --- folder in this list. See `workspaceFolders` in the LSP spec. --- @field workspace_folders? lsp.WorkspaceFolder[] --- ---- (default false) Server requires a workspace (no "single file" support). +--- (default false) Server requires a workspace (no "single file" support). Note: Without +--- a workspace, cross-file features (navigation, hover) may or may not work depending on the +--- language server, even if the server doesn't require a workspace. --- @field workspace_required? boolean --- --- Map overriding the default capabilities defined by |vim.lsp.protocol.make_client_capabilities()|, diff --git a/runtime/lua/vim/lsp/log.lua b/runtime/lua/vim/lsp/log.lua index e28a856215..2dccd86ecd 100644 --- a/runtime/lua/vim/lsp/log.lua +++ b/runtime/lua/vim/lsp/log.lua @@ -1,4 +1,25 @@ --- Logger for language client plugin. +--- @brief +--- The `vim.lsp.log` module provides logging for the Nvim LSP client. +--- +--- When debugging language servers, it is helpful to enable extra-verbose logging of the LSP client +--- RPC events. Example: +--- ```lua +--- vim.lsp.set_log_level 'trace' +--- require('vim.lsp.log').set_format_func(vim.inspect) +--- ``` +--- +--- Then try to run the language server, and open the log with: +--- ```vim +--- :lua vim.cmd('tabnew ' .. vim.lsp.get_log_path()) +--- ``` +--- +--- (Or use `:LspLog` if you have nvim-lspconfig installed.) +--- +--- Note: +--- - Remember to DISABLE verbose logging ("debug" or "trace" level), else you may encounter +--- performance issues. +--- - "ERROR" messages containing "stderr" only indicate that the log was sent to stderr. Many +--- servers send harmless messages via stderr. local log = {} -- cgit