diff options
28 files changed, 257 insertions, 219 deletions
diff --git a/.editorconfig b/.editorconfig index 0d54d6cb33..6e551f77ad 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,6 +10,9 @@ insert_final_newline = true [*.{c,h,in,lua}] max_line_length = 100 +[src/nvim/eval.lua] +max_line_length = 68 + [*.py] indent_size = 4 diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index b120c09468..89f218c5be 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -672,8 +672,7 @@ nvim_eval_statusline({str}, {opts}) *nvim_eval_statusline()* true. Each element of the array is a |Dict| with these keys: • start: (number) Byte index (0-based) of first character that uses the highlight. - • group: (string) Name of highlight group. May be removed in the - future, use `groups` instead. + • group: (string) Deprecated. Use `groups` instead. • groups: (array) Names of stacked highlight groups (highest priority last). diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index eaa1b608ce..413802eea1 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -446,26 +446,25 @@ CompleteChanged *CompleteChanged* *CompleteDonePre* CompleteDonePre After Insert mode completion is done. Either - when something was completed or abandoning - completion. |ins-completion| - |complete_info()| can be used, the info is - cleared after triggering CompleteDonePre. - The |v:completed_item| variable contains - information about the completed item. + when something was completed or discarded. + |ins-completion| + |complete_info()| is valid during this event. + |v:completed_item| gives the completed item. *CompleteDone* CompleteDone After Insert mode completion is done. Either - when something was completed or abandoning - completion. |ins-completion| - |complete_info()| cannot be used, the info is - cleared before triggering CompleteDone. Use + when something was completed or discarded. + |ins-completion| + |complete_info()| is cleared before this; use CompleteDonePre if you need it. - |v:completed_item| gives the completed item. + |v:completed_item| gives the completed item, + or empty dict if completion was discarded. Sets these |v:event| keys: complete_word The word that was selected, empty if - abandoned complete. + completion was + abandoned (discarded). complete_type |complete_info_mode| reason Reason for completion being done. Can be one of: @@ -474,7 +473,7 @@ CompleteDone After Insert mode completion is done. Either - "cancel": completion was stopped by |complete_CTRL-E. - "discard": completion was - ended for other reason. + abandoned for other reason. *CursorHold* CursorHold When the user doesn't press a key for the time diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index ae7fa8bcf9..80ce36d948 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -1038,12 +1038,13 @@ chdir({dir}) *chdir()* (`string`) cindent({lnum}) *cindent()* - Get the amount of indent for line {lnum} according the C - indenting rules, as with 'cindent'. + Get the amount of indent for line {lnum} according the + |C-indenting| rules, as with 'cindent'. The indent is counted in spaces, the value of 'tabstop' is relevant. {lnum} is used just like in |getline()|. When {lnum} is invalid -1 is returned. - See |C-indenting|. + + To get or set indent of lines in a string, see |vim.text.indent()|. Parameters: ~ • {lnum} (`integer`) @@ -4902,6 +4903,8 @@ indent({lnum}) *indent()* |getline()|. When {lnum} is invalid -1 is returned. + To get or set indent of lines in a string, see |vim.text.indent()|. + Parameters: ~ • {lnum} (`integer|string`) @@ -5903,9 +5906,8 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]]) *maparg()* When {abbr} is there and it is |TRUE| use abbreviations instead of mappings. - When {dict} is there and it is |TRUE| return a dictionary - containing all the information of the mapping with the - following items: *mapping-dict* + When {dict} is |TRUE|, return a dictionary describing the + mapping, with these items: *mapping-dict* "lhs" The {lhs} of the mapping as it would be typed "lhsraw" The {lhs} of the mapping as raw bytes "lhsrawalt" The {lhs} of the mapping as raw bytes, alternate @@ -7500,6 +7502,7 @@ prompt_setcallback({buf}, {expr}) *prompt_setcallback()* endif endfunc call prompt_setcallback(bufnr(), function('s:TextEntered')) +< Parameters: ~ • {buf} (`integer|string`) @@ -10223,7 +10226,9 @@ stdioopen({opts}) *stdioopen()* stdpath({what}) *stdpath()* *E6100* Returns |standard-path| locations of various default files and - directories. + directories. The locations are driven by |base-directories| + which you can configure via |$NVIM_APPNAME| or the `$XDG_…` + environment variables. {what} Type Description ~ cache String Cache directory: arbitrary temporary diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt index 9e44f54e6b..f7cbf7fd36 100644 --- a/runtime/doc/change.txt +++ b/runtime/doc/change.txt @@ -282,9 +282,9 @@ gr{char} Replace the virtual characters under the cursor with most CTRL-keys, cannot be used. *gr-default* - Nvim creates default mappings with "gr" as a prefix, - which may inhibit the behavior of |gr|. Use the - following to restore the builtin behavior: > + Nvim creates |lsp-defaults| mappings which may inhibit + the builtin behavior of |gr|. Use this to restore the + builtin behavior: > nnoremap <nowait> gr gr < diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index f1d287b1bb..46af8801a5 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -747,9 +747,9 @@ Man Open the manpage for the <cWORD> (man buffers) Man! Display the current buffer contents as a manpage. |:Man| accepts command modifiers. For example, to use a vertical split: >vim - :vertical Man printf + :vertical Man printf To reuse the current window: >vim - :hide Man printf + :hide Man printf Local mappings: K or CTRL-] Jump to the manpage for the <cWORD> under the @@ -769,25 +769,30 @@ Variables: empty. Enabled by default. Set |FALSE| to enable soft wrapping. -To use Nvim as a manpager: >sh - export MANPAGER='nvim +Man!' +To use Nvim as a manpager: >bash + export MANPAGER='nvim +Man!' Note that when running `man` from the shell and with that `MANPAGER` in your environment, `man` will pre-format the manpage using `groff`. Thus, Nvim will inevitably display the manual page as it was passed to it from stdin. One of the caveats of this is that the width will _always_ be hard-wrapped and not -soft wrapped as with `g:man_hardwrap=0`. You can set in your environment: >sh - export MANWIDTH=999 +soft wrapped as with `g:man_hardwrap=0`. You can set in your environment: >bash + export MANWIDTH=999 So `groff`'s pre-formatting output will be the same as with `g:man_hardwrap=0` i.e soft-wrapped. -To disable bold highlighting: > - :highlight link manBold Normal +To disable bold highlighting: >vim + :highlight link manBold Normal -An alternative to using `MANPAGER` in shell can be redefined `man`, for example: >sh - man() { - nvim "+hide Man $1" - } +Troubleshooting: + +If you see an error like: > + fuse: mount failed: Permission denied +this may be caused by AppArmor sandboxing. To fix this, add a local override +in e.g. `/etc/apparmor.d/local/usr.bin.man`: >bash + mount fstype=fuse.nvim options=(ro, nosuid, nodev) -> /tmp/**, + /usr/bin/fusermount Ux, +See also https://github.com/neovim/neovim/issues/30268 . MARKDOWN *ft-markdown-plugin* diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 9216255185..23780dd177 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -255,24 +255,23 @@ FAQ *lsp-faq* ================================================================================ LSP API *lsp-api* -LSP core API is described at |lsp-core|. Those are the core functions for -creating and managing clients. +The |lsp-core| API provides core functions for creating and managing clients. +The |lsp-buf| functions perform operations for LSP clients attached to the +current buffer. -The `vim.lsp.buf_…` functions perform operations for all LSP clients attached -to the given buffer. |lsp-buf| - -LSP request/response handlers are implemented as Lua functions (see -|lsp-handler|). *lsp-method* - Requests and notifications defined by the LSP specification are referred to as -"LSP methods". The Nvim LSP client provides default handlers in the global -|vim.lsp.handlers| table, you can list them with this command: >vim +"LSP methods". These are handled by Lua |lsp-handler| functions. + +The |vim.lsp.handlers| global table defines default handlers (only for +server-to-client requests/notifications, not client-to-server). Note: depends +on server support; they won't run if your server doesn't support them. + +You can list them with: >vim :lua vim.print(vim.tbl_keys(vim.lsp.handlers)) < -They are also listed below. Note that handlers depend on server support: they -won't run if your server doesn't support them. +They are also listed below. - `'callHierarchy/incomingCalls'` - `'callHierarchy/outgoingCalls'` @@ -345,12 +344,18 @@ Each response handler has this signature: > Handlers can be set by (in increasing priority): *vim.lsp.handlers* +- Directly calling a LSP method via |Client:request()|. This is the only way + to "override" the default client-to-server request handling (by + side-stepping `vim.lsp.buf` and related interfaces). >lua + local client = assert(vim.lsp.get_clients()[1]) + client:request('textDocument/definition') + - Setting a field in `vim.lsp.handlers`. This global table contains the default mappings of |lsp-method| names to handlers. (Note: only for server-to-client requests/notifications, not client-to-server.) Example: >lua vim.lsp.handlers['textDocument/publishDiagnostics'] = my_custom_diagnostics_handler -< + - Passing a {handlers} parameter to |vim.lsp.start()|. This sets the default |lsp-handler| for a specific server. (Note: only for server-to-client requests/notifications, not client-to-server.) @@ -361,7 +366,7 @@ Handlers can be set by (in increasing priority): ['textDocument/publishDiagnostics'] = my_custom_server_definition }, } -< + - Passing a {handler} parameter to |vim.lsp.buf_request_all()|. This sets the |lsp-handler| ONLY for the given request(s). Example: >lua @@ -1276,12 +1281,12 @@ Lua module: vim.lsp.client *lsp-client* config that was passed to |vim.lsp.start()|. You can use this to modify parameters before they are sent. - • {on_init}? (`elem_or_list<fun(client: vim.lsp.Client, initialize_result: lsp.InitializeResult)>`) + • {on_init}? (`elem_or_list<fun(client: vim.lsp.Client, init_result: lsp.InitializeResult)>`) Callback invoked after LSP "initialize", where `result` is a table of `capabilities` and anything else the server may send. For example, - clangd sends `initialize_result.offsetEncoding` - if `capabilities.offsetEncoding` was sent to it. + clangd sends `init_result.offsetEncoding` if + `capabilities.offsetEncoding` was sent to it. You can only modify the `client.offset_encoding` here before any notifications are sent. • {on_exit}? (`elem_or_list<fun(code: integer, signal: integer, client_id: integer)>`) @@ -1431,6 +1436,10 @@ Client:supports_method({method}, {bufnr}) *Client:supports_method()* ============================================================================== Lua module: vim.lsp.buf *lsp-buf* +The `vim.lsp.buf_…` functions perform operations for LSP clients attached to +the current buffer. + + *vim.lsp.ListOpts* Fields: ~ @@ -1816,6 +1825,28 @@ save({lenses}, {bufnr}, {client_id}) *vim.lsp.codelens.save()* ============================================================================== Lua module: vim.lsp.completion *lsp-completion* +The `vim.lsp.completion` module enables insert-mode completion driven by an +LSP server. Call `enable()` to make it available through Nvim builtin +completion (via the |CompleteDone| event). Specify `autotrigger=true` to +activate "auto-completion" when you type any of the server-defined +`triggerCharacters`. + +Example: activate LSP-driven auto-completion: >lua + vim.lsp.start({ + name = 'ts_ls', + cmd = …, + on_attach = function(client, bufnr) + vim.lsp.completion.enable(true, client.id, bufnr, { + autotrigger = true, + convert = function(item) + return { abbr = item.label:gsub('%b()', '') } + end, + }) + end, + }) +< + + *vim.lsp.completion.BufferOpts* Fields: ~ @@ -1839,7 +1870,7 @@ enable({enable}, {client_id}, {bufnr}, {opts}) |vim.lsp.completion.BufferOpts|. trigger() *vim.lsp.completion.trigger()* - Trigger LSP completion in the current buffer. + Triggers LSP completion once in the current buffer. ============================================================================== @@ -2026,9 +2057,10 @@ Lua module: vim.lsp.util *lsp-util* • {title}? (`string`) • {title_pos}? (`'left'|'center'|'right'`) • {relative}? (`'mouse'|'cursor'|'editor'`) (default: `'cursor'`) - • {anchor_bias}? (`'auto'|'above'|'below'`, default: `'auto'`) - - "auto": place window based on which side of the - cursor has more lines + • {anchor_bias}? (`'auto'|'above'|'below'`, default: `'auto'`) Adjusts + placement relative to cursor. + • "auto": place window based on which side of the + cursor has more lines • "above": place the window above the cursor unless there are not enough lines to display the full window height. diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index e8543b5ece..c184e4792d 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -575,7 +575,7 @@ Example: File-change detection *watch-file* *inotify-limitations* When on Linux you may need to increase the maximum number of `inotify` watches and queued events as the default limit can be too low. To increase the limit, -run: >sh +run: >bash sysctl fs.inotify.max_user_watches=494462 < This will increase the limit to 494462 watches and queued events. These lines @@ -1075,13 +1075,12 @@ vim.stricmp({a}, {b}) *vim.stricmp()* vim.ui_attach({ns}, {options}, {callback}) *vim.ui_attach()* WARNING: This feature is experimental/unstable. - Attach to |ui-events|, similar to |nvim_ui_attach()| but receive events as - Lua callback. Can be used to implement screen elements like popupmenu or + Subscribe to |ui-events|, similar to |nvim_ui_attach()| but receive events + in a Lua callback. Used to implement screen elements like popupmenu or message handling in Lua. - {options} should be a dictionary-like table, where `ext_...` options - should be set to true to receive events for the respective external - element. + {options} is a dict with one or more `ext_…` |ui-option|s set to true to + enable events for the respective UI element. {callback} receives event name plus additional parameters. See |ui-popupmenu| and the sections below for event format for respective @@ -1102,14 +1101,14 @@ vim.ui_attach({ns}, {options}, {callback}) *vim.ui_attach()* ns = vim.api.nvim_create_namespace('my_fancy_pum') vim.ui_attach(ns, {ext_popupmenu=true}, function(event, ...) - if event == "popupmenu_show" then + if event == 'popupmenu_show' then local items, selected, row, col, grid = ... - print("display pum ", #items) - elseif event == "popupmenu_select" then + print('display pum ', #items) + elseif event == 'popupmenu_select' then local selected = ... - print("selected", selected) - elseif event == "popupmenu_hide" then - print("FIN") + print('selected', selected) + elseif event == 'popupmenu_hide' then + print('FIN') end end) < diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 8ea05aba58..a6f5f85d37 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4295,12 +4295,12 @@ A jump table for the options with a short description can be found at |Q_op|. "g<LeftMouse>" is "<C-LeftMouse> (jump to tag under mouse click) "g<RightMouse>" is "<C-RightMouse> ("CTRL-T") - *'mousemoveevent'* *'mousemev'* *'nomousemoveevent'* *'nomousemev'* +*'mousemoveevent'* *'mousemev'* *'nomousemoveevent'* *'nomousemev'* *mouse-hover* 'mousemoveevent' 'mousemev' boolean (default off) global When on, mouse move events are delivered to the input queue and are - available for mapping. The default, off, avoids the mouse movement - overhead except when needed. + available for mapping |<MouseMove>|. The default, off, avoids the mouse + movement overhead except when needed. Warning: Setting this option can make pending mappings to be aborted when the mouse is moved. diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index 158ea6a4a1..e246ceb942 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -274,9 +274,8 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|. pack/*/start/{name} ~ Note that {name} is the directory name, not the name - of the .vim file. All the files matching the pattern + of the .vim file. All files matching the patterns pack/*/opt/{name}/plugin/**/*.vim ~ - and pack/*/opt/{name}/plugin/**/*.lua ~ will be sourced. This allows for using subdirectories below "plugin", just like with plugins in diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index d8d5e42397..2e4781f0e6 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -379,7 +379,8 @@ argument. *--embed* --embed Use stdin/stdout as a msgpack-RPC channel, so applications can - embed and control Nvim via the RPC |API|. + embed and control Nvim via the RPC |API|. If the channel is + closed (except by |:detach|), Nvim exits. Waits for the client ("embedder") to call |nvim_ui_attach()| before sourcing startup files and reading buffers, so that UIs @@ -389,15 +390,14 @@ argument. During this pre-startup phase the user config is of course not available (similar to `--cmd`). - Embedders _not_ using the UI protocol must pass |--headless|: > + Non-UI embedders must pass |--headless|, then startup will + continue without waiting for `nvim_ui_attach`: > nvim --embed --headless - -< Then startup will continue without waiting for `nvim_ui_attach`. - This is equivalent to: > +< which is equivalent to: > nvim --headless --cmd "call stdioopen({'rpc': v:true})" < - Embedders that use the UI protocol on a socket connection must - pass |--listen| as well as |--embed|: > + UI embedders that want the UI protocol on a socket (instead of + stdio) must pass |--listen| as well as |--embed|: > nvim --embed --listen addr < See also: |ui-startup| |channel-stdio| diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index a3e09a9ea5..f0172c36e5 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -123,7 +123,7 @@ UI embedders (clients that start Nvim with |--embed| and later call nvim --embed Nvim will pause before loading startup files and reading buffers, so the UI has a chance to invoke requests and do early initialization. Startup will -continue as soon as the UI invokes |nvim_ui_attach()|. +continue when the UI invokes |nvim_ui_attach()|. A simple UI only needs to do a single |nvim_ui_attach()| request and then prepare to handle any UI event. A more featureful UI, which might need @@ -149,17 +149,14 @@ procedure: entering normal mode, for example reading variables set by init.vim. *ui-startup-stdin* -An UI can support the native read from stdin feature as invoked with -`command | nvim -` for the builtin TUI. |--| -The embedding process can detect that its stdin is open to a file which -not is a terminal, just like Nvim does. It then needs to forward this fd -to Nvim. As fd=0 is already is used to send rpc data from the embedder to -Nvim, it needs to use some other file descriptor, like fd=3 or higher. - -Then, `stdin_fd` option should be passed to `nvim_ui_attach` and Nvim will -implicitly read it as a buffer. This option can only be used when Nvim is -launched with `--embed` option, as described above. - +UIs can support reading from stdin (like `command | nvim -`, see |--|) as follows: + +1. The embedding process detects that the stdin fd is not a terminal. +2. It then needs to forward this fd to Nvim. Because fd=0 is already is used + to send RPC data from embedder to Nvim, it must use some other file + descriptor, like fd=3 or higher. +3. Then pass the fd as the `stdin_fd` parameter of `nvim_ui_attach`. Nvim will + read it as text into buffer 1. ============================================================================== Global Events *ui-global* diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua index af194aa70e..15cdd8fc79 100644 --- a/runtime/lua/vim/_meta/api.lua +++ b/runtime/lua/vim/_meta/api.lua @@ -1152,8 +1152,7 @@ function vim.api.nvim_eval(expr) end --- the "highlights" key in {opts} is true. Each element of the array is a --- |Dict| with these keys: --- - start: (number) Byte index (0-based) of first character that uses the highlight. ---- - group: (string) Name of highlight group. May be removed in the future, use ---- `groups` instead. +--- - group: (string) Deprecated. Use `groups` instead. --- - groups: (array) Names of stacked highlight groups (highest priority last). function vim.api.nvim_eval_statusline(str, opts) end diff --git a/runtime/lua/vim/_meta/builtin.lua b/runtime/lua/vim/_meta/builtin.lua index 9fa2e242c4..2d5975b977 100644 --- a/runtime/lua/vim/_meta/builtin.lua +++ b/runtime/lua/vim/_meta/builtin.lua @@ -223,12 +223,11 @@ function vim.schedule(fn) end --- - If {callback} errors, the error is raised. function vim.wait(time, callback, interval, fast_only) end ---- Attach to |ui-events|, similar to |nvim_ui_attach()| but receive events ---- as Lua callback. Can be used to implement screen elements like ---- popupmenu or message handling in Lua. +--- Subscribe to |ui-events|, similar to |nvim_ui_attach()| but receive events in a Lua callback. +--- Used to implement screen elements like popupmenu or message handling in Lua. --- ---- {options} should be a dictionary-like table, where `ext_...` options should ---- be set to true to receive events for the respective external element. +--- {options} is a dict with one or more `ext_…` |ui-option|s set to true to enable events for +--- the respective UI element. --- --- {callback} receives event name plus additional parameters. See |ui-popupmenu| --- and the sections below for event format for respective events. @@ -250,14 +249,14 @@ function vim.wait(time, callback, interval, fast_only) end --- ns = vim.api.nvim_create_namespace('my_fancy_pum') --- --- vim.ui_attach(ns, {ext_popupmenu=true}, function(event, ...) ---- if event == "popupmenu_show" then +--- if event == 'popupmenu_show' then --- local items, selected, row, col, grid = ... ---- print("display pum ", #items) ---- elseif event == "popupmenu_select" then +--- print('display pum ', #items) +--- elseif event == 'popupmenu_select' then --- local selected = ... ---- print("selected", selected) ---- elseif event == "popupmenu_hide" then ---- print("FIN") +--- print('selected', selected) +--- elseif event == 'popupmenu_hide' then +--- print('FIN') --- end --- end) --- ``` diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 25cc3aae00..8df174a838 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -4381,8 +4381,8 @@ vim.go.mousemodel = vim.o.mousemodel vim.go.mousem = vim.go.mousemodel --- When on, mouse move events are delivered to the input queue and are ---- available for mapping. The default, off, avoids the mouse movement ---- overhead except when needed. +--- available for mapping `<MouseMove>`. The default, off, avoids the mouse +--- movement overhead except when needed. --- Warning: Setting this option can make pending mappings to be aborted --- when the mouse is moved. --- diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index 4970a3023b..5504d577d6 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -899,12 +899,13 @@ function vim.fn.charidx(string, idx, countcc, utf16) end --- @return string function vim.fn.chdir(dir) end ---- Get the amount of indent for line {lnum} according the C ---- indenting rules, as with 'cindent'. +--- Get the amount of indent for line {lnum} according the +--- |C-indenting| rules, as with 'cindent'. --- The indent is counted in spaces, the value of 'tabstop' is --- relevant. {lnum} is used just like in |getline()|. --- When {lnum} is invalid -1 is returned. ---- See |C-indenting|. +--- +--- To get or set indent of lines in a string, see |vim.text.indent()|. --- --- @param lnum integer --- @return integer @@ -4430,6 +4431,8 @@ function vim.fn.id(expr) end --- |getline()|. --- When {lnum} is invalid -1 is returned. --- +--- To get or set indent of lines in a string, see |vim.text.indent()|. +--- --- @param lnum integer|string --- @return integer function vim.fn.indent(lnum) end @@ -5335,9 +5338,8 @@ function vim.fn.map(expr1, expr2) end --- When {abbr} is there and it is |TRUE| use abbreviations --- instead of mappings. --- ---- When {dict} is there and it is |TRUE| return a dictionary ---- containing all the information of the mapping with the ---- following items: *mapping-dict* +--- When {dict} is |TRUE|, return a dictionary describing the +--- mapping, with these items: *mapping-dict* --- "lhs" The {lhs} of the mapping as it would be typed --- "lhsraw" The {lhs} of the mapping as raw bytes --- "lhsrawalt" The {lhs} of the mapping as raw bytes, alternate @@ -5389,7 +5391,7 @@ function vim.fn.maparg(name, mode, abbr, dict) end --- @param mode string --- @param abbr boolean --- @param dict true ---- @return string|table<string,any> +--- @return table<string,any> function vim.fn.maparg(name, mode, abbr, dict) end --- Check if there is a mapping that matches with {name} in mode @@ -6821,6 +6823,7 @@ function vim.fn.prompt_getprompt(buf) end --- endif --- endfunc --- call prompt_setcallback(bufnr(), function('s:TextEntered')) +--- < --- --- @param buf integer|string --- @param expr string|function @@ -9328,7 +9331,9 @@ function vim.fn.state(what) end function vim.fn.stdioopen(opts) end --- Returns |standard-path| locations of various default files and ---- directories. +--- directories. The locations are driven by |base-directories| +--- which you can configure via |$NVIM_APPNAME| or the `$XDG_…` +--- environment variables. --- --- {what} Type Description ~ --- cache String Cache directory: arbitrary temporary diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index cbec06df02..83624234bc 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -254,7 +254,7 @@ end --- fully initialized. Use `on_init` to do any actions once --- the client has been initialized. --- @return string? # Error message, if any -local function create_and_initialize_client(config) +local function create_and_init_client(config) local ok, res = pcall(require('vim.lsp.client').create, config) if not ok then return nil, res --[[@as string]] @@ -601,7 +601,7 @@ function lsp.start(config, opts) end end - local client_id, err = create_and_initialize_client(config) + local client_id, err = create_and_init_client(config) if err then if not opts.silent then vim.notify(err, vim.log.levels.WARN) @@ -716,7 +716,7 @@ end --- @return string? # Error message, if any function lsp.start_client(config) vim.deprecate('vim.lsp.start_client()', 'vim.lsp.start()', '0.13') - return create_and_initialize_client(config) + return create_and_init_client(config) end ---Buffer lifecycle handler for textDocument/didSave diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 49e71af4f6..47f41b43aa 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -1,3 +1,6 @@ +--- @brief +--- The `vim.lsp.buf_…` functions perform operations for LSP clients attached to the current buffer. + local api = vim.api local lsp = vim.lsp local validate = vim.validate diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 79a91c3d5f..8c75ee321d 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -6,7 +6,7 @@ local ms = lsp.protocol.Methods local changetracking = lsp._changetracking local validate = vim.validate ---- @alias vim.lsp.client.on_init_cb fun(client: vim.lsp.Client, initialize_result: lsp.InitializeResult) +--- @alias vim.lsp.client.on_init_cb fun(client: vim.lsp.Client, init_result: lsp.InitializeResult) --- @alias vim.lsp.client.on_attach_cb fun(client: vim.lsp.Client, bufnr: integer) --- @alias vim.lsp.client.on_exit_cb fun(code: integer, signal: integer, client_id: integer) --- @alias vim.lsp.client.before_init_cb fun(params: lsp.InitializeParams, config: vim.lsp.ClientConfig) @@ -108,11 +108,11 @@ local validate = vim.validate --- You can use this to modify parameters before they are sent. --- @field before_init? fun(params: lsp.InitializeParams, config: vim.lsp.ClientConfig) --- ---- Callback invoked after LSP "initialize", where `result` is a table of `capabilities` ---- and anything else the server may send. For example, clangd sends ---- `initialize_result.offsetEncoding` if `capabilities.offsetEncoding` was sent to it. ---- You can only modify the `client.offset_encoding` here before any notifications are sent. ---- @field on_init? elem_or_list<fun(client: vim.lsp.Client, initialize_result: lsp.InitializeResult)> +--- Callback invoked after LSP "initialize", where `result` is a table of `capabilities` and +--- anything else the server may send. For example, clangd sends `init_result.offsetEncoding` if +--- `capabilities.offsetEncoding` was sent to it. You can only modify the `client.offset_encoding` +--- here before any notifications are sent. +--- @field on_init? elem_or_list<fun(client: vim.lsp.Client, init_result: lsp.InitializeResult)> --- --- Callback invoked on client exit. --- - code: exit code of the process @@ -506,7 +506,7 @@ function Client:initialize() root_path = vim.uri_to_fname(root_uri) end - local initialize_params = { + local init_params = { -- The process Id of the parent process that started the server. Is null if -- the process has not been started by another process. If the parent -- process is not alive then the server should exit (see exit notification) @@ -536,15 +536,15 @@ function Client:initialize() self:_run_callbacks( { self._before_init_cb }, lsp.client_errors.BEFORE_INIT_CALLBACK_ERROR, - initialize_params, + init_params, config ) - log.trace(self._log_prefix, 'initialize_params', initialize_params) + log.trace(self._log_prefix, 'init_params', init_params) local rpc = self.rpc - rpc.request('initialize', initialize_params, function(init_err, result) + rpc.request('initialize', init_params, function(init_err, result) assert(not init_err, tostring(init_err)) assert(result, 'server sent empty result') rpc.notify('initialized', vim.empty_dict()) diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index 1466dcf438..7b8ce02726 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -1,3 +1,25 @@ +--- @brief +--- The `vim.lsp.completion` module enables insert-mode completion driven by an LSP server. Call +--- `enable()` to make it available through Nvim builtin completion (via the |CompleteDone| event). +--- Specify `autotrigger=true` to activate "auto-completion" when you type any of the server-defined +--- `triggerCharacters`. +--- +--- Example: activate LSP-driven auto-completion: +--- ```lua +--- vim.lsp.start({ +--- name = 'ts_ls', +--- cmd = …, +--- on_attach = function(client, bufnr) +--- vim.lsp.completion.enable(true, client.id, bufnr, { +--- autotrigger = true, +--- convert = function(item) +--- return { abbr = item.label:gsub('%b()', '') } +--- end, +--- }) +--- end, +--- }) +--- ``` + local M = {} local api = vim.api @@ -749,7 +771,7 @@ function M.enable(enable, client_id, bufnr, opts) end end ---- Trigger LSP completion in the current buffer. +--- Triggers LSP completion once in the current buffer. function M.trigger() local bufnr = api.nvim_get_current_buf() local clients = (buf_handles[bufnr] or {}).clients or {} diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index b0567e3b59..1219f71427 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1503,6 +1503,7 @@ end --- (default: `'cursor'`) --- @field relative? 'mouse'|'cursor'|'editor' --- +--- Adjusts placement relative to cursor. --- - "auto": place window based on which side of the cursor has more lines --- - "above": place the window above the cursor unless there are not enough lines --- to display the full window height. diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 3a89e44938..c734e2aa2a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1985,8 +1985,7 @@ Array nvim_get_mark(String name, Dict(empty) *opts, Arena *arena, Error *err) /// the "highlights" key in {opts} is true. Each element of the array is a /// |Dict| with these keys: /// - start: (number) Byte index (0-based) of first character that uses the highlight. -/// - group: (string) Name of highlight group. May be removed in the future, use -/// `groups` instead. +/// - group: (string) Deprecated. Use `groups` instead. /// - groups: (array) Names of stacked highlight groups (highest priority last). Dict nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena *arena, Error *err) FUNC_API_SINCE(8) FUNC_API_FAST diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 1bb2bea502..3c06fc4fe3 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -1225,12 +1225,13 @@ M.funcs = { args = 1, base = 1, desc = [=[ - Get the amount of indent for line {lnum} according the C - indenting rules, as with 'cindent'. + Get the amount of indent for line {lnum} according the + |C-indenting| rules, as with 'cindent'. The indent is counted in spaces, the value of 'tabstop' is relevant. {lnum} is used just like in |getline()|. When {lnum} is invalid -1 is returned. - See |C-indenting|. + + To get or set indent of lines in a string, see |vim.text.indent()|. ]=], name = 'cindent', @@ -5473,6 +5474,8 @@ M.funcs = { |getline()|. When {lnum} is invalid -1 is returned. + To get or set indent of lines in a string, see |vim.text.indent()|. + ]=], name = 'indent', params = { { 'lnum', 'integer|string' } }, @@ -6595,9 +6598,8 @@ M.funcs = { When {abbr} is there and it is |TRUE| use abbreviations instead of mappings. - When {dict} is there and it is |TRUE| return a dictionary - containing all the information of the mapping with the - following items: *mapping-dict* + When {dict} is |TRUE|, return a dictionary describing the + mapping, with these items: *mapping-dict* "lhs" The {lhs} of the mapping as it would be typed "lhsraw" The {lhs} of the mapping as raw bytes "lhsrawalt" The {lhs} of the mapping as raw bytes, alternate @@ -6659,7 +6661,7 @@ M.funcs = { { 'abbr', 'boolean' }, { 'dict', 'true' }, }, - returns = 'string|table<string,any>', + returns = 'table<string,any>', }, mapcheck = { args = { 1, 3 }, @@ -8278,7 +8280,7 @@ M.funcs = { endif endfunc call prompt_setcallback(bufnr(), function('s:TextEntered')) - + < ]=], name = 'prompt_setcallback', params = { { 'buf', 'integer|string' }, { 'expr', 'string|function' } }, @@ -11225,7 +11227,9 @@ M.funcs = { tags = { 'E6100' }, desc = [=[ Returns |standard-path| locations of various default files and - directories. + directories. The locations are driven by |base-directories| + which you can configure via |$NVIM_APPNAME| or the `$XDG_…` + environment variables. {what} Type Description ~ cache String Cache directory: arbitrary temporary diff --git a/src/nvim/options.lua b/src/nvim/options.lua index ff919bb522..d1d5a56082 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -5802,8 +5802,8 @@ local options = { defaults = false, desc = [=[ When on, mouse move events are delivered to the input queue and are - available for mapping. The default, off, avoids the mouse movement - overhead except when needed. + available for mapping |<MouseMove>|. The default, off, avoids the mouse + movement overhead except when needed. Warning: Setting this option can make pending mappings to be aborted when the mouse is moved. ]=], @@ -5811,6 +5811,7 @@ local options = { redraw = { 'ui_option' }, scope = { 'global' }, short_desc = N_('deliver mouse move events to input queue'), + tags = { 'mouse-hover' }, type = 'boolean', varname = 'p_mousemev', }, diff --git a/test/functional/lua/command_line_completion_spec.lua b/test/functional/lua/command_line_completion_spec.lua index ae0ab19d6b..7dac7448e9 100644 --- a/test/functional/lua/command_line_completion_spec.lua +++ b/test/functional/lua/command_line_completion_spec.lua @@ -18,19 +18,19 @@ end before_each(clear) describe('nlua_expand_pat', function() - it('should complete exact matches', function() + it('completes exact matches', function() eq({ { 'exact' }, 0 }, get_completions('exact', { exact = true })) end) - it('should return empty table when nothing matches', function() + it('returns empty table when nothing matches', function() eq({ {}, 0 }, get_completions('foo', { bar = true })) end) - it('should return nice completions with function call prefix', function() + it('returns nice completions with function call prefix', function() eq({ { 'FOO' }, 6 }, get_completions('print(F', { FOO = true, bawr = true })) end) - it('should return keys for nested dictionaries', function() + it('returns keys for nested dicts', function() eq( { { 'nvim_buf_set_lines', @@ -47,7 +47,7 @@ describe('nlua_expand_pat', function() ) end) - it('it should work with colons', function() + it('with colons', function() eq( { { 'bawr', @@ -63,7 +63,7 @@ describe('nlua_expand_pat', function() ) end) - it('should return keys for string reffed dictionaries', function() + it('returns keys after string key', function() eq( { { 'nvim_buf_set_lines', @@ -78,9 +78,7 @@ describe('nlua_expand_pat', function() }, }) ) - end) - it('should return keys for string reffed dictionaries', function() eq( { { 'nvim_buf_set_lines', @@ -99,7 +97,7 @@ describe('nlua_expand_pat', function() ) end) - it('should work with lazy submodules of "vim" global', function() + it('with lazy submodules of "vim" global', function() eq({ { 'inspect', 'inspect_pos' }, 4 }, get_completions('vim.inspec')) eq({ { 'treesitter' }, 4 }, get_completions('vim.treesi')) @@ -107,7 +105,7 @@ describe('nlua_expand_pat', function() eq({ { 'set' }, 11 }, get_completions('vim.keymap.se')) end) - it('should exclude private fields after "."', function() + it('excludes private fields after "."', function() eq( { { 'bar' }, 4 }, get_completions('foo.', { @@ -119,7 +117,7 @@ describe('nlua_expand_pat', function() ) end) - it('should include private fields after "._"', function() + it('includes private fields after "._"', function() eq( { { '_bar' }, 4 }, get_completions('foo._', { @@ -131,7 +129,7 @@ describe('nlua_expand_pat', function() ) end) - it('should be able to interpolate globals', function() + it('can interpolate globals', function() eq( { { 'nvim_buf_set_lines', @@ -149,8 +147,8 @@ describe('nlua_expand_pat', function() ) end) - describe('should complete vim.fn', function() - it('correctly works for simple completion', function() + describe('vim.fn', function() + it('simple completion', function() local actual = get_completions('vim.fn.did') local expected = { { 'did_filetype' }, @@ -158,7 +156,7 @@ describe('nlua_expand_pat', function() } eq(expected, actual) end) - it('should not suggest items with #', function() + it('does not suggest "#" items', function() exec_lua [[ -- ensure remote#host#... functions exist vim.cmd [=[ @@ -176,7 +174,7 @@ describe('nlua_expand_pat', function() end) end) - describe('should complete for variable accessors for', function() + describe('completes', function() it('vim.v', function() local actual = get_completions('vim.v.t_') local expected = { @@ -240,7 +238,7 @@ describe('nlua_expand_pat', function() end) end) - describe('should complete for option accessors for', function() + describe('completes', function() -- for { vim.o, vim.go, vim.opt, vim.opt_local, vim.opt_global } local test_opt = function(accessor) do @@ -271,7 +269,7 @@ describe('nlua_expand_pat', function() test_opt('vim.opt_local') test_opt('vim.opt_global') - it('vim.o, suggesting all the known options', function() + it('vim.o, suggesting all known options', function() local completions = get_completions('vim.o.')[1] ---@type string[] eq( exec_lua [[ @@ -314,45 +312,19 @@ describe('nlua_expand_pat', function() end) end) - it('should return everything if the input is of length 0', function() + it('returns everything if input is empty', function() eq({ { 'other', 'vim' }, 0 }, get_completions('', { vim = true, other = true })) end) - describe('get_parts', function() - it('should return an empty list for no separators', function() - eq({ {}, 1 }, get_compl_parts('vim')) - end) - - it('just the first item before a period', function() - eq({ { 'vim' }, 5 }, get_compl_parts('vim.ap')) - end) - - it('should return multiple parts just for period', function() - eq({ { 'vim', 'api' }, 9 }, get_compl_parts('vim.api.nvim_buf')) - end) - - it('should be OK with colons', function() - eq({ { 'vim', 'api' }, 9 }, get_compl_parts('vim:api.nvim_buf')) - end) - - it('should work for just one string ref', function() - eq({ { 'vim', 'api' }, 12 }, get_compl_parts("vim['api'].nvim_buf")) - end) - - it('should work for just one string ref, with double quote', function() - eq({ { 'vim', 'api' }, 12 }, get_compl_parts('vim["api"].nvim_buf')) - end) - - it('should allows back-to-back string ref', function() - eq({ { 'vim', 'nested', 'api' }, 22 }, get_compl_parts('vim["nested"]["api"].nvim_buf')) - end) - - it('should allows back-to-back string ref with spaces before and after', function() - eq({ { 'vim', 'nested', 'api' }, 25 }, get_compl_parts('vim[ "nested" ]["api"].nvim_buf')) - end) - - it('should allow VAR style loolup', function() - eq({ { 'vim', { 'NESTED' }, 'api' }, 20 }, get_compl_parts('vim[NESTED]["api"].nvim_buf')) - end) + it('get_parts', function() + eq({ {}, 1 }, get_compl_parts('vim')) + eq({ { 'vim' }, 5 }, get_compl_parts('vim.ap')) + eq({ { 'vim', 'api' }, 9 }, get_compl_parts('vim.api.nvim_buf')) + eq({ { 'vim', 'api' }, 9 }, get_compl_parts('vim:api.nvim_buf')) + eq({ { 'vim', 'api' }, 12 }, get_compl_parts("vim['api'].nvim_buf")) + eq({ { 'vim', 'api' }, 12 }, get_compl_parts('vim["api"].nvim_buf')) + eq({ { 'vim', 'nested', 'api' }, 22 }, get_compl_parts('vim["nested"]["api"].nvim_buf')) + eq({ { 'vim', 'nested', 'api' }, 25 }, get_compl_parts('vim[ "nested" ]["api"].nvim_buf')) + eq({ { 'vim', { 'NESTED' }, 'api' }, 20 }, get_compl_parts('vim[NESTED]["api"].nvim_buf')) end) end) diff --git a/test/functional/lua/thread_spec.lua b/test/functional/lua/thread_spec.lua index 8ca4bdc4f5..7610886b47 100644 --- a/test/functional/lua/thread_spec.lua +++ b/test/functional/lua/thread_spec.lua @@ -19,7 +19,7 @@ describe('thread', function() screen = Screen.new(50, 10) end) - it('handle non-string error', function() + it('non-string error()', function() exec_lua [[ local thread = vim.uv.new_thread(function() error() diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index a82279e775..83d45bcf62 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -888,8 +888,9 @@ describe('stdpath()', function() os.remove(testlog) end) - -- Windows appends 'nvim-data' instead of just 'nvim' to prevent collisions - -- due to XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME being the same. + --- Windows appends 'nvim-data' instead of just 'nvim' to prevent collisions + --- due to XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME being the same. + --- @param name string local function maybe_data(name) return is_os('win') and name .. '-data' or name end @@ -898,7 +899,7 @@ describe('stdpath()', function() local statedir = maybe_data('nvim') local env_sep = is_os('win') and ';' or ':' - it('acceptance', function() + it('works', function() clear() -- Do not explicitly set any env vars. eq('nvim', fn.fnamemodify(fn.stdpath('cache'), ':t')) @@ -911,6 +912,15 @@ describe('stdpath()', function() assert_alive() -- Check for crash. #8393 end) + it('failure modes', function() + clear() + eq('Vim(call):E6100: "capybara" is not a valid stdpath', exc_exec('call stdpath("capybara")')) + eq('Vim(call):E6100: "" is not a valid stdpath', exc_exec('call stdpath("")')) + eq('Vim(call):E6100: "23" is not a valid stdpath', exc_exec('call stdpath(23)')) + eq('Vim(call):E731: Using a Dictionary as a String', exc_exec('call stdpath({"eris": 23})')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call stdpath([23])')) + end) + it('$NVIM_APPNAME', function() local appname = 'NVIM_APPNAME_TEST' .. ('_'):rep(106) clear({ env = { NVIM_APPNAME = appname, NVIM_LOG_FILE = testlog } }) @@ -1263,19 +1273,4 @@ describe('stdpath()', function() }) end) end) - - describe('errors', function() - before_each(clear) - - it('on unknown strings', function() - eq('Vim(call):E6100: "capybara" is not a valid stdpath', exc_exec('call stdpath("capybara")')) - eq('Vim(call):E6100: "" is not a valid stdpath', exc_exec('call stdpath("")')) - eq('Vim(call):E6100: "23" is not a valid stdpath', exc_exec('call stdpath(23)')) - end) - - it('on non-strings', function() - eq('Vim(call):E731: Using a Dictionary as a String', exc_exec('call stdpath({"eris": 23})')) - eq('Vim(call):E730: Using a List as a String', exc_exec('call stdpath([23])')) - end) - end) end) diff --git a/test/functional/script/luacats_grammar_spec.lua b/test/functional/script/luacats_grammar_spec.lua index 2fcd0adfa4..6d1037b79c 100644 --- a/test/functional/script/luacats_grammar_spec.lua +++ b/test/functional/script/luacats_grammar_spec.lua @@ -264,7 +264,7 @@ describe('luacats grammar', function() -- generics { 'elem_or_list<string>' }, { - 'elem_or_list<fun(client: vim.lsp.Client, initialize_result: lsp.InitializeResult)>', + 'elem_or_list<fun(client: vim.lsp.Client, init_result: lsp.InitializeResult)>', nil, }, } |