diff options
Diffstat (limited to 'runtime/doc')
30 files changed, 2382 insertions, 887 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 98dd330b48..d52a9a8409 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -19,6 +19,7 @@ API Usage *api-rpc* *RPC* *rpc* *msgpack-rpc* RPC is the typical way to control Nvim programmatically. Nvim implements the MessagePack-RPC protocol: + https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md https://github.com/msgpack/msgpack/blob/0b8f5ac/spec.md Many clients use the API: user interfaces (GUIs), remote plugins, scripts like @@ -439,8 +440,68 @@ Example: create a float with scratch buffer: > > ============================================================================== +Extended marks *api-extended-marks* + +Extended marks (extmarks) represent buffer annotations that track text changes +in the buffer. They could be used to represent cursors, folds, misspelled +words, and anything else that needs to track a logical location in the buffer +over time. + +Example: + +We will set an extmark at the first row and third column. |api-indexing| is +zero-indexed, so we use row=0 and column=2. Passing id=0 creates a new mark +and returns the id: > + + let g:mark_ns = nvim_create_namespace('myplugin') + let g:mark_id = nvim_buf_set_extmark(0, g:mark_ns, 0, 0, 2, {}) + +We can get a mark by its id: > + + echo nvim_buf_get_extmark_by_id(0, g:mark_ns, g:mark_id) + => [0, 2] + +We can get all marks in a buffer for our namespace (or by a range): > + + echo nvim_buf_get_extmarks(0, g:mark_ns, 0, -1, {}) + => [[1, 0, 2]] + +Deleting all text surrounding an extmark does not remove the extmark. To +remove an extmark use |nvim_buf_del_extmark()|. + +Namespaces allow your plugin to manage only its own extmarks, ignoring those +created by another plugin. + +Extmark positions changed by an edit will be restored on undo/redo. Creating +and deleting extmarks is not a buffer change, thus new undo states are not +created for extmark changes. + +============================================================================== Global Functions *api-global* +nvim_exec({src}, {output}) *nvim_exec()* + Executes Vimscript (multiline block of Ex-commands), like + anonymous |:source|. + + Unlike |nvim_command()| this function supports heredocs, + script-scope (s:), etc. + + On execution error: fails with VimL error, does not update + v:errmsg. + + Parameters: ~ + {src} Vimscript code + {output} Capture and return all (non-error, non-shell + |:!|) output + + Return: ~ + Output (non-error, non-shell |:!|) if `output` is true, + else empty string. + + See also: ~ + |execute()| + |nvim_command()| + nvim_command({command}) *nvim_command()* Executes an ex-command. @@ -450,6 +511,9 @@ nvim_command({command}) *nvim_command()* Parameters: ~ {command} Ex-command string + See also: ~ + |nvim_exec()| + nvim_get_hl_by_name({name}, {rgb}) *nvim_get_hl_by_name()* Gets a highlight definition by name. @@ -571,19 +635,9 @@ nvim_replace_termcodes({str}, {from_part}, {do_lt}, {special}) replace_termcodes cpoptions -nvim_command_output({command}) *nvim_command_output()* - Executes an ex-command and returns its (non-error) output. - Shell |:!| output is not captured. - - On execution error: fails with VimL error, does not update - v:errmsg. - - Parameters: ~ - {command} Ex-command string - nvim_eval({expr}) *nvim_eval()* - Evaluates a VimL expression (:help expression). Dictionaries - and Lists are recursively expanded. + Evaluates a VimL |expression|. Dictionaries and Lists are + recursively expanded. On execution error: fails with VimL error, does not update v:errmsg. @@ -594,7 +648,7 @@ nvim_eval({expr}) *nvim_eval()* Return: ~ Evaluation result or expanded object -nvim_execute_lua({code}, {args}) *nvim_execute_lua()* +nvim_exec_lua({code}, {args}) *nvim_exec_lua()* Execute Lua code. Parameters (if any) are available as `...` inside the chunk. The chunk can return a value. @@ -850,10 +904,10 @@ nvim_open_win({buffer}, {enter}, {config}) *nvim_open_win()* {enter} Enter the window (make it the current window) {config} Map defining the window configuration. Keys: • `relative` : Sets the window layout to "floating", placed - at (row,col) coordinates relative to one of: + at (row,col) coordinates relative to: • "editor" The global editor grid • "win" Window given by the `win` field, or - current window by default. + current window. • "cursor" Cursor position in current window. • `win` : |window-ID| for relative="win". @@ -896,10 +950,11 @@ nvim_open_win({buffer}, {enter}, {config}) *nvim_open_win()* 'number', 'relativenumber', 'cursorline', 'cursorcolumn', 'foldcolumn', 'spell' and 'list' options. 'signcolumn' is changed to - `auto` . The end-of-buffer region is hidden - by setting `eob` flag of 'fillchars' to a - space char, and clearing the |EndOfBuffer| - region in 'winhighlight'. + `auto` and 'colorcolumn' is cleared. The + end-of-buffer region is hidden by setting + `eob` flag of 'fillchars' to a space char, + and clearing the |EndOfBuffer| region in + 'winhighlight'. Return: ~ Window handle, or 0 on error @@ -984,7 +1039,7 @@ nvim_put({lines}, {type}, {after}, {follow}) *nvim_put()* {type} Edit behavior: any |getregtype()| result, or: • "b" |blockwise-visual| mode (may include width, e.g. "b3") - • "c" |characterwise| mode + • "c" |charwise| mode • "l" |linewise| mode • "" guess by contents, see |setreg()| {after} Insert after cursor (like |p|), or before (like @@ -1476,45 +1531,73 @@ nvim_buf_line_count({buffer}) *nvim_buf_line_count()* Line count, or 0 for unloaded buffer. |api-buffer| nvim_buf_attach({buffer}, {send_buffer}, {opts}) *nvim_buf_attach()* - Activates buffer-update events on a channel, or as lua + Activates buffer-update events on a channel, or as Lua callbacks. + Example (Lua): capture buffer updates in a global `events` variable (use "print(vim.inspect(events))" to see its + contents): > + events = {} + vim.api.nvim_buf_attach(0, false, { + on_lines=function(...) table.insert(events, {...}) end}) +< + Parameters: ~ {buffer} Buffer handle, or 0 for current buffer - {send_buffer} Set to true if the initial notification - should contain the whole buffer. If so, the - first notification will be a - `nvim_buf_lines_event` . Otherwise, the - first notification will be a - `nvim_buf_changedtick_event` . Not used for - lua callbacks. + {send_buffer} True if the initial notification should + contain the whole buffer: first + notification will be `nvim_buf_lines_event` + . Else the first notification will be + `nvim_buf_changedtick_event` . Not for Lua + callbacks. {opts} Optional parameters. - • `on_lines` : lua callback received on - change. - • `on_changedtick` : lua callback received - on changedtick increment without text - change. - • `utf_sizes` : include UTF-32 and UTF-16 - size of the replaced region. See - |api-buffer-updates-lua| for more - information + • on_lines: Lua callback invoked on change. + Return `true` to detach. Args: + • buffer handle + • b:changedtick + • first line that changed (zero-indexed) + • last line that was changed + • last line in the updated range + • byte count of previous contents + • deleted_codepoints (if `utf_sizes` is + true) + • deleted_codeunits (if `utf_sizes` is + true) + + • on_changedtick: Lua callback invoked on + changedtick increment without text + change. Args: + • buffer handle + • b:changedtick + + • on_detach: Lua callback invoked on + detach. Args: + • buffer handle + + • utf_sizes: include UTF-32 and UTF-16 size + of the replaced region, as args to + `on_lines` . + + Return: ~ + False if attach failed (invalid parameter, or buffer isn't + loaded); otherwise True. TODO: LUA_API_NO_EVAL - Return: ~ - False when updates couldn't be enabled because the buffer - isn't loaded or `opts` contained an invalid key; otherwise - True. TODO: LUA_API_NO_EVAL + See also: ~ + |nvim_buf_detach()| + |api-buffer-updates-lua| nvim_buf_detach({buffer}) *nvim_buf_detach()* Deactivates buffer-update events on the channel. - For Lua callbacks see |api-lua-detach|. - Parameters: ~ {buffer} Buffer handle, or 0 for current buffer Return: ~ - False when updates couldn't be disabled because the buffer - isn't loaded; otherwise True. + False if detach failed (because the buffer isn't loaded); + otherwise True. + + See also: ~ + |nvim_buf_attach()| + |api-lua-detach| for detaching Lua callbacks *nvim_buf_get_lines()* nvim_buf_get_lines({buffer}, {start}, {end}, {strict_indexing}) @@ -1726,6 +1809,99 @@ nvim_buf_get_mark({buffer}, {name}) *nvim_buf_get_mark()* Return: ~ (row, col) tuple + *nvim_buf_get_extmark_by_id()* +nvim_buf_get_extmark_by_id({buffer}, {ns_id}, {id}) + Returns position for a given extmark id + + Parameters: ~ + {buffer} Buffer handle, or 0 for current buffer + {ns_id} Namespace id from |nvim_create_namespace()| + {id} Extmark id + + Return: ~ + (row, col) tuple or empty list () if extmark id was absent + + *nvim_buf_get_extmarks()* +nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {opts}) + Gets extmarks in "traversal order" from a |charwise| region + defined by buffer positions (inclusive, 0-indexed + |api-indexing|). + + Region can be given as (row,col) tuples, or valid extmark ids + (whose positions define the bounds). 0 and -1 are understood + as (0,0) and (-1,-1) respectively, thus the following are + equivalent: +> + nvim_buf_get_extmarks(0, my_ns, 0, -1, {}) + nvim_buf_get_extmarks(0, my_ns, [0,0], [-1,-1], {}) +< + + If `end` is less than `start` , traversal works backwards. + (Useful with `limit` , to get the first marks prior to a given + position.) + + Example: +> + local a = vim.api + local pos = a.nvim_win_get_cursor(0) + local ns = a.nvim_create_namespace('my-plugin') + -- Create new extmark at line 1, column 1. + local m1 = a.nvim_buf_set_extmark(0, ns, 0, 0, 0, {}) + -- Create new extmark at line 3, column 1. + local m2 = a.nvim_buf_set_extmark(0, ns, 0, 2, 0, {}) + -- Get extmarks only from line 3. + local ms = a.nvim_buf_get_extmarks(0, ns, {2,0}, {2,0}, {}) + -- Get all marks in this buffer + namespace. + local all = a.nvim_buf_get_extmarks(0, ns, 0, -1, {}) + print(vim.inspect(ms)) +< + + Parameters: ~ + {buffer} Buffer handle, or 0 for current buffer + {ns_id} Namespace id from |nvim_create_namespace()| + {start} Start of range, given as (row, col) or valid + extmark id (whose position defines the bound) + {end} End of range, given as (row, col) or valid + extmark id (whose position defines the bound) + {opts} Optional parameters. Keys: + • limit: Maximum number of marks to return + + Return: ~ + List of [extmark_id, row, col] tuples in "traversal + order". + + *nvim_buf_set_extmark()* +nvim_buf_set_extmark({buffer}, {ns_id}, {id}, {line}, {col}, {opts}) + Creates or updates an extmark. + + To create a new extmark, pass id=0. The extmark id will be + returned. It is also allowed to create a new mark by passing + in a previously unused id, but the caller must then keep track + of existing and unused ids itself. (Useful over RPC, to avoid + waiting for the return value.) + + Parameters: ~ + {buffer} Buffer handle, or 0 for current buffer + {ns_id} Namespace id from |nvim_create_namespace()| + {id} Extmark id, or 0 to create new + {line} Line number where to place the mark + {col} Column where to place the mark + {opts} Optional parameters. Currently not used. + + Return: ~ + Id of the created/updated extmark + +nvim_buf_del_extmark({buffer}, {ns_id}, {id}) *nvim_buf_del_extmark()* + Removes an extmark. + + Parameters: ~ + {buffer} Buffer handle, or 0 for current buffer + {ns_id} Namespace id from |nvim_create_namespace()| + {id} Extmark id + + Return: ~ + true if the extmark was found, else false + *nvim_buf_add_highlight()* nvim_buf_add_highlight({buffer}, {ns_id}, {hl_group}, {line}, {col_start}, {col_end}) @@ -1769,8 +1945,8 @@ nvim_buf_add_highlight({buffer}, {ns_id}, {hl_group}, {line}, *nvim_buf_clear_namespace()* nvim_buf_clear_namespace({buffer}, {ns_id}, {line_start}, {line_end}) - Clears namespaced objects, highlights and virtual text, from a - line range + Clears namespaced objects (highlights, extmarks, virtual text) + from a region. Lines are 0-indexed. |api-indexing| To clear the namespace in the entire buffer, specify line_start=0 and line_end=-1. @@ -1821,6 +1997,27 @@ nvim_buf_set_virtual_text({buffer}, {ns_id}, {line}, {chunks}, {opts}) Return: ~ The ns_id that was used +nvim_buf_get_virtual_text({buffer}, {lnum}) *nvim_buf_get_virtual_text()* + Get the virtual text (annotation) for a buffer line. + + The virtual text is returned as list of lists, whereas the + inner lists have either one or two elements. The first element + is the actual text, the optional second element is the + highlight group. + + The format is exactly the same as given to + nvim_buf_set_virtual_text(). + + If there is no virtual text associated with the given line, an + empty list is returned. + + Parameters: ~ + {buffer} Buffer handle, or 0 for current buffer + {line} Line to get the virtual text from (zero-indexed) + + Return: ~ + List of virtual text chunks + nvim__buf_stats({buffer}) *nvim__buf_stats()* TODO: Documentation diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 34ea083f96..18dfa587e8 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -559,16 +559,14 @@ CmdlineLeave Before leaving the command-line (including *CmdwinEnter* CmdwinEnter After entering the command-line window. Useful for setting options specifically for - this special type of window. This is - triggered _instead_ of BufEnter and WinEnter. + this special type of window. <afile> is set to a single character, indicating the type of command-line. |cmdwin-char| *CmdwinLeave* CmdwinLeave Before leaving the command-line window. Useful to clean up any global setting done - with CmdwinEnter. This is triggered _instead_ - of BufLeave and WinLeave. + with CmdwinEnter. <afile> is set to a single character, indicating the type of command-line. |cmdwin-char| diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt index bd3f22a371..dcebbc524c 100644 --- a/runtime/doc/change.txt +++ b/runtime/doc/change.txt @@ -90,7 +90,7 @@ start and end of the motion are not in the same line, and there are only blanks before the start and there are no non-blanks after the end of the motion, the delete becomes linewise. This means that the delete also removes the line of blanks that you might expect to remain. Use the |o_v| operator to -force the motion to be characterwise. +force the motion to be charwise. Trying to delete an empty region of text (e.g., "d0" in the first column) is an error when 'cpoptions' includes the 'E' flag. @@ -1074,7 +1074,7 @@ also use these commands to move text from one file to another, because Vim preserves all registers when changing buffers (the CTRL-^ command is a quick way to toggle between two files). - *linewise-register* *characterwise-register* + *linewise-register* *charwise-register* You can repeat the put commands with "." (except for :put) and undo them. If the command that was used to get the text into the register was |linewise|, Vim inserts the text below ("p") or above ("P") the line where the cursor is. @@ -1116,10 +1116,9 @@ this happen. However, if the width of the block is not a multiple of a <Tab> width and the text after the inserted block contains <Tab>s, that text may be misaligned. -Note that after a characterwise yank command, Vim leaves the cursor on the -first yanked character that is closest to the start of the buffer. This means -that "yl" doesn't move the cursor, but "yh" moves the cursor one character -left. +Note that after a charwise yank command, Vim leaves the cursor on the first +yanked character that is closest to the start of the buffer. This means that +"yl" doesn't move the cursor, but "yh" moves the cursor one character left. Rationale: In Vi the "y" command followed by a backwards motion would sometimes not move the cursor to the first yanked character, because redisplaying was skipped. In Vim it always moves to diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index ee1f76e4e4..b31177ce0e 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -1122,11 +1122,9 @@ edited as described in |cmdwin-char|. AUTOCOMMANDS -Two autocommand events are used: |CmdwinEnter| and |CmdwinLeave|. Since this -window is of a special type, the WinEnter, WinLeave, BufEnter and BufLeave -events are not triggered. You can use the Cmdwin events to do settings -specifically for the command-line window. Be careful not to cause side -effects! +Two autocommand events are used: |CmdwinEnter| and |CmdwinLeave|. You can use +the Cmdwin events to do settings specifically for the command-line window. +Be careful not to cause side effects! Example: > :au CmdwinEnter : let b:cpt_save = &cpt | set cpt=. :au CmdwinLeave : let &cpt = b:cpt_save diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index b76a37810c..7c6b9ad1d3 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -14,6 +14,8 @@ updated. API ~ *nvim_buf_clear_highlight()* Use |nvim_buf_clear_namespace()| instead. +*nvim_command_output()* Use |nvim_exec()| instead. +*nvim_execute_lua()* Use |nvim_exec_lua()| instead. Commands ~ *:rv* diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt index 90c2e30771..09c5b7c4ad 100644 --- a/runtime/doc/develop.txt +++ b/runtime/doc/develop.txt @@ -143,6 +143,87 @@ DOCUMENTATION *dev-doc* /// @param dirname The path fragment before `pend` < +C docstrings ~ + +Nvim API documentation lives in the source code, as docstrings (Doxygen +comments) on the function definitions. The |api| :help is generated +from the docstrings defined in src/nvim/api/*.c. + +Docstring format: +- Lines start with `///` +- Special tokens start with `@` followed by the token name: + `@note`, `@param`, `@returns` +- Limited markdown is supported. + - List-items start with `-` (useful to nest or "indent") +- Use `<pre>` for code samples. + +Example: the help for |nvim_open_win()| is generated from a docstring defined +in src/nvim/api/vim.c like this: > + + /// Opens a new window. + /// ... + /// + /// Example (Lua): window-relative float + /// <pre> + /// vim.api.nvim_open_win(0, false, + /// {relative='win', row=3, col=3, width=12, height=3}) + /// </pre> + /// + /// @param buffer Buffer to display + /// @param enter Enter the window + /// @param config Map defining the window configuration. Keys: + /// - relative: Sets the window layout, relative to: + /// - "editor" The global editor grid. + /// - "win" Window given by the `win` field. + /// - "cursor" Cursor position in current window. + /// ... + /// @param[out] err Error details, if any + /// + /// @return Window handle, or 0 on error + + +Lua docstrings ~ + *dev-lua-doc* +Lua documentation lives in the source code, as docstrings on the function +definitions. The |lua-vim| :help is generated from the docstrings. + +Docstring format: +- Lines in the main description start with `---` +- Special tokens start with `--@` followed by the token name: + `--@see`, `--@param`, `--@returns` +- Limited markdown is supported. + - List-items start with `-` (useful to nest or "indent") +- Use `<pre>` for code samples. + +Example: the help for |vim.paste()| is generated from a docstring decorating +vim.paste in src/nvim/lua/vim.lua like this: > + + --- Paste handler, invoked by |nvim_paste()| when a conforming UI + --- (such as the |TUI|) pastes text into the editor. + --- + --- Example: To remove ANSI color codes when pasting: + --- <pre> + --- vim.paste = (function() + --- local overridden = vim.paste + --- ... + --- end)() + --- </pre> + --- + --@see |paste| + --- + --@param lines ... + --@param phase ... + --@returns false if client should cancel the paste. + + +LUA *dev-lua* + +- Keep the core Lua modules |lua-stdlib| simple. Avoid elaborate OOP or + pseudo-OOP designs. Plugin authors just want functions to call, they don't + want to learn a big, fancy inheritance hierarchy. So we should avoid complex + objects: tables are usually better. + + API *dev-api* Use this template to name new API functions: @@ -155,10 +236,11 @@ with a {thing} that groups functions under a common concept). Use existing common {action} names if possible: add Append to, or insert into, a collection - get Get a thing (or group of things by query) - set Set a thing (or group of things) del Delete a thing (or group of things) + exec Execute code + get Get a thing (or group of things by query) list Get all things + set Set a thing (or group of things) Use consistent names for {thing} in all API functions. E.g. a buffer is called "buf" everywhere, not "buffer" in some places and "buf" in others. @@ -268,8 +350,8 @@ External UIs are expected to implement these common features: chords (<C-,> <C-Enter> <C-S-x> <D-x>) and patterns ("shift shift") that do not potentially conflict with Nvim defaults, plugins, etc. - Consider the "option_set" |ui-global| event as a hint for other GUI - behaviors. UI-related options ('guifont', 'ambiwidth', …) are published in - this event. + behaviors. Various UI-related options ('guifont', 'ambiwidth', …) are + published in this event. See also "mouse_on", "mouse_off". vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/runtime/doc/digraph.txt b/runtime/doc/digraph.txt index b106e625f2..7f807b5eee 100644 --- a/runtime/doc/digraph.txt +++ b/runtime/doc/digraph.txt @@ -20,7 +20,9 @@ An alternative is using the 'keymap' option. 1. Defining digraphs *digraphs-define* *:dig* *:digraphs* -:dig[raphs] show currently defined digraphs. +:dig[raphs][!] Show currently defined digraphs. + With [!] headers are used to make it a bit easier to + find a specific character. *E104* *E39* :dig[raphs] {char1}{char2} {number} ... Add digraph {char1}{char2} to the list. {number} is diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 512cfc4e58..597175b5e5 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1217,7 +1217,7 @@ lambda expression *expr-lambda* *lambda* {args -> expr1} lambda expression A lambda expression creates a new unnamed function which returns the result of -evaluating |expr1|. Lambda expressions differ from |user-functions| in +evaluating |expr1|. Lambda expressions differ from |user-function|s in the following ways: 1. The body of the lambda expression is an |expr1| and not a sequence of |Ex| @@ -1547,10 +1547,12 @@ v:errmsg Last given error message. :if v:errmsg != "" : ... handle error < - *v:errors* *errors-variable* + *v:errors* *errors-variable* *assert-return* v:errors Errors found by assert functions, such as |assert_true()|. This is a list of strings. The assert functions append an item when an assert fails. + The return value indicates this: a one is returned if an item + was added to v:errors, otherwise zero is returned. To remove old results make it empty: > :let v:errors = [] < If v:errors is set to anything but a list it is made an empty @@ -1735,6 +1737,10 @@ v:lnum Line number for the 'foldexpr' |fold-expr|, 'formatexpr' and expressions is being evaluated. Read-only when in the |sandbox|. + *v:lua* *lua-variable* +v:lua Prefix for calling Lua functions from expressions. + See |v:lua-call| for more information. + *v:mouse_win* *mouse_win-variable* v:mouse_win Window number for a mouse click obtained with |getchar()|. First window has number 1, like with |winnr()|. The value is @@ -1984,9 +1990,12 @@ v:windowid Application-specific window "handle" which may be set by any |window-ID|. ============================================================================== -4. Builtin Functions *functions* +4. Builtin Functions *vim-function* *functions* + +The Vimscript subsystem (referred to as "eval" internally) provides the +following builtin functions. Scripts can also define |user-function|s. -See |function-list| for a list grouped by what the function is used for. +See |function-list| to browse functions by topic. (Use CTRL-] on the function name to jump to the full explanation.) @@ -2004,24 +2013,26 @@ argidx() Number current index in the argument list arglistid([{winnr} [, {tabnr}]]) Number argument list id argv({nr} [, {winid}]) String {nr} entry of the argument list argv([-1, {winid}]) List the argument list -assert_beeps({cmd}) none assert {cmd} causes a beep +assert_beeps({cmd}) Number assert {cmd} causes a beep assert_equal({exp}, {act} [, {msg}]) - none assert {exp} is equal to {act} + Number assert {exp} is equal to {act} +assert_equalfile({fname-one}, {fname-two}) + Number assert file contents is equal assert_exception({error} [, {msg}]) - none assert {error} is in v:exception -assert_fails({cmd} [, {error}]) none assert {cmd} fails + Number assert {error} is in v:exception +assert_fails({cmd} [, {error}]) Number assert {cmd} fails assert_false({actual} [, {msg}]) - none assert {actual} is false + Number assert {actual} is false assert_inrange({lower}, {upper}, {actual} [, {msg}]) - none assert {actual} is inside the range + Number assert {actual} is inside the range assert_match({pat}, {text} [, {msg}]) - none assert {pat} matches {text} + Number assert {pat} matches {text} assert_notequal({exp}, {act} [, {msg}]) - none assert {exp} is not equal {act} + Number assert {exp} is not equal {act} assert_notmatch({pat}, {text} [, {msg}]) - none assert {pat} not matches {text} -assert_report({msg}) none report a test failure -assert_true({actual} [, {msg}]) none assert {actual} is true + Number assert {pat} not matches {text} +assert_report({msg}) Number report a test failure +assert_true({actual} [, {msg}]) Number assert {actual} is true asin({expr}) Float arc sine of {expr} atan({expr}) Float arc tangent of {expr} atan2({expr}, {expr}) Float arc tangent of {expr1} / {expr2} @@ -2580,12 +2591,13 @@ argv([{nr} [, {winid}]) assert_beeps({cmd}) *assert_beeps()* Run {cmd} and add an error message to |v:errors| if it does NOT produce a beep or visual bell. - Also see |assert_fails()|. + Also see |assert_fails()| and |assert-return|. *assert_equal()* assert_equal({expected}, {actual}, [, {msg}]) When {expected} and {actual} are not equal an error message is - added to |v:errors|. + added to |v:errors| and 1 is returned. Otherwise zero is + returned |assert-return|. There is no automatic conversion, the String "4" is different from the Number 4. And the number 4 is different from the Float 4.0. The value of 'ignorecase' is not used here, case @@ -2597,9 +2609,17 @@ assert_equal({expected}, {actual}, [, {msg}]) < Will result in a string to be added to |v:errors|: test.vim line 12: Expected 'foo' but got 'bar' ~ + *assert_equalfile()* +assert_equalfile({fname-one}, {fname-two}) + When the files {fname-one} and {fname-two} do not contain + exactly the same text an error message is added to |v:errors|. + Also see |assert-return|. + When {fname-one} or {fname-two} does not exist the error will + mention that. + assert_exception({error} [, {msg}]) *assert_exception()* When v:exception does not contain the string {error} an error - message is added to |v:errors|. + message is added to |v:errors|. Also see |assert-return|. This can be used to assert that a command throws an exception. Using the error number, followed by a colon, avoids problems with translations: > @@ -2612,7 +2632,7 @@ assert_exception({error} [, {msg}]) *assert_exception()* assert_fails({cmd} [, {error} [, {msg}]]) *assert_fails()* Run {cmd} and add an error message to |v:errors| if it does - NOT produce an error. + NOT produce an error. Also see |assert-return|. When {error} is given it must match in |v:errmsg|. Note that beeping is not considered an error, and some failing commands only beep. Use |assert_beeps()| for those. @@ -2620,6 +2640,7 @@ assert_fails({cmd} [, {error} [, {msg}]]) *assert_fails()* assert_false({actual} [, {msg}]) *assert_false()* When {actual} is not false an error message is added to |v:errors|, like with |assert_equal()|. + Also see |assert-return|. A value is false when it is zero or |v:false|. When "{actual}" is not a number or |v:false| the assert fails. When {msg} is omitted an error in the form @@ -2636,7 +2657,7 @@ assert_inrange({lower}, {upper}, {actual} [, {msg}]) *assert_inrange()* *assert_match()* assert_match({pattern}, {actual} [, {msg}]) When {pattern} does not match {actual} an error message is - added to |v:errors|. + added to |v:errors|. Also see |assert-return|. {pattern} is used as with |=~|: The matching is always done like 'magic' was set and 'cpoptions' is empty, no matter what @@ -2657,18 +2678,22 @@ assert_match({pattern}, {actual} [, {msg}]) assert_notequal({expected}, {actual} [, {msg}]) The opposite of `assert_equal()`: add an error message to |v:errors| when {expected} and {actual} are equal. + Also see |assert-return|. *assert_notmatch()* assert_notmatch({pattern}, {actual} [, {msg}]) The opposite of `assert_match()`: add an error message to |v:errors| when {pattern} matches {actual}. + Also see |assert-return|. assert_report({msg}) *assert_report()* Report a test failure directly, using {msg}. + Always returns one. assert_true({actual} [, {msg}]) *assert_true()* When {actual} is not true an error message is added to |v:errors|, like with |assert_equal()|. + Also see |assert-return|. A value is |TRUE| when it is a non-zero number or |v:true|. When {actual} is not a number or |v:true| the assert fails. When {msg} is omitted an error in the form "Expected True but @@ -3525,7 +3550,7 @@ exists({expr}) The result is a Number, which is |TRUE| if {expr} is string) *funcname built-in function (see |functions|) or user defined function (see - |user-functions|). Also works for a + |user-function|). Also works for a variable that is a Funcref. varname internal variable (see |internal-variables|). Also works @@ -4479,8 +4504,7 @@ getftype({fname}) *getftype()* systems that support it. On some systems only "dir" and "file" are returned. - *getjumplist()* -getjumplist([{winnr} [, {tabnr}]]) +getjumplist([{winnr} [, {tabnr}]]) *getjumplist()* Returns the |jumplist| for the specified window. Without arguments use the current window. @@ -4536,6 +4560,10 @@ getloclist({nr},[, {what}]) *getloclist()* If the optional {what} dictionary argument is supplied, then returns the items listed in {what} as a dictionary. Refer to |getqflist()| for the supported items in {what}. + If {what} contains 'filewinid', then returns the id of the + window used to display files from the location list. This + field is applicable only when called from a location list + window. getmatches() *getmatches()* Returns a |List| with all matches previously defined for the @@ -4699,7 +4727,7 @@ getreg([{regname} [, 1 [, {list}]]]) *getreg()* getregtype([{regname}]) *getregtype()* The result is a String, which is type of register {regname}. The value will be one of: - "v" for |characterwise| text + "v" for |charwise| text "V" for |linewise| text "<CTRL-V>{width}" for |blockwise-visual| text "" for an empty or unknown register @@ -4941,9 +4969,11 @@ has({feature}) Returns 1 if {feature} is supported, 0 otherwise. The < *feature-list* List of supported pseudo-feature names: acl |ACL| support + bsd BSD system (not macOS, use "mac" for that). iconv Can use |iconv()| for conversion. +shellslash Can use backslashes in filenames (Windows) clipboard |clipboard| provider is available. + mac MacOS system. nvim This is Nvim. python2 Legacy Vim |python2| interface. |has-python| python3 Legacy Vim |python3| interface. |has-python| @@ -4953,6 +4983,7 @@ has({feature}) Returns 1 if {feature} is supported, 0 otherwise. The unix Unix system. *vim_starting* True during |startup|. win32 Windows system (32 or 64 bit). + win64 Windows system (64 bit). wsl WSL (Windows Subsystem for Linux) system *has-patch* @@ -5420,6 +5451,9 @@ jobstart({cmd}[, {opts}]) *jobstart()* |on_exit| : exit event handler (function name or |Funcref|) cwd : Working directory of the job; defaults to |current-directory|. + env : A dict of strings to append (or replace see + |clear_env|) to the current environment. + clear_env: If set, use the exact values passed in |env| rpc : If set, |msgpack-rpc| will be used to communicate with the job over stdin and stdout. "on_stdout" is then ignored, but "on_stderr" can still be used. @@ -6103,7 +6137,7 @@ mode([expr]) Return a string that indicates the current mode. n Normal no Operator-pending - nov Operator-pending (forced characterwise |o_v|) + nov Operator-pending (forced charwise |o_v|) noV Operator-pending (forced linewise |o_V|) noCTRL-V Operator-pending (forced blockwise |o_CTRL-V|) niI Normal using |i_CTRL-O| in |Insert-mode| @@ -6640,7 +6674,7 @@ remote_expr({server}, {string} [, {idvar} [, {timeout}]]) between (not at the end), like with join(expr, "\n"). If {idvar} is present and not empty, it is taken as the name of a variable and a {serverid} for later use with - remote_read() is stored there. + |remote_read()| is stored there. If {timeout} is given the read times out after this many seconds. Otherwise a timeout of 600 seconds is used. See also |clientserver| |RemoteReply|. @@ -7413,7 +7447,7 @@ setreg({regname}, {value} [, {options}]) If {options} contains "a" or {regname} is upper case, then the value is appended. {options} can also contain a register type specification: - "c" or "v" |characterwise| mode + "c" or "v" |charwise| mode "l" or "V" |linewise| mode "b" or "<CTRL-V>" |blockwise-visual| mode If a number immediately follows "b" or "<CTRL-V>" then this is @@ -9222,7 +9256,7 @@ Don't forget that "^" will only match at the first character of the String and "\n". ============================================================================== -5. Defining functions *user-functions* +5. Defining functions *user-function* New functions can be defined. These can be called just like builtin functions. The function executes a sequence of Ex commands. Normal mode @@ -9680,7 +9714,7 @@ This does NOT work: > register, "@/" for the search pattern. If the result of {expr1} ends in a <CR> or <NL>, the register will be linewise, otherwise it will be set to - characterwise. + charwise. This can be used to clear the last search pattern: > :let @/ = "" < This is different from searching for an empty string, @@ -9762,6 +9796,54 @@ This does NOT work: > Like above, but append/add/subtract the value for each |List| item. + *:let=<<* *:let-heredoc* + *E990* *E991* *E172* *E221* +:let {var-name} =<< [trim] {marker} +text... +text... +{marker} + Set internal variable {var-name} to a List containing + the lines of text bounded by the string {marker}. + {marker} cannot start with a lower case character. + The last line should end only with the {marker} string + without any other character. Watch out for white + space after {marker}! + + Without "trim" any white space characters in the lines + of text are preserved. If "trim" is specified before + {marker}, then indentation is stripped so you can do: > + let text =<< trim END + if ok + echo 'done' + endif + END +< Results in: ["if ok", " echo 'done'", "endif"] + The marker must line up with "let" and the indentation + of the first line is removed from all the text lines. + Specifically: all the leading indentation exactly + matching the leading indentation of the first + non-empty text line is stripped from the input lines. + All leading indentation exactly matching the leading + indentation before `let` is stripped from the line + containing {marker}. Note that the difference between + space and tab matters here. + + If {var-name} didn't exist yet, it is created. + Cannot be followed by another command, but can be + followed by a comment. + + Examples: > + let var1 =<< END + Sample text 1 + Sample text 2 + Sample text 3 + END + + let data =<< trim DATA + 1 2 3 4 + 5 6 7 8 + DATA +< *E121* :let {var-name} .. List the value of variable {var-name}. Multiple variable names may be given. Special names recognized diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index c579c390c6..c649688d99 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -549,7 +549,9 @@ Variables: *b:man_default_sects* Comma-separated, ordered list of preferred sections. For example in C one usually wants section 3 or 2: > :let b:man_default_sections = '3,2' -*g:man_hardwrap* Hard-wrap to $MANWIDTH. May improve layout. +*g:man_hardwrap* Hard-wrap to $MANWIDTH or window width if $MANWIDTH is + empty. Enabled by default. Set |FALSE| to enable soft + wrapping. To use Nvim as a manpager: > export MANPAGER='nvim +Man!' @@ -558,10 +560,13 @@ Note that when running `man` from the shell and with that `MANPAGER` in your environment, `man` will pre-format the manpage using `groff`. Thus, Neovim 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 `:Man`. You can set in your environment: > +soft wrapped as with `g:man_hardwrap=0`. You can set in your environment: > export MANWIDTH=999 -So `groff`'s pre-formatting output will be the same as with `:Man` i.e soft-wrapped. +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 PDF *ft-pdf-plugin* diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt index 284cd26583..6090fa96bb 100644 --- a/runtime/doc/help.txt +++ b/runtime/doc/help.txt @@ -129,6 +129,7 @@ Advanced editing ~ |autocmd.txt| automatically executing commands on an event |eval.txt| expression evaluation, conditional commands |fold.txt| hide (fold) ranges of lines +|lua.txt| Lua API Special issues ~ |print.txt| printing @@ -157,7 +158,6 @@ GUI ~ Interfaces ~ |if_cscop.txt| using Cscope with Vim -|if_lua.txt| Lua interface |if_pyth.txt| Python interface |if_ruby.txt| Ruby interface |sign.txt| debugging signs diff --git a/runtime/doc/if_lua.txt b/runtime/doc/if_lua.txt index aa2d0a03c6..34bcf0f039 100644 --- a/runtime/doc/if_lua.txt +++ b/runtime/doc/if_lua.txt @@ -1,668 +1,8 @@ -*if_lua.txt* Nvim - NVIM REFERENCE MANUAL + NVIM REFERENCE MANUAL - -Lua engine *lua* *Lua* - - Type |gO| to see the table of contents. - -============================================================================== -Introduction *lua-intro* - -The Lua 5.1 language is builtin and always available. Try this command to get -an idea of what lurks beneath: > - - :lua print(vim.inspect(package.loaded)) - -Nvim includes a "standard library" |lua-stdlib| for Lua. It complements the -"editor stdlib" (|functions| and Ex commands) and the |API|, all of which can -be used from Lua code. - -Module conflicts are resolved by "last wins". For example if both of these -are on 'runtimepath': - runtime/lua/foo.lua - ~/.config/nvim/lua/foo.lua -then `require('foo')` loads "~/.config/nvim/lua/foo.lua", and -"runtime/lua/foo.lua" is not used. See |lua-require| to understand how Nvim -finds and loads Lua modules. The conventions are similar to VimL plugins, -with some extra features. See |lua-require-example| for a walkthrough. - -============================================================================== -Importing Lua modules *lua-require* - -Nvim automatically adjusts `package.path` and `package.cpath` according to -effective 'runtimepath' value. Adjustment happens whenever 'runtimepath' is -changed. `package.path` is adjusted by simply appending `/lua/?.lua` and -`/lua/?/init.lua` to each directory from 'runtimepath' (`/` is actually the -first character of `package.config`). - -Similarly to `package.path`, modified directories from 'runtimepath' are also -added to `package.cpath`. In this case, instead of appending `/lua/?.lua` and -`/lua/?/init.lua` to each runtimepath, all unique `?`-containing suffixes of -the existing `package.cpath` are used. Example: - -1. Given that - - 'runtimepath' contains `/foo/bar,/xxx;yyy/baz,/abc`; - - initial (defined at compile-time or derived from - `$LUA_CPATH`/`$LUA_INIT`) `package.cpath` contains - `./?.so;/def/ghi/a?d/j/g.elf;/def/?.so`. -2. It finds `?`-containing suffixes `/?.so`, `/a?d/j/g.elf` and `/?.so`, in - order: parts of the path starting from the first path component containing - question mark and preceding path separator. -3. The suffix of `/def/?.so`, namely `/?.so` is not unique, as it’s the same - as the suffix of the first path from `package.path` (i.e. `./?.so`). Which - leaves `/?.so` and `/a?d/j/g.elf`, in this order. -4. 'runtimepath' has three paths: `/foo/bar`, `/xxx;yyy/baz` and `/abc`. The - second one contains semicolon which is a paths separator so it is out, - leaving only `/foo/bar` and `/abc`, in order. -5. The cartesian product of paths from 4. and suffixes from 3. is taken, - giving four variants. In each variant `/lua` path segment is inserted - between path and suffix, leaving - - - `/foo/bar/lua/?.so` - - `/foo/bar/lua/a?d/j/g.elf` - - `/abc/lua/?.so` - - `/abc/lua/a?d/j/g.elf` - -6. New paths are prepended to the original `package.cpath`. - -The result will look like this: - - `/foo/bar,/xxx;yyy/baz,/abc` ('runtimepath') - × `./?.so;/def/ghi/a?d/j/g.elf;/def/?.so` (`package.cpath`) - - = `/foo/bar/lua/?.so;/foo/bar/lua/a?d/j/g.elf;/abc/lua/?.so;/abc/lua/a?d/j/g.elf;./?.so;/def/ghi/a?d/j/g.elf;/def/?.so` - -Note: - -- To track 'runtimepath' updates, paths added at previous update are - remembered and removed at the next update, while all paths derived from the - new 'runtimepath' are prepended as described above. This allows removing - paths when path is removed from 'runtimepath', adding paths when they are - added and reordering `package.path`/`package.cpath` content if 'runtimepath' - was reordered. - -- Although adjustments happen automatically, Nvim does not track current - values of `package.path` or `package.cpath`. If you happen to delete some - paths from there you can set 'runtimepath' to trigger an update: > - let &runtimepath = &runtimepath - -- Skipping paths from 'runtimepath' which contain semicolons applies both to - `package.path` and `package.cpath`. Given that there are some badly written - plugins using shell which will not work with paths containing semicolons it - is better to not have them in 'runtimepath' at all. - ------------------------------------------------------------------------------- -LUA PLUGIN EXAMPLE *lua-require-example* - -The following example plugin adds a command `:MakeCharBlob` which transforms -current buffer into a long `unsigned char` array. Lua contains transformation -function in a module `lua/charblob.lua` which is imported in -`autoload/charblob.vim` (`require("charblob")`). Example plugin is supposed -to be put into any directory from 'runtimepath', e.g. `~/.config/nvim` (in -this case `lua/charblob.lua` means `~/.config/nvim/lua/charblob.lua`). - -autoload/charblob.vim: > - - function charblob#encode_buffer() - call setline(1, luaeval( - \ 'require("charblob").encode(unpack(_A))', - \ [getline(1, '$'), &textwidth, ' '])) - endfunction - -plugin/charblob.vim: > - - if exists('g:charblob_loaded') - finish - endif - let g:charblob_loaded = 1 - - command MakeCharBlob :call charblob#encode_buffer() - -lua/charblob.lua: > - - local function charblob_bytes_iter(lines) - local init_s = { - next_line_idx = 1, - next_byte_idx = 1, - lines = lines, - } - local function next(s, _) - if lines[s.next_line_idx] == nil then - return nil - end - if s.next_byte_idx > #(lines[s.next_line_idx]) then - s.next_line_idx = s.next_line_idx + 1 - s.next_byte_idx = 1 - return ('\n'):byte() - end - local ret = lines[s.next_line_idx]:byte(s.next_byte_idx) - if ret == ('\n'):byte() then - ret = 0 -- See :h NL-used-for-NUL. - end - s.next_byte_idx = s.next_byte_idx + 1 - return ret - end - return next, init_s, nil - end - - local function charblob_encode(lines, textwidth, indent) - local ret = { - 'const unsigned char blob[] = {', - indent, - } - for byte in charblob_bytes_iter(lines) do - -- .- space + number (width 3) + comma - if #(ret[#ret]) + 5 > textwidth then - ret[#ret + 1] = indent - else - ret[#ret] = ret[#ret] .. ' ' - end - ret[#ret] = ret[#ret] .. (('%3u,'):format(byte)) - end - ret[#ret + 1] = '};' - return ret - end - - return { - bytes_iter = charblob_bytes_iter, - encode = charblob_encode, - } - -============================================================================== -Commands *lua-commands* - - *:lua* -:[range]lua {chunk} - Execute Lua chunk {chunk}. - -Examples: -> - :lua vim.api.nvim_command('echo "Hello, Nvim!"') -< -To see the Lua version: > - :lua print(_VERSION) - -To see the LuaJIT version: > - :lua print(jit.version) -< - -:[range]lua << [endmarker] -{script} -{endmarker} - Execute Lua script {script}. Useful for including Lua - code in Vim scripts. - -The {endmarker} must NOT be preceded by any white space. - -If [endmarker] is omitted from after the "<<", a dot '.' must be used after -{script}, like for the |:append| and |:insert| commands. - -Example: -> - function! CurrentLineInfo() - lua << EOF - local linenr = vim.api.nvim_win_get_cursor(0)[1] - local curline = vim.api.nvim_buf_get_lines( - 0, linenr, linenr + 1, false)[1] - print(string.format("Current line [%d] has %d bytes", - linenr, #curline)) - EOF - endfunction - -Note that the `local` variables will disappear when block finishes. This is -not the case for globals. - - *:luado* -:[range]luado {body} Execute Lua function "function (line, linenr) {body} - end" for each line in the [range], with the function - argument being set to the text of each line in turn, - without a trailing <EOL>, and the current line number. - If the value returned by the function is a string it - becomes the text of the line in the current turn. The - default for [range] is the whole file: "1,$". - -Examples: -> - :luado return string.format("%s\t%d", line:reverse(), #line) - - :lua require"lpeg" - :lua -- balanced parenthesis grammar: - :lua bp = lpeg.P{ "(" * ((1 - lpeg.S"()") + lpeg.V(1))^0 * ")" } - :luado if bp:match(line) then return "-->\t" .. line end -< - - *:luafile* -:[range]luafile {file} - Execute Lua script in {file}. - The whole argument is used as a single file name. - -Examples: -> - :luafile script.lua - :luafile % -< - -All these commands execute a Lua chunk from either the command line (:lua and -:luado) or a file (:luafile) with the given line [range]. Similarly to the Lua -interpreter, each chunk has its own scope and so only global variables are -shared between command calls. All Lua default libraries are available. In -addition, Lua "print" function has its output redirected to the Nvim message -area, with arguments separated by a white space instead of a tab. - -Lua uses the "vim" module (see |lua-vim|) to issue commands to Nvim. However, -procedures that alter buffer content, open new buffers, and change cursor -position are restricted when the command is executed in the |sandbox|. - - -============================================================================== -luaeval() *lua-eval* *luaeval()* - -The (dual) equivalent of "vim.eval" for passing Lua values to Nvim is -"luaeval". "luaeval" takes an expression string and an optional argument used -for _A inside expression and returns the result of the expression. It is -semantically equivalent in Lua to: -> - local chunkheader = "local _A = select(1, ...) return " - function luaeval (expstr, arg) - local chunk = assert(loadstring(chunkheader .. expstr, "luaeval")) - return chunk(arg) -- return typval - end - -Lua nils, numbers, strings, tables and booleans are converted to their -respective VimL types. An error is thrown if conversion of any other Lua types -is attempted. - -The magic global "_A" contains the second argument to luaeval(). - -Example: > - :echo luaeval('_A[1] + _A[2]', [40, 2]) - 42 - :echo luaeval('string.match(_A, "[a-z]+")', 'XYXfoo123') - foo - -Lua tables are used as both dictionaries and lists, so it is impossible to -determine whether empty table is meant to be empty list or empty dictionary. -Additionally lua does not have integer numbers. To distinguish between these -cases there is the following agreement: - -0. Empty table is empty list. -1. Table with N incrementally growing integral numbers, starting from 1 and - ending with N is considered to be a list. -2. Table with string keys, none of which contains NUL byte, is considered to - be a dictionary. -3. Table with string keys, at least one of which contains NUL byte, is also - considered to be a dictionary, but this time it is converted to - a |msgpack-special-map|. - *lua-special-tbl* -4. Table with `vim.type_idx` key may be a dictionary, a list or floating-point - value: - - `{[vim.type_idx]=vim.types.float, [vim.val_idx]=1}` is converted to - a floating-point 1.0. Note that by default integral lua numbers are - converted to |Number|s, non-integral are converted to |Float|s. This - variant allows integral |Float|s. - - `{[vim.type_idx]=vim.types.dictionary}` is converted to an empty - dictionary, `{[vim.type_idx]=vim.types.dictionary, [42]=1, a=2}` is - converted to a dictionary `{'a': 42}`: non-string keys are ignored. - Without `vim.type_idx` key tables with keys not fitting in 1., 2. or 3. - are errors. - - `{[vim.type_idx]=vim.types.list}` is converted to an empty list. As well - as `{[vim.type_idx]=vim.types.list, [42]=1}`: integral keys that do not - form a 1-step sequence from 1 to N are ignored, as well as all - non-integral keys. - -Examples: > - - :echo luaeval('math.pi') - :function Rand(x,y) " random uniform between x and y - : return luaeval('(_A.y-_A.x)*math.random()+_A.x', {'x':a:x,'y':a:y}) - : endfunction - :echo Rand(1,10) - -Note that currently second argument to `luaeval` undergoes VimL to lua -conversion, so changing containers in lua do not affect values in VimL. Return -value is also always converted. When converting, |msgpack-special-dict|s are -treated specially. - -============================================================================== -Lua standard modules *lua-stdlib* - -The Nvim Lua "standard library" (stdlib) is the `vim` module, which exposes -various functions and sub-modules. It is always loaded, thus require("vim") -is unnecessary. - -You can peek at the module properties: > - - :lua print(vim.inspect(vim)) - -Result is something like this: > - - { - _os_proc_children = <function 1>, - _os_proc_info = <function 2>, - ... - api = { - nvim__id = <function 5>, - nvim__id_array = <function 6>, - ... - }, - deepcopy = <function 106>, - gsplit = <function 107>, - ... - } - -To find documentation on e.g. the "deepcopy" function: > - - :help vim.deepcopy - -Note that underscore-prefixed functions (e.g. "_os_proc_children") are -internal/private and must not be used by plugins. - ------------------------------------------------------------------------------- -VIM.API *lua-api* - -`vim.api` exposes the full Nvim |API| as a table of Lua functions. - -Example: to use the "nvim_get_current_line()" API function, call -"vim.api.nvim_get_current_line()": > - - print(tostring(vim.api.nvim_get_current_line())) - ------------------------------------------------------------------------------- -VIM.LOOP *lua-loop* - -`vim.loop` exposes all features of the Nvim event-loop. This is a low-level -API that provides functionality for networking, filesystem, and process -management. Try this command to see available functions: > - - :lua print(vim.inspect(vim.loop)) - -Reference: http://docs.libuv.org -Examples: https://github.com/luvit/luv/tree/master/examples - - *E5560* *lua-loop-callbacks* -It is an error to directly invoke `vim.api` functions (except |api-fast|) in -`vim.loop` callbacks. For example, this is an error: > - - local timer = vim.loop.new_timer() - timer:start(1000, 0, function() - vim.api.nvim_command('echomsg "test"') - end) - -To avoid the error use |vim.schedule_wrap()| to defer the callback: > - - local timer = vim.loop.new_timer() - timer:start(1000, 0, vim.schedule_wrap(function() - vim.api.nvim_command('echomsg "test"') - end)) - -Example: repeating timer - 1. Save this code to a file. - 2. Execute it with ":luafile %". > - - -- Create a timer handle (implementation detail: uv_timer_t). - local timer = vim.loop.new_timer() - local i = 0 - -- Waits 1000ms, then repeats every 750ms until timer:close(). - timer:start(1000, 750, function() - print('timer invoked! i='..tostring(i)) - if i > 4 then - timer:close() -- Always close handles to avoid leaks. - end - i = i + 1 - end) - print('sleeping'); - - -Example: TCP echo-server *tcp-server* - 1. Save this code to a file. - 2. Execute it with ":luafile %". - 3. Note the port number. - 4. Connect from any TCP client (e.g. "nc 0.0.0.0 36795"): > - - local function create_server(host, port, on_connection) - local server = vim.loop.new_tcp() - server:bind(host, port) - server:listen(128, function(err) - assert(not err, err) -- Check for errors. - local sock = vim.loop.new_tcp() - server:accept(sock) -- Accept client connection. - on_connection(sock) -- Start reading messages. - end) - return server - end - local server = create_server('0.0.0.0', 0, function(sock) - sock:read_start(function(err, chunk) - assert(not err, err) -- Check for errors. - if chunk then - sock:write(chunk) -- Echo received messages to the channel. - else -- EOF (stream closed). - sock:close() -- Always close handles to avoid leaks. - end - end) - end) - print('TCP echo-server listening on port: '..server:getsockname().port) - ------------------------------------------------------------------------------- -VIM *lua-util* - -vim.in_fast_event() *vim.in_fast_event()* - Returns true if the code is executing as part of a "fast" event - handler, where most of the API is disabled. These are low-level events - (e.g. |lua-loop-callbacks|) which can be invoked whenever Nvim polls - for input. When this is `false` most API functions are callable (but - may be subject to other restrictions such as |textlock|). - -vim.stricmp({a}, {b}) *vim.stricmp()* - Compares strings case-insensitively. Returns 0, 1 or -1 if strings - are equal, {a} is greater than {b} or {a} is lesser than {b}, - respectively. - -vim.str_utfindex({str}[, {index}]) *vim.str_utfindex()* - Convert byte index to UTF-32 and UTF-16 indicies. If {index} is not - supplied, the length of the string is used. All indicies are zero-based. - Returns two values: the UTF-32 and UTF-16 indicies respectively. - - Embedded NUL bytes are treated as terminating the string. Invalid - UTF-8 bytes, and embedded surrogates are counted as one code - point each. An {index} in the middle of a UTF-8 sequence is rounded - upwards to the end of that sequence. - -vim.str_byteindex({str}, {index}[, {use_utf16}]) *vim.str_byteindex()* - Convert UTF-32 or UTF-16 {index} to byte index. If {use_utf16} is not - supplied, it defaults to false (use UTF-32). Returns the byte index. - - Invalid UTF-8 and NUL is treated like by |vim.str_byteindex()|. An {index} - in the middle of a UTF-16 sequence is rounded upwards to the end of that - sequence. - -vim.schedule({callback}) *vim.schedule()* - Schedules {callback} to be invoked soon by the main event-loop. Useful - to avoid |textlock| or other temporary restrictions. - -vim.type_idx *vim.type_idx* - Type index for use in |lua-special-tbl|. Specifying one of the - values from |vim.types| allows typing the empty table (it is - unclear whether empty lua table represents empty list or empty array) - and forcing integral numbers to be |Float|. See |lua-special-tbl| for - more details. - -vim.val_idx *vim.val_idx* - Value index for tables representing |Float|s. A table representing - floating-point value 1.0 looks like this: > - { - [vim.type_idx] = vim.types.float, - [vim.val_idx] = 1.0, - } -< See also |vim.type_idx| and |lua-special-tbl|. - -vim.types *vim.types* - Table with possible values for |vim.type_idx|. Contains two sets - of key-value pairs: first maps possible values for |vim.type_idx| - to human-readable strings, second maps human-readable type names to - values for |vim.type_idx|. Currently contains pairs for `float`, - `array` and `dictionary` types. - - Note: one must expect that values corresponding to `vim.types.float`, - `vim.types.array` and `vim.types.dictionary` fall under only two - following assumptions: - 1. Value may serve both as a key and as a value in a table. Given the - properties of lua tables this basically means “value is not `nil`”. - 2. For each value in `vim.types` table `vim.types[vim.types[value]]` - is the same as `value`. - No other restrictions are put on types, and it is not guaranteed that - values corresponding to `vim.types.float`, `vim.types.array` and - `vim.types.dictionary` will not change or that `vim.types` table will - only contain values for these three types. +Moved to |lua.txt| ============================================================================== -Lua module: vim *lua-vim* - -inspect({object}, {options}) *vim.inspect()* - Return a human-readable representation of the given object. - - See also: ~ - https://github.com/kikito/inspect.lua - https://github.com/mpeterv/vinspect - -paste({lines}, {phase}) *vim.paste()* - Paste handler, invoked by |nvim_paste()| when a conforming UI - (such as the |TUI|) pastes text into the editor. - - Parameters: ~ - {lines} |readfile()|-style list of lines to paste. - |channel-lines| - {phase} -1: "non-streaming" paste: the call contains all - lines. If paste is "streamed", `phase` indicates the stream state: - • 1: starts the paste (exactly once) - • 2: continues the paste (zero or more times) - • 3: ends the paste (exactly once) - - Return: ~ - false if client should cancel the paste. - - See also: ~ - |paste| - -schedule_wrap({cb}) *vim.schedule_wrap()* - Defers callback `cb` until the Nvim API is safe to call. - - See also: ~ - |lua-loop-callbacks| - |vim.schedule()| - |vim.in_fast_event()| - - - - -deepcopy({orig}) *vim.deepcopy()* - Returns a deep copy of the given object. Non-table objects are - copied as in a typical Lua assignment, whereas table objects - are copied recursively. - - Parameters: ~ - {orig} Table to copy - - Return: ~ - New table of copied keys and (nested) values. - -gsplit({s}, {sep}, {plain}) *vim.gsplit()* - Splits a string at each instance of a separator. - - Parameters: ~ - {s} String to split - {sep} Separator string or pattern - {plain} If `true` use `sep` literally (passed to - String.find) - - Return: ~ - Iterator over the split components - - See also: ~ - |vim.split()| - https://www.lua.org/pil/20.2.html - http://lua-users.org/wiki/StringLibraryTutorial - -split({s}, {sep}, {plain}) *vim.split()* - Splits a string at each instance of a separator. - - Examples: > - split(":aa::b:", ":") --> {'','aa','','bb',''} - split("axaby", "ab?") --> {'','x','y'} - split(x*yz*o, "*", true) --> {'x','yz','o'} -< - - Parameters: ~ - {s} String to split - {sep} Separator string or pattern - {plain} If `true` use `sep` literally (passed to - String.find) - - Return: ~ - List-like table of the split components. - - See also: ~ - |vim.gsplit()| - -tbl_contains({t}, {value}) *vim.tbl_contains()* - Checks if a list-like (vector) table contains `value` . - - Parameters: ~ - {t} Table to check - {value} Value to compare - - Return: ~ - true if `t` contains `value` - -tbl_extend({behavior}, {...}) *vim.tbl_extend()* - Merges two or more map-like tables. - - Parameters: ~ - {behavior} Decides what to do if a key is found in more - than one map: - • "error": raise an error - • "keep": use value from the leftmost map - • "force": use value from the rightmost map - {...} Two or more map-like tables. - - See also: ~ - |extend()| - -tbl_flatten({t}) *vim.tbl_flatten()* - Creates a copy of a list-like table such that any nested - tables are "unrolled" and appended to the result. - - Parameters: ~ - {t} List-like table - - Return: ~ - Flattened copy of the given list-like table. - -trim({s}) *vim.trim()* - Trim whitespace (Lua pattern "%s") from both sides of a - string. - - Parameters: ~ - {s} String to trim - - Return: ~ - String with whitespace removed from its beginning and end - - See also: ~ - https://www.lua.org/pil/20.2.html - -pesc({s}) *vim.pesc()* - Escapes magic chars in a Lua pattern string. - - Parameters: ~ - {s} String to escape - - Return: ~ - %-escaped pattern string - - See also: ~ - https://github.com/rxi/lume - - vim:tw=78:ts=8:ft=help:norl: + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index be9e25113a..ed9853a8da 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -404,7 +404,7 @@ tag char note action in Normal mode ~ |t| t{char} 1 cursor till before Nth occurrence of {char} to the right |u| u 2 undo changes -|v| v start characterwise Visual mode +|v| v start charwise Visual mode |w| w 1 cursor N words forward |x| ["x]x 2 delete N characters under and after the cursor [into register x] @@ -767,6 +767,7 @@ tag char note action in Normal mode ~ |gn| gn 1,2 find the next match with the last used search pattern and Visually select it |gm| gm 1 go to character at middle of the screenline +|gM| gM 1 go to character at middle of the text line |go| go 1 cursor to byte N in the buffer |gp| ["x]gp 2 put the text [from register x] after the cursor N times, leave the cursor after it @@ -865,7 +866,7 @@ These can be used after an operator, but before a {motion} has been entered. tag char action in Operator-pending mode ~ ----------------------------------------------------------------------- -|o_v| v force operator to work characterwise +|o_v| v force operator to work charwise |o_V| V force operator to work linewise |o_CTRL-V| CTRL-V force operator to work blockwise @@ -977,7 +978,7 @@ tag command note action in Visual mode ~ |v_r| r 2 replace highlighted area with a character |v_s| s 2 delete highlighted area and start insert |v_u| u 2 make highlighted area lowercase -|v_v| v make Visual mode characterwise or stop +|v_v| v make Visual mode charwise or stop Visual mode |v_x| x 2 delete the highlighted area |v_y| y yank the highlighted area @@ -1163,11 +1164,13 @@ tag command action ~ |:cNfile| :cNf[ile] go to last error in previous file |:cabbrev| :ca[bbrev] like ":abbreviate" but for Command-line mode |:cabclear| :cabc[lear] clear all abbreviations for Command-line mode +|:cabove| :cabo[ve] go to error above current line |:caddbuffer| :cad[dbuffer] add errors from buffer |:caddexpr| :cadde[xpr] add errors from expr |:caddfile| :caddf[ile] add error message to current quickfix list |:call| :cal[l] call a function |:catch| :cat[ch] part of a :try command +|:cbelow| :cbe[low] go to error below current line |:cbottom| :cbo[ttom] scroll to the bottom of the quickfix window |:cbuffer| :cb[uffer] parse error messages and jump to first error |:cc| :cc go to specific error @@ -1324,12 +1327,14 @@ tag command action ~ |:lNext| :lN[ext] go to previous entry in location list |:lNfile| :lNf[ile] go to last entry in previous file |:list| :l[ist] print lines +|:labove| :lab[ove] go to location above current line |:laddexpr| :lad[dexpr] add locations from expr |:laddbuffer| :laddb[uffer] add locations from buffer |:laddfile| :laddf[ile] add locations to current location list |:last| :la[st] go to the last file in the argument list |:language| :lan[guage] set the language (locale) |:later| :lat[er] go to newer change, redo +|:lbelow| :lbe[low] go to location below current line |:lbottom| :lbo[ttom] scroll to the bottom of the location window |:lbuffer| :lb[uffer] parse locations and jump to first location |:lcd| :lc[d] change directory locally diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt index 887ef764bd..c59ed43a47 100644 --- a/runtime/doc/intro.txt +++ b/runtime/doc/intro.txt @@ -271,7 +271,7 @@ and <> are part of what you type, the context should make this clear. operator is pending. - Ex commands can be used to move the cursor. This can be used to call a function that does some complicated motion. - The motion is always characterwise exclusive, no matter + The motion is always charwise exclusive, no matter what ":" command is used. This means it's impossible to include the last character of a line without the line break (unless 'virtualedit' is set). @@ -378,11 +378,11 @@ notation meaning equivalent decimal value(s) ~ <kEqual> keypad = *keypad-equal* <kEnter> keypad Enter *keypad-enter* <k0> - <k9> keypad 0 to 9 *keypad-0* *keypad-9* -<S-...> shift-key *shift* *<S-* -<C-...> control-key *control* *ctrl* *<C-* -<M-...> alt-key or meta-key *META* *ALT* *<M-* -<A-...> same as <M-...> *<A-* -<D-...> command-key or "super" key *<D-* +<S-…> shift-key *shift* *<S-* +<C-…> control-key *control* *ctrl* *<C-* +<M-…> alt-key or meta-key *META* *ALT* *<M-* +<A-…> same as <M-…> *<A-* +<D-…> command-key or "super" key *<D-* ----------------------------------------------------------------------- Note: The shifted cursor keys, the help key, and the undo key are only diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt new file mode 100644 index 0000000000..d6d16b8481 --- /dev/null +++ b/runtime/doc/lsp.txt @@ -0,0 +1,575 @@ +*lsp.txt* Nvim LSP API + + NVIM REFERENCE MANUAL + + +Nvim Language Server Protocol (LSP) API *lsp* + +Nvim is a client to the Language Server Protocol: + + https://microsoft.github.io/language-server-protocol/ + + Type |gO| to see the table of contents. + +================================================================================ +LANGUAGE SERVER PROTOCOL (LSP) CLIENT *lsp-intro* + +The `vim.lsp` Lua module provides a flexible API for consuming LSP servers. + +To use LSP in practice, a language server must be installed. + https://microsoft.github.io/language-server-protocol/implementors/servers/ + +After installing a language server to your machine, you must tell Nvim how to +start and interact with that language server. +- Easy way: use the configs provided here by the nvim-lsp plugin. + https://github.com/neovim/nvim-lsp +- Low-level way: use |vim.lsp.start_client()| and |vim.lsp.buf_attach_client()| + directly. Useful if you want to build advanced LSP plugins based on the + Nvim LSP module. |lsp-advanced-js-example| + + *lsp-config* +Nvim LSP client will automatically provide inline diagnostics when available. +|lsp-callbacks| But you probably want to use other features too, such as +go-to-definition, "hover", etc. Example config: > + + nnoremap <silent> gd <cmd>lua vim.lsp.buf.declaration()<CR> + nnoremap <silent> <c-]> <cmd>lua vim.lsp.buf.definition()<CR> + nnoremap <silent> K <cmd>lua vim.lsp.buf.hover()<CR> + nnoremap <silent> gD <cmd>lua vim.lsp.buf.implementation()<CR> + nnoremap <silent> <c-k> <cmd>lua vim.lsp.buf.signature_help()<CR> + nnoremap <silent> 1gD <cmd>lua vim.lsp.buf.type_definition()<CR> + +< + *vim.lsp.omnifunc()* +Nvim provides the vim.lsp.omnifunc 'omnifunc' handler which allows +|i_CTRL-X_CTRL-O| to consume LSP completion features. Example config (note the +use of |v:lua| to call Lua from Vimscript): > + + " Use LSP omni-completion in Python files. + autocmd Filetype python setlocal omnifunc=v:lua.vim.lsp.omnifunc + + +FAQ ~ + +> How to force-reload LSP? + +Stop all clients, then reload the buffer. > + + :lua vim.lsp.stop_all_clients() + :edit + +> Why isn't completion working? + +In the buffer where you want to use LSP, check that 'omnifunc' is set to +"v:lua.vim.lsp.omnifunc": > + + :verbose set omnifunc? + +Some other plugin may be overriding the option. To avoid that, you could set +the option in an |after-directory| ftplugin, e.g. "after/ftplugin/python.vim". + +================================================================================ + *lsp-core-api* +These are the core api functions for working with clients. You will mainly be +using |vim.lsp.start_client()| and |vim.lsp.buf_attach_client()| for operations +and |vim.lsp.get_client_by_id()| to retrieve a client by its id after it has +initialized (or {config.on_init}. see below) + + *vim.lsp.start_client()* + +vim.lsp.start_client({config}) + + The main function used for starting clients. + Start a client and initialize it. + + Its arguments are passed via a configuration object {config}. + + Mandatory parameters:~ + + `root_dir` + {string} specifying the directory where the LSP server will base + as its rootUri on initialization. + + `cmd` + {string} or {list} which is the base command to execute for the LSP. A + string will be run using |'shell'| and a list will be interpreted as a + bare command with arguments passed. This is the same as |jobstart()|. + + Optional parameters:~ + + `cmd_cwd` + {string} specifying the directory to launch the `cmd` process. This is not + related to `root_dir`. + By default, |getcwd()| is used. + + `cmd_env` + {table} specifying the environment flags to pass to the LSP on spawn. + This can be specified using keys like a map or as a list with `k=v` pairs + or both. Non-string values are coerced to a string. + For example: + `{ "PRODUCTION=true"; "TEST=123"; PORT = 8080; HOST = "0.0.0.0"; }` + + `capabilities` + A {table} which will be used instead of + `vim.lsp.protocol.make_client_capabilities()` which contains Nvim's + default capabilities and passed to the language server on initialization. + You'll probably want to use make_client_capabilities() and modify the + result. + NOTE: + To send an empty dictionary, you should use + `{[vim.type_idx]=vim.types.dictionary}` Otherwise, it will be encoded as + an array. + + `callbacks` + A {table} of whose keys are language server method names and the values + are `function(err, method, params, client_id)` See |lsp-callbacks| for + more. This will be combined with |lsp-default-callbacks| to resolve + the callbacks for a client as a fallback. + + `init_options` + A {table} of values to pass in the initialization request as + `initializationOptions`. See the `initialize` in the LSP spec. + + `name` + A {string} used in log messages. Defaults to {client_id} + + `offset_encoding` + One of "utf-8", "utf-16", or "utf-32" which is the encoding that the LSP + server expects. + The default encoding for Language Server Protocol is UTF-16, but there are + language servers which may use other encodings. + By default, it is "utf-16" as specified in the LSP specification. The + client does not verify this is correct. + + `on_error(code, ...)` + A function for handling errors thrown by client operation. {code} is a + number describing the error. Other arguments may be passed depending on + the error kind. See |vim.lsp.client_errors| for possible errors. + `vim.lsp.client_errors[code]` can be used to retrieve a human + understandable string. + + `before_init(initialize_params, config)` + A function which is called *before* the request `initialize` is completed. + `initialize_params` contains the parameters we are sending to the server + and `config` is the config that was passed to `start_client()` for + convenience. You can use this to modify parameters before they are sent. + + `on_init(client, initialize_result)` + A function which is called after the request `initialize` is completed. + `initialize_result` contains `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. + + `on_attach(client, bufnr)` + A function which is called after the client is attached to a buffer. + + `on_exit(code, signal, client_id)` + A function which is called after the client has exited. code is the exit + code of the process, and signal is a number describing the signal used to + terminate (if any). + + `trace` + "off" | "messages" | "verbose" | nil passed directly to the language + server in the initialize request. + Invalid/empty values will default to "off" + + Returns:~ + {client_id} + You can use |vim.lsp.get_client_by_id()| to get the actual client object. + See |lsp-client| for what the client structure will be. + + NOTE: The client is only available *after* it has been initialized, which + may happen after a small delay (or never if there is an error). For this + reason, you may want to use `on_init` to do any actions once the client has + been initialized. + + *lsp-client* + +The client object has some methods and members related to using the client. + + Methods:~ + + `request(method, params, [callback])` + Send a request to the server. If callback is not specified, it will use + {client.callbacks} to try to find a callback. If one is not found there, + then an error will occur. + This is a thin wrapper around {client.rpc.request} with some additional + checking. + Returns a boolean to indicate if the notification was successful. If it + is false, then it will always be false (the client has shutdown). + If it was successful, then it will return the request id as the second + result. You can use this with `notify("$/cancel", { id = request_id })` + to cancel the request. This helper is made automatically with + |vim.lsp.buf_request()| + Returns: status, [client_id] + + `notify(method, params)` + This is just {client.rpc.notify}() + Returns a boolean to indicate if the notification was successful. If it + is false, then it will always be false (the client has shutdown). + Returns: status + + `cancel_request(id)` + This is just {client.rpc.notify}("$/cancelRequest", { id = id }) + Returns the same as `notify()`. + + `stop([force])` + Stop a client, optionally with force. + By default, it will just ask the server to shutdown without force. + If you request to stop a client which has previously been requested to + shutdown, it will automatically escalate and force shutdown. + + `is_stopped()` + Returns true if the client is fully stopped. + + Members: ~ + `id` (number) + The id allocated to the client. + + `name` (string) + If a name is specified on creation, that will be used. Otherwise it is + just the client id. This is used for logs and messages. + + `offset_encoding` (string) + The encoding used for communicating with the server. You can modify this + in the `on_init` method before text is sent to the server. + + `callbacks` (table) + The callbacks used by the client as described in |lsp-callbacks|. + + `config` (table) + A copy of the table that was passed by the user to + |vim.lsp.start_client()|. + + `server_capabilities` (table) + The response from the server sent on `initialize` describing the + server's capabilities. + + `resolved_capabilities` (table) + A normalized table of capabilities that we have detected based on the + initialize response from the server in `server_capabilities`. + + + *vim.lsp.buf_attach_client()* +vim.lsp.buf_attach_client({bufnr}, {client_id}) + + Implements the `textDocument/did*` notifications required to track a buffer + for any language server. + + Without calling this, the server won't be notified of changes to a buffer. + + *vim.lsp.get_client_by_id()* +vim.lsp.get_client_by_id({client_id}) + + Look up an active client by its id, returns nil if it is not yet initialized + or is not a valid id. Returns |lsp-client| + + *vim.lsp.stop_client()* +vim.lsp.stop_client({client_id}, [{force}]) + + Stop a client, optionally with force. + By default, it will just ask the server to shutdown without force. + If you request to stop a client which has previously been requested to + shutdown, it will automatically escalate and force shutdown. + + You can also use `client.stop()` if you have access to the client. + + *vim.lsp.stop_all_clients()* +vim.lsp.stop_all_clients([{force}]) + + |vim.lsp.stop_client()|, but for all active clients. + + *vim.lsp.get_active_clients()* +vim.lsp.get_active_clients() + + Return a list of all of the active clients. See |lsp-client| for a + description of what a client looks like. + + *vim.lsp.rpc_response_error()* +vim.lsp.rpc_response_error({code}, [{message}], [{data}]) + + Helper function to create an RPC response object/table. This is an alias for + |vim.lsp.rpc.rpc_response_error|. Code must be an RPC error code as + described in `vim.lsp.protocol.ErrorCodes`. + + You can describe an optional {message} string or arbitrary {data} to send to + the server. + +================================================================================ +LSP CALLBACKS *lsp-callbacks* + +DEFAULT CALLBACKS ~ + *vim.lsp.callbacks* +The `vim.lsp.callbacks` table defines default callbacks used when +creating a new client. Keys are LSP method names: > + + :lua print(vim.inspect(vim.tbl_keys(vim.lsp.callbacks))) + +These LSP requests/notifications are defined by default: + + textDocument/publishDiagnostics + window/logMessage + window/showMessage + +You can check these via `vim.tbl_keys(vim.lsp.callbacks)`. + +These will be used preferrentially in `vim.lsp.buf` methods when handling +requests. They will also be used when responding to server requests and +notifications. + +Use cases: +- Users can modify this to customize to their preferences. +- UI plugins can modify this by assigning to + `vim.lsp.callbacks[method]` so as to provide more specialized + handling, allowing you to leverage the UI capabilities available. UIs should + try to be conscientious of any existing changes the user may have set + already by checking for existing values. + +Any callbacks passed directly to `request` methods on a server client will +have the highest precedence, followed by the `callbacks`. + +You can override the default handlers, +- globally: by modifying the `vim.lsp.callbacks` table +- per-client: by passing the {callbacks} table parameter to + |vim.lsp.start_client| + +Each handler has this signature: > + + function(err, method, params, client_id) + +Callbacks are functions which are called in a variety of situations by the +client. Their signature is `function(err, method, params, client_id)` They can +be set by the {callbacks} parameter for |vim.lsp.start_client| or via the +|vim.lsp.callbacks|. + +Handlers are called for: +- Notifications from the server (`err` is always `nil`). +- Requests initiated by the server (`err` is always `nil`). + The handler can respond by returning two values: `result, err` + where `err` must be shaped like an RPC error: + `{ code, message, data? }` + You can use |vim.lsp.rpc_response_error()| to create this object. +- Handling requests initiated by the client if the request doesn't explicitly + specify a callback (such as in |vim.lsp.buf_request|). + +================================================================================ +VIM.LSP.PROTOCOL *vim.lsp.protocol* + +The `vim.lsp.protocol` module provides constants defined in the LSP +specification, and helper functions for creating protocol-related objects. + + https://github.com/microsoft/language-server-protocol/raw/gh-pages/_specifications/specification-3-14.md + +Useful examples are `vim.lsp.protocol.ErrorCodes`. These objects allow reverse +lookup by either the number or string name. + + e.g. vim.lsp.protocol.TextDocumentSyncKind.Full == 1 + vim.lsp.protocol.TextDocumentSyncKind[1] == "Full" + + Utility functions used internally are: + `vim.lsp.protocol.make_client_capabilities()` + Make a ClientCapabilities object. These are the builtin + capabilities. + `vim.lsp.protocol.resolve_capabilities(server_capabilites)` + Creates a normalized object describing capabilities from the server + capabilities. + +================================================================================ + *vim.lsp.util* + +TODO: Describe the utils here for handling/applying things from LSP. + +================================================================================ + *lsp-buf-methods* +There are methods which operate on the buffer level for all of the active +clients attached to the buffer. + + *vim.lsp.buf_request()* +vim.lsp.buf_request({bufnr}, {method}, {params}, [{callback}]) + Send a async request for all the clients active and attached to the buffer. + + Parameters: ~ + {bufnr}: The buffer handle or 0 for the current buffer. + + {method}: The LSP method name. + + {params}: The parameters to send. + + {callback}: An optional `function(err, method, params, client_id)` which + will be called for this request. If you do not specify it, then it will + use the client's callback in {client.callbacks}. See |lsp-callbacks| for + more information. + + Returns:~ + + A table from client id to the request id for all of the successful + requests. + + The second result is a function which can be used to cancel all the + requests. You can do this individually with `client.cancel_request()` + + *vim.lsp.buf_request_sync()* +vim.lsp.buf_request_sync({bufnr}, {method}, {params}, [{timeout_ms}]) + Calls |vim.lsp.buf_request()|, but it will wait for the result and block Vim + in the process. + The parameters are the same as |vim.lsp.buf_request()|, but the return + result is different. + It will wait maximum of {timeout_ms} which defaults to 100ms. + + Returns:~ + + If the timeout is exceeded or a cancel is sent or an error, it will cancel + the request and return `nil, err` where `err` is a string that describes + the reason why it failed. + + If it is successful, it will return a table from client id to result id. + + *vim.lsp.buf_notify()* +vim.lsp.buf_notify({bufnr}, {method}, {params}) + Send a notification to all servers on the buffer. + + Parameters: ~ + {bufnr}: The buffer handle or 0 for the current buffer. + + {method}: The LSP method name. + + {params}: The parameters to send. + +================================================================================ + *lsp-logging* + + *vim.lsp.set_log_level()* +vim.lsp.set_log_level({level}) + You can set the log level for language server client logging. + Possible values: "trace", "debug", "info", "warn", "error" + + Default: "warn" + + Example: `lua vim.lsp.set_log_level("debug")` + + *vim.lsp.get_log_path()* +vim.lsp.get_log_path() + Returns the path that LSP logs are written. + + *vim.lsp.log_levels* +vim.lsp.log_levels + Log level dictionary with reverse lookup as well. + + Can be used to lookup the number from the name or vice-versa. + Levels: "trace" (0), "debug" (1), "info" (2), "warn" (3), "error" (4) + +================================================================================ +LSP EXAMPLE *lsp-advanced-js-example* + +For more advanced configurations where just filtering by filetype isn't +sufficient, you can use the `vim.lsp.start_client()` and +`vim.lsp.buf_attach_client()` commands to easily customize the configuration +however you please. For example, if you want to do your own filtering, or +start a new LSP client based on the root directory for if you plan to work +with multiple projects in a single session. Below is a fully working Lua +example which can do exactly that. + +The example will: +1. Check for each new buffer whether or not we want to start an LSP client. +2. Try to find a root directory by ascending from the buffer's path. +3. Create a new LSP for that root directory if one doesn't exist. +4. Attach the buffer to the client for that root directory. + +> + -- Some path manipulation utilities + local function is_dir(filename) + local stat = vim.loop.fs_stat(filename) + return stat and stat.type == 'directory' or false + end + + local path_sep = vim.loop.os_uname().sysname == "Windows" and "\\" or "/" + -- Asumes filepath is a file. + local function dirname(filepath) + local is_changed = false + local result = filepath:gsub(path_sep.."([^"..path_sep.."]+)$", function() + is_changed = true + return "" + end) + return result, is_changed + end + + local function path_join(...) + return table.concat(vim.tbl_flatten {...}, path_sep) + end + + -- Ascend the buffer's path until we find the rootdir. + -- is_root_path is a function which returns bool + local function buffer_find_root_dir(bufnr, is_root_path) + local bufname = vim.api.nvim_buf_get_name(bufnr) + if vim.fn.filereadable(bufname) == 0 then + return nil + end + local dir = bufname + -- Just in case our algo is buggy, don't infinite loop. + for _ = 1, 100 do + local did_change + dir, did_change = dirname(dir) + if is_root_path(dir, bufname) then + return dir, bufname + end + -- If we can't ascend further, then stop looking. + if not did_change then + return nil + end + end + end + + -- A table to store our root_dir to client_id lookup. We want one LSP per + -- root directory, and this is how we assert that. + local javascript_lsps = {} + -- Which filetypes we want to consider. + local javascript_filetypes = { + ["javascript.jsx"] = true; + ["javascript"] = true; + ["typescript"] = true; + ["typescript.jsx"] = true; + } + + -- Create a template configuration for a server to start, minus the root_dir + -- which we will specify later. + local javascript_lsp_config = { + name = "javascript"; + cmd = { path_join(os.getenv("JAVASCRIPT_LANGUAGE_SERVER_DIRECTORY"), "lib", "language-server-stdio.js") }; + } + + -- This needs to be global so that we can call it from the autocmd. + function check_start_javascript_lsp() + local bufnr = vim.api.nvim_get_current_buf() + -- Filter which files we are considering. + if not javascript_filetypes[vim.api.nvim_buf_get_option(bufnr, 'filetype')] then + return + end + -- Try to find our root directory. We will define this as a directory which contains + -- node_modules. Another choice would be to check for `package.json`, or for `.git`. + local root_dir = buffer_find_root_dir(bufnr, function(dir) + return is_dir(path_join(dir, 'node_modules')) + -- return vim.fn.filereadable(path_join(dir, 'package.json')) == 1 + -- return is_dir(path_join(dir, '.git')) + end) + -- We couldn't find a root directory, so ignore this file. + if not root_dir then return end + + -- Check if we have a client alredy or start and store it. + local client_id = javascript_lsps[root_dir] + if not client_id then + local new_config = vim.tbl_extend("error", javascript_lsp_config, { + root_dir = root_dir; + }) + client_id = vim.lsp.start_client(new_config) + javascript_lsps[root_dir] = client_id + end + -- Finally, attach to the buffer to track changes. This will do nothing if we + -- are already attached. + vim.lsp.buf_attach_client(bufnr, client_id) + end + + vim.api.nvim_command [[autocmd BufReadPost * lua check_start_javascript_lsp()]] +< + +vim:tw=78:ts=8:ft=help:norl: diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt new file mode 100644 index 0000000000..c0da06ffe3 --- /dev/null +++ b/runtime/doc/lua.txt @@ -0,0 +1,1001 @@ +*lua.txt* Nvim + + + NVIM REFERENCE MANUAL + + +Lua engine *lua* *Lua* + + Type |gO| to see the table of contents. + +============================================================================== +Introduction *lua-intro* + +The Lua 5.1 language is builtin and always available. Try this command to get +an idea of what lurks beneath: > + + :lua print(vim.inspect(package.loaded)) + +Nvim includes a "standard library" |lua-stdlib| for Lua. It complements the +"editor stdlib" (|functions| and Ex commands) and the |API|, all of which can +be used from Lua code. + +Module conflicts are resolved by "last wins". For example if both of these +are on 'runtimepath': + runtime/lua/foo.lua + ~/.config/nvim/lua/foo.lua +then `require('foo')` loads "~/.config/nvim/lua/foo.lua", and +"runtime/lua/foo.lua" is not used. See |lua-require| to understand how Nvim +finds and loads Lua modules. The conventions are similar to VimL plugins, +with some extra features. See |lua-require-example| for a walkthrough. + +============================================================================== +Importing Lua modules *lua-require* + + *lua-package-path* +Nvim automatically adjusts `package.path` and `package.cpath` according to +effective 'runtimepath' value. Adjustment happens whenever 'runtimepath' is +changed. `package.path` is adjusted by simply appending `/lua/?.lua` and +`/lua/?/init.lua` to each directory from 'runtimepath' (`/` is actually the +first character of `package.config`). + +Similarly to `package.path`, modified directories from 'runtimepath' are also +added to `package.cpath`. In this case, instead of appending `/lua/?.lua` and +`/lua/?/init.lua` to each runtimepath, all unique `?`-containing suffixes of +the existing `package.cpath` are used. Example: + +1. Given that + - 'runtimepath' contains `/foo/bar,/xxx;yyy/baz,/abc`; + - initial (defined at compile-time or derived from + `$LUA_CPATH`/`$LUA_INIT`) `package.cpath` contains + `./?.so;/def/ghi/a?d/j/g.elf;/def/?.so`. +2. It finds `?`-containing suffixes `/?.so`, `/a?d/j/g.elf` and `/?.so`, in + order: parts of the path starting from the first path component containing + question mark and preceding path separator. +3. The suffix of `/def/?.so`, namely `/?.so` is not unique, as it’s the same + as the suffix of the first path from `package.path` (i.e. `./?.so`). Which + leaves `/?.so` and `/a?d/j/g.elf`, in this order. +4. 'runtimepath' has three paths: `/foo/bar`, `/xxx;yyy/baz` and `/abc`. The + second one contains semicolon which is a paths separator so it is out, + leaving only `/foo/bar` and `/abc`, in order. +5. The cartesian product of paths from 4. and suffixes from 3. is taken, + giving four variants. In each variant `/lua` path segment is inserted + between path and suffix, leaving + + - `/foo/bar/lua/?.so` + - `/foo/bar/lua/a?d/j/g.elf` + - `/abc/lua/?.so` + - `/abc/lua/a?d/j/g.elf` + +6. New paths are prepended to the original `package.cpath`. + +The result will look like this: + + `/foo/bar,/xxx;yyy/baz,/abc` ('runtimepath') + × `./?.so;/def/ghi/a?d/j/g.elf;/def/?.so` (`package.cpath`) + + = `/foo/bar/lua/?.so;/foo/bar/lua/a?d/j/g.elf;/abc/lua/?.so;/abc/lua/a?d/j/g.elf;./?.so;/def/ghi/a?d/j/g.elf;/def/?.so` + +Note: + +- To track 'runtimepath' updates, paths added at previous update are + remembered and removed at the next update, while all paths derived from the + new 'runtimepath' are prepended as described above. This allows removing + paths when path is removed from 'runtimepath', adding paths when they are + added and reordering `package.path`/`package.cpath` content if 'runtimepath' + was reordered. + +- Although adjustments happen automatically, Nvim does not track current + values of `package.path` or `package.cpath`. If you happen to delete some + paths from there you can set 'runtimepath' to trigger an update: > + let &runtimepath = &runtimepath + +- Skipping paths from 'runtimepath' which contain semicolons applies both to + `package.path` and `package.cpath`. Given that there are some badly written + plugins using shell which will not work with paths containing semicolons it + is better to not have them in 'runtimepath' at all. + +------------------------------------------------------------------------------ +LUA PLUGIN EXAMPLE *lua-require-example* + +The following example plugin adds a command `:MakeCharBlob` which transforms +current buffer into a long `unsigned char` array. Lua contains transformation +function in a module `lua/charblob.lua` which is imported in +`autoload/charblob.vim` (`require("charblob")`). Example plugin is supposed +to be put into any directory from 'runtimepath', e.g. `~/.config/nvim` (in +this case `lua/charblob.lua` means `~/.config/nvim/lua/charblob.lua`). + +autoload/charblob.vim: > + + function charblob#encode_buffer() + call setline(1, luaeval( + \ 'require("charblob").encode(unpack(_A))', + \ [getline(1, '$'), &textwidth, ' '])) + endfunction + +plugin/charblob.vim: > + + if exists('g:charblob_loaded') + finish + endif + let g:charblob_loaded = 1 + + command MakeCharBlob :call charblob#encode_buffer() + +lua/charblob.lua: > + + local function charblob_bytes_iter(lines) + local init_s = { + next_line_idx = 1, + next_byte_idx = 1, + lines = lines, + } + local function next(s, _) + if lines[s.next_line_idx] == nil then + return nil + end + if s.next_byte_idx > #(lines[s.next_line_idx]) then + s.next_line_idx = s.next_line_idx + 1 + s.next_byte_idx = 1 + return ('\n'):byte() + end + local ret = lines[s.next_line_idx]:byte(s.next_byte_idx) + if ret == ('\n'):byte() then + ret = 0 -- See :h NL-used-for-NUL. + end + s.next_byte_idx = s.next_byte_idx + 1 + return ret + end + return next, init_s, nil + end + + local function charblob_encode(lines, textwidth, indent) + local ret = { + 'const unsigned char blob[] = {', + indent, + } + for byte in charblob_bytes_iter(lines) do + -- .- space + number (width 3) + comma + if #(ret[#ret]) + 5 > textwidth then + ret[#ret + 1] = indent + else + ret[#ret] = ret[#ret] .. ' ' + end + ret[#ret] = ret[#ret] .. (('%3u,'):format(byte)) + end + ret[#ret + 1] = '};' + return ret + end + + return { + bytes_iter = charblob_bytes_iter, + encode = charblob_encode, + } + +============================================================================== +Commands *lua-commands* + +These commands execute a Lua chunk from either the command line (:lua, :luado) +or a file (:luafile) on the given line [range]. As always in Lua, each chunk +has its own scope (closure), so only global variables are shared between +command calls. The |lua-stdlib| modules, user modules, and anything else on +|lua-package-path| are available. + +The Lua print() function redirects its output to the Nvim message area, with +arguments separated by " " (space) instead of "\t" (tab). + + *:lua* +:[range]lua {chunk} + Executes Lua chunk {chunk}. + + Examples: > + :lua vim.api.nvim_command('echo "Hello, Nvim!"') +< To see the Lua version: > + :lua print(_VERSION) +< To see the LuaJIT version: > + :lua print(jit.version) +< + *:lua-heredoc* +:[range]lua << [endmarker] +{script} +{endmarker} + Executes Lua script {script} from within Vimscript. + {endmarker} must NOT be preceded by whitespace. You + can omit [endmarker] after the "<<" and use a dot "." + after {script} (similar to |:append|, |:insert|). + + Example: + > + function! CurrentLineInfo() + lua << EOF + local linenr = vim.api.nvim_win_get_cursor(0)[1] + local curline = vim.api.nvim_buf_get_lines( + 0, linenr, linenr + 1, false)[1] + print(string.format("Current line [%d] has %d bytes", + linenr, #curline)) + EOF + endfunction + +< Note that the `local` variables will disappear when + the block finishes. But not globals. + + *:luado* +:[range]luado {body} Executes Lua chunk "function(line, linenr) {body} end" + for each buffer line in [range], where `line` is the + current line text (without <EOL>), and `linenr` is the + current line number. If the function returns a string + that becomes the text of the corresponding buffer + line. Default [range] is the whole file: "1,$". + + Examples: + > + :luado return string.format("%s\t%d", line:reverse(), #line) + + :lua require"lpeg" + :lua -- balanced parenthesis grammar: + :lua bp = lpeg.P{ "(" * ((1 - lpeg.S"()") + lpeg.V(1))^0 * ")" } + :luado if bp:match(line) then return "-->\t" .. line end +< + + *:luafile* +:[range]luafile {file} + Execute Lua script in {file}. + The whole argument is used as a single file name. + + Examples: + > + :luafile script.lua + :luafile % +< + +============================================================================== +luaeval() *lua-eval* *luaeval()* + +The (dual) equivalent of "vim.eval" for passing Lua values to Nvim is +"luaeval". "luaeval" takes an expression string and an optional argument used +for _A inside expression and returns the result of the expression. It is +semantically equivalent in Lua to: +> + local chunkheader = "local _A = select(1, ...) return " + function luaeval (expstr, arg) + local chunk = assert(loadstring(chunkheader .. expstr, "luaeval")) + return chunk(arg) -- return typval + end + +Lua nils, numbers, strings, tables and booleans are converted to their +respective VimL types. An error is thrown if conversion of any other Lua types +is attempted. + +The magic global "_A" contains the second argument to luaeval(). + +Example: > + :echo luaeval('_A[1] + _A[2]', [40, 2]) + 42 + :echo luaeval('string.match(_A, "[a-z]+")', 'XYXfoo123') + foo + +Lua tables are used as both dictionaries and lists, so it is impossible to +determine whether empty table is meant to be empty list or empty dictionary. +Additionally Lua does not have integer numbers. To distinguish between these +cases there is the following agreement: + +0. Empty table is empty list. +1. Table with N incrementally growing integral numbers, starting from 1 and + ending with N is considered to be a list. +2. Table with string keys, none of which contains NUL byte, is considered to + be a dictionary. +3. Table with string keys, at least one of which contains NUL byte, is also + considered to be a dictionary, but this time it is converted to + a |msgpack-special-map|. + *lua-special-tbl* +4. Table with `vim.type_idx` key may be a dictionary, a list or floating-point + value: + - `{[vim.type_idx]=vim.types.float, [vim.val_idx]=1}` is converted to + a floating-point 1.0. Note that by default integral Lua numbers are + converted to |Number|s, non-integral are converted to |Float|s. This + variant allows integral |Float|s. + - `{[vim.type_idx]=vim.types.dictionary}` is converted to an empty + dictionary, `{[vim.type_idx]=vim.types.dictionary, [42]=1, a=2}` is + converted to a dictionary `{'a': 42}`: non-string keys are ignored. + Without `vim.type_idx` key tables with keys not fitting in 1., 2. or 3. + are errors. + - `{[vim.type_idx]=vim.types.list}` is converted to an empty list. As well + as `{[vim.type_idx]=vim.types.list, [42]=1}`: integral keys that do not + form a 1-step sequence from 1 to N are ignored, as well as all + non-integral keys. + +Examples: > + + :echo luaeval('math.pi') + :function Rand(x,y) " random uniform between x and y + : return luaeval('(_A.y-_A.x)*math.random()+_A.x', {'x':a:x,'y':a:y}) + : endfunction + :echo Rand(1,10) + +Note: second argument to `luaeval` undergoes VimL to Lua conversion +("marshalled"), so changes to Lua containers do not affect values in VimL. +Return value is also always converted. When converting, +|msgpack-special-dict|s are treated specially. + +============================================================================== +Vimscript v:lua interface *v:lua-call* + +From Vimscript the special `v:lua` prefix can be used to call Lua functions +which are global or accessible from global tables. The expression > + v:lua.func(arg1, arg2) +is equivalent to the Lua chunk > + return func(...) +where the args are converted to Lua values. The expression > + v:lua.somemod.func(args) +is equivalent to the Lua chunk > + return somemod.func(...) + +You can use `v:lua` in "func" options like 'tagfunc', 'omnifunc', etc. +For example consider the following Lua omnifunc handler: > + + function mymod.omnifunc(findstart, base) + if findstart == 1 then + return 0 + else + return {'stuff', 'steam', 'strange things'} + end + end + vim.api.nvim_buf_set_option(0, 'omnifunc', 'v:lua.mymod.omnifunc') + +Note: the module ("mymod" in the above example) must be a Lua global. + +Note: `v:lua` without a call is not allowed in a Vimscript expression: +|Funcref|s cannot represent Lua functions. The following are errors: > + + let g:Myvar = v:lua.myfunc " Error + call SomeFunc(v:lua.mycallback) " Error + let g:foo = v:lua " Error + let g:foo = v:['lua'] " Error + + +============================================================================== +Lua standard modules *lua-stdlib* + +The Nvim Lua "standard library" (stdlib) is the `vim` module, which exposes +various functions and sub-modules. It is always loaded, thus require("vim") +is unnecessary. + +You can peek at the module properties: > + + :lua print(vim.inspect(vim)) + +Result is something like this: > + + { + _os_proc_children = <function 1>, + _os_proc_info = <function 2>, + ... + api = { + nvim__id = <function 5>, + nvim__id_array = <function 6>, + ... + }, + deepcopy = <function 106>, + gsplit = <function 107>, + ... + } + +To find documentation on e.g. the "deepcopy" function: > + + :help vim.deepcopy() + +Note that underscore-prefixed functions (e.g. "_os_proc_children") are +internal/private and must not be used by plugins. + +------------------------------------------------------------------------------ +VIM.LOOP *lua-loop* *vim.loop* + +`vim.loop` exposes all features of the Nvim event-loop. This is a low-level +API that provides functionality for networking, filesystem, and process +management. Try this command to see available functions: > + + :lua print(vim.inspect(vim.loop)) + +Reference: http://docs.libuv.org +Examples: https://github.com/luvit/luv/tree/master/examples + + *E5560* *lua-loop-callbacks* +It is an error to directly invoke `vim.api` functions (except |api-fast|) in +`vim.loop` callbacks. For example, this is an error: > + + local timer = vim.loop.new_timer() + timer:start(1000, 0, function() + vim.api.nvim_command('echomsg "test"') + end) + +To avoid the error use |vim.schedule_wrap()| to defer the callback: > + + local timer = vim.loop.new_timer() + timer:start(1000, 0, vim.schedule_wrap(function() + vim.api.nvim_command('echomsg "test"') + end)) + +Example: repeating timer + 1. Save this code to a file. + 2. Execute it with ":luafile %". > + + -- Create a timer handle (implementation detail: uv_timer_t). + local timer = vim.loop.new_timer() + local i = 0 + -- Waits 1000ms, then repeats every 750ms until timer:close(). + timer:start(1000, 750, function() + print('timer invoked! i='..tostring(i)) + if i > 4 then + timer:close() -- Always close handles to avoid leaks. + end + i = i + 1 + end) + print('sleeping'); + + +Example: File-change detection *watch-file* + 1. Save this code to a file. + 2. Execute it with ":luafile %". + 3. Use ":Watch %" to watch any file. + 4. Try editing the file from another text editor. + 5. Observe that the file reloads in Nvim (because on_change() calls + |:checktime|). > + + local w = vim.loop.new_fs_event() + local function on_change(err, fname, status) + -- Do work... + vim.api.nvim_command('checktime') + -- Debounce: stop/start. + w:stop() + watch_file(fname) + end + function watch_file(fname) + local fullpath = vim.api.nvim_call_function( + 'fnamemodify', {fname, ':p'}) + w:start(fullpath, {}, vim.schedule_wrap(function(...) + on_change(...) end)) + end + vim.api.nvim_command( + "command! -nargs=1 Watch call luaeval('watch_file(_A)', expand('<args>'))") + + +Example: TCP echo-server *tcp-server* + 1. Save this code to a file. + 2. Execute it with ":luafile %". + 3. Note the port number. + 4. Connect from any TCP client (e.g. "nc 0.0.0.0 36795"): > + + local function create_server(host, port, on_connect) + local server = vim.loop.new_tcp() + server:bind(host, port) + server:listen(128, function(err) + assert(not err, err) -- Check for errors. + local sock = vim.loop.new_tcp() + server:accept(sock) -- Accept client connection. + on_connect(sock) -- Start reading messages. + end) + return server + end + local server = create_server('0.0.0.0', 0, function(sock) + sock:read_start(function(err, chunk) + assert(not err, err) -- Check for errors. + if chunk then + sock:write(chunk) -- Echo received messages to the channel. + else -- EOF (stream closed). + sock:close() -- Always close handles to avoid leaks. + end + end) + end) + print('TCP echo-server listening on port: '..server:getsockname().port) + +------------------------------------------------------------------------------ +VIM.TREESITTER *lua-treesitter* + +Nvim integrates the tree-sitter library for incremental parsing of buffers. + +Currently Nvim does not provide the tree-sitter parsers, instead these must +be built separately, for instance using the tree-sitter utility. +The parser is loaded into nvim using > + + vim.treesitter.add_language("/path/to/c_parser.so", "c") + +<Create a parser for a buffer and a given language (if another plugin uses the +same buffer/language combination, it will be safely reused). Use > + + parser = vim.treesitter.get_parser(bufnr, lang) + +<`bufnr=0` can be used for current buffer. `lang` will default to 'filetype' (this +doesn't work yet for some filetypes like "cpp") Currently, the parser will be +retained for the lifetime of a buffer but this is subject to change. A plugin +should keep a reference to the parser object as long as it wants incremental +updates. + +Whenever you need to access the current syntax tree, parse the buffer: > + + tstree = parser:parse() + +<This will return an immutable tree that represents the current state of the +buffer. When the plugin wants to access the state after a (possible) edit +it should call `parse()` again. If the buffer wasn't edited, the same tree will +be returned again without extra work. If the buffer was parsed before, +incremental parsing will be done of the changed parts. + +NB: to use the parser directly inside a |nvim_buf_attach| Lua callback, you must +call `get_parser()` before you register your callback. But preferably parsing +shouldn't be done directly in the change callback anyway as they will be very +frequent. Rather a plugin that does any kind of analysis on a tree should use +a timer to throttle too frequent updates. + +Tree methods *lua-treesitter-tree* + +tstree:root() *tstree:root()* + Return the root node of this tree. + + +Node methods *lua-treesitter-node* + +tsnode:parent() *tsnode:parent()* + Get the node's immediate parent. + +tsnode:child_count() *tsnode:child_count()* + Get the node's number of children. + +tsnode:child(N) *tsnode:child()* + Get the node's child at the given index, where zero represents the + first child. + +tsnode:named_child_count() *tsnode:named_child_count()* + Get the node's number of named children. + +tsnode:named_child(N) *tsnode:named_child()* + Get the node's named child at the given index, where zero represents + the first named child. + +tsnode:start() *tsnode:start()* + Get the node's start position. Return three values: the row, column + and total byte count (all zero-based). + +tsnode:end_() *tsnode:end_()* + Get the node's end position. Return three values: the row, column + and total byte count (all zero-based). + +tsnode:range() *tsnode:range()* + Get the range of the node. Return four values: the row, column + of the start position, then the row, column of the end position. + +tsnode:type() *tsnode:type()* + Get the node's type as a string. + +tsnode:symbol() *tsnode:symbol()* + Get the node's type as a numerical id. + +tsnode:named() *tsnode:named()* + Check if the node is named. Named nodes correspond to named rules in + the grammar, whereas anonymous nodes correspond to string literals + in the grammar. + +tsnode:missing() *tsnode:missing()* + Check if the node is missing. Missing nodes are inserted by the + parser in order to recover from certain kinds of syntax errors. + +tsnode:has_error() *tsnode:has_error()* + Check if the node is a syntax error or contains any syntax errors. + +tsnode:sexpr() *tsnode:sexpr()* + Get an S-expression representing the node as a string. + +tsnode:descendant_for_range(start_row, start_col, end_row, end_col) + *tsnode:descendant_for_range()* + Get the smallest node within this node that spans the given range of + (row, column) positions + +tsnode:named_descendant_for_range(start_row, start_col, end_row, end_col) + *tsnode:named_descendant_for_range()* + Get the smallest named node within this node that spans the given + range of (row, column) positions + +------------------------------------------------------------------------------ +VIM *lua-builtin* + +vim.api.{func}({...}) *vim.api* + Invokes Nvim |API| function {func} with arguments {...}. + Example: call the "nvim_get_current_line()" API function: > + print(tostring(vim.api.nvim_get_current_line())) + +vim.call({func}, {...}) *vim.call()* + Invokes |vim-function| or |user-function| {func} with arguments {...}. + See also |vim.fn|. Equivalent to: > + vim.fn[func]({...}) + +vim.in_fast_event() *vim.in_fast_event()* + Returns true if the code is executing as part of a "fast" event + handler, where most of the API is disabled. These are low-level events + (e.g. |lua-loop-callbacks|) which can be invoked whenever Nvim polls + for input. When this is `false` most API functions are callable (but + may be subject to other restrictions such as |textlock|). + +vim.NIL *vim.NIL* + Special value used to represent NIL in msgpack-rpc and |v:null| in + vimL interaction, and similar cases. Lua `nil` cannot be used as + part of a lua table representing a Dictionary or Array, as it + is equivalent to a missing value: `{"foo", nil}` is the same as + `{"foo"}` + +vim.rpcnotify({channel}, {method}[, {args}...]) *vim.rpcnotify()* + Sends {event} to {channel} via |RPC| and returns immediately. + If {channel} is 0, the event is broadcast to all channels. + + This function also works in a fast callback |lua-loop-callbacks|. + +vim.rpcrequest({channel}, {method}[, {args}...]) *vim.rpcrequest()* + Sends a request to {channel} to invoke {method} via + |RPC| and blocks until a response is received. + + Note: NIL values as part of the return value is represented as + |vim.NIL| special value + +vim.stricmp({a}, {b}) *vim.stricmp()* + Compares strings case-insensitively. Returns 0, 1 or -1 if strings + are equal, {a} is greater than {b} or {a} is lesser than {b}, + respectively. + +vim.str_utfindex({str}[, {index}]) *vim.str_utfindex()* + Convert byte index to UTF-32 and UTF-16 indicies. If {index} is not + supplied, the length of the string is used. All indicies are zero-based. + Returns two values: the UTF-32 and UTF-16 indicies respectively. + + Embedded NUL bytes are treated as terminating the string. Invalid + UTF-8 bytes, and embedded surrogates are counted as one code + point each. An {index} in the middle of a UTF-8 sequence is rounded + upwards to the end of that sequence. + +vim.str_byteindex({str}, {index}[, {use_utf16}]) *vim.str_byteindex()* + Convert UTF-32 or UTF-16 {index} to byte index. If {use_utf16} is not + supplied, it defaults to false (use UTF-32). Returns the byte index. + + Invalid UTF-8 and NUL is treated like by |vim.str_byteindex()|. An {index} + in the middle of a UTF-16 sequence is rounded upwards to the end of that + sequence. + +vim.schedule({callback}) *vim.schedule()* + Schedules {callback} to be invoked soon by the main event-loop. Useful + to avoid |textlock| or other temporary restrictions. + +vim.fn.{func}({...}) *vim.fn* + Invokes |vim-function| or |user-function| {func} with arguments {...}. + To call autoload functions, use the syntax: > + vim.fn['some#function']({...}) +< + Unlike vim.api.|nvim_call_function| this converts directly between Vim + objects and Lua objects. If the Vim function returns a float, it will + be represented directly as a Lua number. Empty lists and dictionaries + both are represented by an empty table. + + Note: |v:null| values as part of the return value is represented as + |vim.NIL| special value + + Note: vim.fn keys are generated lazily, thus `pairs(vim.fn)` only + enumerates functions that were called at least once. + +vim.type_idx *vim.type_idx* + Type index for use in |lua-special-tbl|. Specifying one of the + values from |vim.types| allows typing the empty table (it is + unclear whether empty Lua table represents empty list or empty array) + and forcing integral numbers to be |Float|. See |lua-special-tbl| for + more details. + +vim.val_idx *vim.val_idx* + Value index for tables representing |Float|s. A table representing + floating-point value 1.0 looks like this: > + { + [vim.type_idx] = vim.types.float, + [vim.val_idx] = 1.0, + } +< See also |vim.type_idx| and |lua-special-tbl|. + +vim.types *vim.types* + Table with possible values for |vim.type_idx|. Contains two sets + of key-value pairs: first maps possible values for |vim.type_idx| + to human-readable strings, second maps human-readable type names to + values for |vim.type_idx|. Currently contains pairs for `float`, + `array` and `dictionary` types. + + Note: one must expect that values corresponding to `vim.types.float`, + `vim.types.array` and `vim.types.dictionary` fall under only two + following assumptions: + 1. Value may serve both as a key and as a value in a table. Given the + properties of Lua tables this basically means “value is not `nil`”. + 2. For each value in `vim.types` table `vim.types[vim.types[value]]` + is the same as `value`. + No other restrictions are put on types, and it is not guaranteed that + values corresponding to `vim.types.float`, `vim.types.array` and + `vim.types.dictionary` will not change or that `vim.types` table will + only contain values for these three types. + +============================================================================== +Lua module: vim *lua-vim* + +inspect({object}, {options}) *vim.inspect()* + Return a human-readable representation of the given object. + + See also: ~ + https://github.com/kikito/inspect.lua + https://github.com/mpeterv/vinspect + +paste({lines}, {phase}) *vim.paste()* + Paste handler, invoked by |nvim_paste()| when a conforming UI + (such as the |TUI|) pastes text into the editor. + + Example: To remove ANSI color codes when pasting: > + + vim.paste = (function(overridden) + return function(lines, phase) + for i,line in ipairs(lines) do + -- Scrub ANSI color codes from paste input. + lines[i] = line:gsub('\27%[[0-9;mK]+', '') + end + overridden(lines, phase) + end + end)(vim.paste) +< + + Parameters: ~ + {lines} |readfile()|-style list of lines to paste. + |channel-lines| + {phase} -1: "non-streaming" paste: the call contains all + lines. If paste is "streamed", `phase` indicates the stream state: + • 1: starts the paste (exactly once) + • 2: continues the paste (zero or more times) + • 3: ends the paste (exactly once) + + Return: ~ + false if client should cancel the paste. + + See also: ~ + |paste| + +schedule_wrap({cb}) *vim.schedule_wrap()* + Defers callback `cb` until the Nvim API is safe to call. + + See also: ~ + |lua-loop-callbacks| + |vim.schedule()| + |vim.in_fast_event()| + + + + +deepcopy({orig}) *vim.deepcopy()* + Returns a deep copy of the given object. Non-table objects are + copied as in a typical Lua assignment, whereas table objects + are copied recursively. + + Parameters: ~ + {orig} Table to copy + + Return: ~ + New table of copied keys and (nested) values. + +gsplit({s}, {sep}, {plain}) *vim.gsplit()* + Splits a string at each instance of a separator. + + Parameters: ~ + {s} String to split + {sep} Separator string or pattern + {plain} If `true` use `sep` literally (passed to + String.find) + + Return: ~ + Iterator over the split components + + See also: ~ + |vim.split()| + https://www.lua.org/pil/20.2.html + http://lua-users.org/wiki/StringLibraryTutorial + +split({s}, {sep}, {plain}) *vim.split()* + Splits a string at each instance of a separator. + + Examples: > + split(":aa::b:", ":") --> {'','aa','','bb',''} + split("axaby", "ab?") --> {'','x','y'} + split(x*yz*o, "*", true) --> {'x','yz','o'} +< + + Parameters: ~ + {s} String to split + {sep} Separator string or pattern + {plain} If `true` use `sep` literally (passed to + String.find) + + Return: ~ + List-like table of the split components. + + See also: ~ + |vim.gsplit()| + +tbl_keys({t}) *vim.tbl_keys()* + Return a list of all keys used in a table. However, the order + of the return table of keys is not guaranteed. + + Parameters: ~ + {t} Table + + Return: ~ + list of keys + + See also: ~ + Fromhttps://github.com/premake/premake-core/blob/master/src/base/table.lua + +tbl_values({t}) *vim.tbl_values()* + Return a list of all values used in a table. However, the + order of the return table of values is not guaranteed. + + Parameters: ~ + {t} Table + + Return: ~ + list of values + +tbl_contains({t}, {value}) *vim.tbl_contains()* + Checks if a list-like (vector) table contains `value` . + + Parameters: ~ + {t} Table to check + {value} Value to compare + + Return: ~ + true if `t` contains `value` + +tbl_isempty({t}) *vim.tbl_isempty()* + See also: ~ + Fromhttps://github.com/premake/premake-core/blob/master/src/base/table.lua@paramt Table to check + +tbl_extend({behavior}, {...}) *vim.tbl_extend()* + Merges two or more map-like tables. + + Parameters: ~ + {behavior} Decides what to do if a key is found in more + than one map: + • "error": raise an error + • "keep": use value from the leftmost map + • "force": use value from the rightmost map + {...} Two or more map-like tables. + + See also: ~ + |extend()| + +deep_equal({a}, {b}) *vim.deep_equal()* + TODO: Documentation + +tbl_add_reverse_lookup({o}) *vim.tbl_add_reverse_lookup()* + Add the reverse lookup values to an existing table. For + example: `tbl_add_reverse_lookup { A = 1 } == { [1] = 'A', A = + 1 }` + + Parameters: ~ + {o} table The table to add the reverse to. + +list_extend({dst}, {src}, {start}, {finish}) *vim.list_extend()* + Extends a list-like table with the values of another list-like + table. + + NOTE: This mutates dst! + + Parameters: ~ + {dst} list which will be modified and appended to. + {src} list from which values will be inserted. + {start} Start index on src. defaults to 1 + {finish} Final index on src. defaults to #src + + Return: ~ + dst + + See also: ~ + |vim.tbl_extend()| + +tbl_flatten({t}) *vim.tbl_flatten()* + Creates a copy of a list-like table such that any nested + tables are "unrolled" and appended to the result. + + Parameters: ~ + {t} List-like table + + Return: ~ + Flattened copy of the given list-like table. + + See also: ~ + Fromhttps://github.com/premake/premake-core/blob/master/src/base/table.lua + +tbl_islist({t}) *vim.tbl_islist()* + Table + + Return: ~ + true: A non-empty array, false: A non-empty table, nil: An + empty table + +trim({s}) *vim.trim()* + Trim whitespace (Lua pattern "%s") from both sides of a + string. + + Parameters: ~ + {s} String to trim + + Return: ~ + String with whitespace removed from its beginning and end + + See also: ~ + https://www.lua.org/pil/20.2.html + +pesc({s}) *vim.pesc()* + Escapes magic chars in a Lua pattern string. + + Parameters: ~ + {s} String to escape + + Return: ~ + %-escaped pattern string + + See also: ~ + https://github.com/rxi/lume + +validate({opt}) *vim.validate()* + Validates a parameter specification (types and values). + + Usage example: > + + function user.new(name, age, hobbies) + vim.validate{ + name={name, 'string'}, + age={age, 'number'}, + hobbies={hobbies, 'table'}, + } + ... + end +< + + Examples with explicit argument values (can be run directly): > + + vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}} + => NOP (success) +< +> + vim.validate{arg1={1, 'table'}} + => error('arg1: expected table, got number') +< +> + vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}} + => error('arg1: expected even number, got 3') +< + + Parameters: ~ + {opt} Map of parameter names to validations. Each key is + a parameter name; each value is a tuple in one of + these forms: + 1. (arg_value, type_name, optional) + • arg_value: argument value + • type_name: string type name, one of: ("table", + "t", "string", "s", "number", "n", "boolean", + "b", "function", "f", "nil", "thread", + "userdata") + • optional: (optional) boolean, if true, `nil` + is valid + + 2. (arg_value, fn, msg) + • arg_value: argument value + • fn: any function accepting one argument, + returns true if and only if the argument is + valid + • msg: (optional) error string if validation + fails + +is_callable({f}) *vim.is_callable()* + Returns true if object `f` can be called as a function. + + Parameters: ~ + {f} Any object + + Return: ~ + true if `f` is callable, else false + + vim:tw=78:ts=8:ft=help:norl: diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt index abe86749c4..58c0d832e6 100644 --- a/runtime/doc/map.txt +++ b/runtime/doc/map.txt @@ -786,7 +786,7 @@ g@{motion} Call the function set by the 'operatorfunc' option. character of the text. The function is called with one String argument: "line" {motion} was |linewise| - "char" {motion} was |characterwise| + "char" {motion} was |charwise| "block" {motion} was |blockwise-visual| Although "block" would rarely appear, since it can only result from Visual mode where "g@" is not useful. diff --git a/runtime/doc/message.txt b/runtime/doc/message.txt index e8c76adad4..bcfd985e71 100644 --- a/runtime/doc/message.txt +++ b/runtime/doc/message.txt @@ -556,7 +556,8 @@ allowed for the command that was used. Vim was not able to create a swap file. You can still edit the file, but if Vim unexpectedly exits the changes will be lost. And Vim may consume a lot of memory when editing a big file. You may want to change the 'directory' option -to avoid this error. See |swap-file|. +to avoid this error. This error is not given when 'directory' is empty. See +|swap-file|. *E140* > Use ! to write partial buffer @@ -678,8 +679,8 @@ no argument has been specified. Invalid argument: {arg} Duplicate argument: {arg} -An Ex command or function has been executed, but an invalid argument has been -specified. +Ex command or function has been executed, but an invalid argument was +specified. Or a non-executable command was given to |system()|. *E488* > Trailing characters diff --git a/runtime/doc/motion.txt b/runtime/doc/motion.txt index 97c7d1cc43..3947e583b7 100644 --- a/runtime/doc/motion.txt +++ b/runtime/doc/motion.txt @@ -60,11 +60,11 @@ After applying the operator the cursor is mostly left at the start of the text that was operated upon. For example, "yfe" doesn't move the cursor, but "yFe" moves the cursor leftwards to the "e" where the yank started. - *linewise* *characterwise* + *linewise* *charwise* *characterwise* The operator either affects whole lines, or the characters between the start and end position. Generally, motions that move between lines affect lines (are linewise), and motions that move within a line affect characters (are -characterwise). However, there are some exceptions. +charwise). However, there are some exceptions. *exclusive* *inclusive* Character motion is either inclusive or exclusive. When inclusive, the @@ -106,10 +106,10 @@ This cannot be repeated: > d:if 1<CR> call search("f")<CR> endif<CR> -Note that when using ":" any motion becomes characterwise exclusive. +Note that when using ":" any motion becomes charwise exclusive. *forced-motion* -FORCING A MOTION TO BE LINEWISE, CHARACTERWISE OR BLOCKWISE +FORCING A MOTION TO BE LINEWISE, CHARWISE OR BLOCKWISE When a motion is not of the type you would like to use, you can force another type by using "v", "V" or CTRL-V just after the operator. @@ -121,22 +121,22 @@ deletes from the cursor position until the character below the cursor > d<C-V>j deletes the character under the cursor and the character below the cursor. > -Be careful with forcing a linewise movement to be used characterwise or -blockwise, the column may not always be defined. +Be careful with forcing a linewise movement to be used charwise or blockwise, +the column may not always be defined. *o_v* v When used after an operator, before the motion command: Force - the operator to work characterwise, also when the motion is + the operator to work charwise, also when the motion is linewise. If the motion was linewise, it will become |exclusive|. - If the motion already was characterwise, toggle + If the motion already was charwise, toggle inclusive/exclusive. This can be used to make an exclusive motion inclusive and an inclusive motion exclusive. *o_V* V When used after an operator, before the motion command: Force the operator to work linewise, also when the motion is - characterwise. + charwise. *o_CTRL-V* CTRL-V When used after an operator, before the motion command: Force @@ -219,6 +219,12 @@ g^ When lines wrap ('wrap' on): To the first non-blank gm Like "g0", but half a screenwidth to the right (or as much as possible). + *gM* +gM Like "g0", but to halfway the text of the line. + With a count: to this percentage of text in the line. + Thus "10gM" is near the start of the text and "90gM" + is near the end of the text. + *g$* *g<End>* g$ or g<End> When lines wrap ('wrap' on): To the last character of the screen line and [count - 1] screen lines downward @@ -412,35 +418,35 @@ between Vi and Vim. 5. Text object motions *object-motions* *(* -( [count] sentences backward. |exclusive| motion. +( [count] |sentence|s backward. |exclusive| motion. *)* -) [count] sentences forward. |exclusive| motion. +) [count] |sentence|s forward. |exclusive| motion. *{* -{ [count] paragraphs backward. |exclusive| motion. +{ [count] |paragraph|s backward. |exclusive| motion. *}* -} [count] paragraphs forward. |exclusive| motion. +} [count] |paragraph|s forward. |exclusive| motion. *]]* -]] [count] sections forward or to the next '{' in the +]] [count] |section|s forward or to the next '{' in the first column. When used after an operator, then also stops below a '}' in the first column. |exclusive| Note that |exclusive-linewise| often applies. *][* -][ [count] sections forward or to the next '}' in the +][ [count] |section|s forward or to the next '}' in the first column. |exclusive| Note that |exclusive-linewise| often applies. *[[* -[[ [count] sections backward or to the previous '{' in +[[ [count] |section|s backward or to the previous '{' in the first column. |exclusive| Note that |exclusive-linewise| often applies. *[]* -[] [count] sections backward or to the previous '}' in +[] [count] |section|s backward or to the previous '}' in the first column. |exclusive| Note that |exclusive-linewise| often applies. @@ -502,36 +508,36 @@ aw "a word", select [count] words (see |word|). Leading or trailing white space is included, but not counted. When used in Visual linewise mode "aw" switches to - Visual characterwise mode. + Visual charwise mode. *v_iw* *iw* iw "inner word", select [count] words (see |word|). White space between words is counted too. When used in Visual linewise mode "iw" switches to - Visual characterwise mode. + Visual charwise mode. *v_aW* *aW* aW "a WORD", select [count] WORDs (see |WORD|). Leading or trailing white space is included, but not counted. When used in Visual linewise mode "aW" switches to - Visual characterwise mode. + Visual charwise mode. *v_iW* *iW* iW "inner WORD", select [count] WORDs (see |WORD|). White space between words is counted too. When used in Visual linewise mode "iW" switches to - Visual characterwise mode. + Visual charwise mode. *v_as* *as* as "a sentence", select [count] sentences (see |sentence|). - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. *v_is* *is* is "inner sentence", select [count] sentences (see |sentence|). - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. *v_ap* *ap* ap "a paragraph", select [count] paragraphs (see @@ -552,14 +558,14 @@ a[ "a [] block", select [count] '[' ']' blocks. This goes backwards to the [count] unclosed '[', and finds the matching ']'. The enclosed text is selected, including the '[' and ']'. - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. i] *v_i]* *v_i[* *i]* *i[* i[ "inner [] block", select [count] '[' ']' blocks. This goes backwards to the [count] unclosed '[', and finds the matching ']'. The enclosed text is selected, excluding the '[' and ']'. - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. a) *v_a)* *a)* *a(* a( *vab* *v_ab* *v_a(* *ab* @@ -567,54 +573,54 @@ ab "a block", select [count] blocks, from "[count] [(" to the matching ')', including the '(' and ')' (see |[(|). Does not include white space outside of the parenthesis. - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. i) *v_i)* *i)* *i(* i( *vib* *v_ib* *v_i(* *ib* ib "inner block", select [count] blocks, from "[count] [(" to the matching ')', excluding the '(' and ')' (see |[(|). - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. a> *v_a>* *v_a<* *a>* *a<* a< "a <> block", select [count] <> blocks, from the [count]'th unmatched '<' backwards to the matching '>', including the '<' and '>'. - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. i> *v_i>* *v_i<* *i>* *i<* i< "inner <> block", select [count] <> blocks, from the [count]'th unmatched '<' backwards to the matching '>', excluding the '<' and '>'. - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. *v_at* *at* at "a tag block", select [count] tag blocks, from the [count]'th unmatched "<aaa>" backwards to the matching "</aaa>", including the "<aaa>" and "</aaa>". See |tag-blocks| about the details. - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. *v_it* *it* it "inner tag block", select [count] tag blocks, from the [count]'th unmatched "<aaa>" backwards to the matching "</aaa>", excluding the "<aaa>" and "</aaa>". See |tag-blocks| about the details. - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. a} *v_a}* *a}* *a{* a{ *v_aB* *v_a{* *aB* aB "a Block", select [count] Blocks, from "[count] [{" to the matching '}', including the '{' and '}' (see |[{|). - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. i} *v_i}* *i}* *i{* i{ *v_iB* *v_i{* *iB* iB "inner Block", select [count] Blocks, from "[count] [{" to the matching '}', excluding the '{' and '}' (see |[{|). - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. a" *v_aquote* *aquote* a' *v_a'* *a'* @@ -628,7 +634,7 @@ a` *v_a`* *a`* start of the line. Any trailing white space is included, unless there is none, then leading white space is included. - When used in Visual mode it is made characterwise. + When used in Visual mode it is made charwise. Repeating this object in Visual mode another string is included. A count is currently not used. @@ -1077,6 +1083,60 @@ When you split a window, the jumplist will be copied to the new window. If you have included the ' item in the 'shada' option the jumplist will be stored in the ShaDa file and restored when starting Vim. + *jumplist-stack* +When jumpoptions includes "stack", the jumplist behaves like the history in a +web browser and like the tag stack. When jumping to a new location from the +middle of the jumplist, the locations after the current position will be +discarded. + +This behavior corresponds to the following situation in a web browser. +Navigate to first.com, second.com, third.com, fourth.com and then fifth.com. +Then navigate backwards twice so that third.com is displayed. At that point, +the history is: +- first.com +- second.com +- third.com <-- +- fourth.com +- fifth.com + +Finally, navigate to a different webpage, new.com. The history is +- first.com +- second.com +- third.com +- new.com <-- + +When the jumpoptions includes "stack", this is the behavior of neovim as well. +That is, given a jumplist like the following in which CTRL-O has been used to +move back three times to location X + + jump line col file/text + 2 1260 8 src/nvim/mark.c <-- location X-2 + 1 685 0 src/nvim/option_defs.h <-- location X-1 +> 0 462 36 src/nvim/option_defs.h <-- location X + 1 479 39 src/nvim/option_defs.h + 2 213 2 src/nvim/mark.c + 3 181 0 src/nvim/mark.c + +jumping to location Y results in the locations after the current locations being +removed: + + jump line col file/text + 3 1260 8 src/nvim/mark.c + 2 685 0 src/nvim/option_defs.h + 1 462 36 src/nvim/option_defs.h <-- location X +> + +Then, when yet another location Z is jumped to, the new location Y appears +directly after location X in the jumplist and location X remains in the same +position relative to the locations (X-1, X-2, etc., ...) that had been before it +prior to the original jump from X to Y: + + jump line col file/text + 4 1260 8 src/nvim/mark.c <-- location X-2 + 3 685 0 src/nvim/option_defs.h <-- location X-1 + 2 462 36 src/nvim/option_defs.h <-- location X + 1 100 0 src/nvim/option_defs.h <-- location Y +> CHANGE LIST JUMPS *changelist* *change-list-jumps* *E664* diff --git a/runtime/doc/msgpack_rpc.txt b/runtime/doc/msgpack_rpc.txt index f5d42dfeb2..5368cf0f4f 100644 --- a/runtime/doc/msgpack_rpc.txt +++ b/runtime/doc/msgpack_rpc.txt @@ -1,7 +1,8 @@ - NVIM REFERENCE MANUAL by Thiago de Arruda - - + NVIM REFERENCE MANUAL This document was merged into |api.txt| and |develop.txt|. + +============================================================================== + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 188f7fc2e2..4b8740c5d2 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -843,6 +843,14 @@ A jump table for the options with a short description can be found at |Q_op|. name, precede it with a backslash. - To include a comma in a directory name precede it with a backslash. - A directory name may end in an '/'. + - For Unix and Win32, if a directory ends in two path separators "//", + the swap file name will be built from the complete path to the file + with all path separators changed to percent '%' signs. This will + ensure file name uniqueness in the backup directory. + On Win32, it is also possible to end with "\\". However, When a + separating comma is following, you must use "//", since "\\" will + include the comma in the file name. Therefore it is recommended to + use '//', instead of '\\'. - Environment variables are expanded |:set_env|. - Careful with '\' characters, type one before a space, type two to get one in the option (see |option-backslash|), for example: > @@ -1875,7 +1883,7 @@ A jump table for the options with a short description can be found at |Q_op|. security reasons. *'dip'* *'diffopt'* -'diffopt' 'dip' string (default "internal,filler") +'diffopt' 'dip' string (default "internal,filler,closeoff") global Option settings for diff mode. It can consist of the following items. All are optional. Items must be separated by a comma. @@ -1932,6 +1940,12 @@ A jump table for the options with a short description can be found at |Q_op|. vertical Start diff mode with vertical splits (unless explicitly specified otherwise). + closeoff When a window is closed where 'diff' is set + and there is only one window remaining in the + same tab page with 'diff' set, execute + `:diffoff` in that window. This undoes a + `:diffsplit` command. + hiddenoff Do not use diff mode for a buffer when it becomes hidden. @@ -1978,7 +1992,7 @@ A jump table for the options with a short description can be found at |Q_op|. possible. If it is not possible in any directory, but last directory listed in the option does not exist, it is created. - Empty means that no swap file will be used (recovery is - impossible!). + impossible!) and no |E303| error will be given. - A directory "." means to put the swap file in the same directory as the edited file. On Unix, a dot is prepended to the file name, so it doesn't show in a directory listing. On MS-Windows the "hidden" @@ -1986,12 +2000,14 @@ A jump table for the options with a short description can be found at |Q_op|. - A directory starting with "./" (or ".\" for Windows) means to put the swap file relative to where the edited file is. The leading "." is replaced with the path name of the edited file. - - For Unix and Win32, if a directory ends in two path separators "//" - or "\\", the swap file name will be built from the complete path to - the file with all path separators substituted to percent '%' signs. - This will ensure file name uniqueness in the preserve directory. - On Win32, when a separating comma is following, you must use "//", - since "\\" will include the comma in the file name. + - For Unix and Win32, if a directory ends in two path separators "//", + the swap file name will be built from the complete path to the file + with all path separators substituted to percent '%' signs. This will + ensure file name uniqueness in the preserve directory. + On Win32, it is also possible to end with "\\". However, When a + separating comma is following, you must use "//", since "\\" will + include the comma in the file name. Therefore it is recommended to + use '//', instead of '\\'. - Spaces after the comma are ignored, other spaces are considered part of the directory name. To have a space at the start of a directory name, precede it with a backslash. @@ -2242,8 +2258,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'fileformat'* *'ff'* 'fileformat' 'ff' string (Windows default: "dos", - Unix default: "unix", - Macintosh default: "mac") + Unix default: "unix") local to buffer This gives the <EOL> of the current buffer, which is used for reading/writing the buffer from/to a file: @@ -2265,7 +2280,6 @@ A jump table for the options with a short description can be found at |Q_op|. 'fileformats' 'ffs' string (default: Vim+Vi Win32: "dos,unix", Vim Unix: "unix,dos", - Vim Mac: "mac,unix,dos", Vi others: "") global This gives the end-of-line (<EOL>) formats that will be tried when @@ -2348,7 +2362,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'fillchars'* *'fcs'* 'fillchars' 'fcs' string (default "") - local to window + global or local to window |global-local| Characters to fill the statuslines and vertical separators. It is a comma separated list of items: @@ -3443,6 +3457,17 @@ A jump table for the options with a short description can be found at |Q_op|. Unprintable and zero-width Unicode characters are displayed as <xxxx>. There is no option to specify these characters. + *'jumpoptions'* *'jop'* +'jumpoptions' 'jop' string (default "") + global + List of words that change the behavior of the |jumplist|. + stack Make the jumplist behave like the tagstack or like a + web browser. Relative location of entries in the + jumplist is preserved at the cost of discarding + subsequent entries when navigating backwards in the + jumplist and then jumping to a location. + |jumplist-stack| + *'joinspaces'* *'js'* *'nojoinspaces'* *'nojs'* 'joinspaces' 'js' boolean (default on) global @@ -3657,7 +3682,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'listchars'* *'lcs'* 'listchars' 'lcs' string (default: "tab:> ,trail:-,nbsp:+" Vi default: "eol:$") - local to window + global or local to window |global-local| Strings to use in 'list' mode and for the |:list| command. It is a comma separated list of string settings. @@ -3698,9 +3723,9 @@ A jump table for the options with a short description can be found at |Q_op|. off and the line continues beyond the right of the screen. *lcs-precedes* - precedes:c Character to show in the first column, when 'wrap' - is off and there is text preceding the character - visible in the first column. + precedes:c Character to show in the first visible column of the + physical line, when there is text preceding the + character visible in the first column. *lcs-conceal* conceal:c Character to show in place of concealed text, when 'conceallevel' is set to 1. A space when omitted. @@ -4583,6 +4608,16 @@ A jump table for the options with a short description can be found at |Q_op|. RedrawDebugRecompose guibg=Red redraw generated by the compositor itself, due to a grid being moved or deleted. + nothrottle Turn off throttling of the message grid. This is an + optimization that joins many small scrolls to one + larger scroll when drawing the message area (with + 'display' msgsep flag active). + invalid Enable stricter checking (abort) of inconsistencies + of the internal screen state. This is mostly + useful when running nvim inside a debugger (and + the test suite). + nodelta Send all internally redrawn cells to the UI, even if + they are unchanged from the already displayed state. *'redrawtime'* *'rdt'* 'redrawtime' 'rdt' number (default 2000) @@ -5159,7 +5194,7 @@ A jump table for the options with a short description can be found at |Q_op|. unescaping, so to keep yourself sane use |:let-&| like shown above. *shell-powershell* To use powershell (on Windows): > - set shell=powershell shellquote=( shellpipe=\| shellxquote= + set shell=powershell shellquote= shellpipe=\| shellxquote= set shellcmdflag=-NoLogo\ -NoProfile\ -ExecutionPolicy\ RemoteSigned\ -Command set shellredir=\|\ Out-File\ -Encoding\ UTF8 @@ -5722,7 +5757,7 @@ A jump table for the options with a short description can be found at |Q_op|. current one. |:vsplit| *'startofline'* *'sol'* *'nostartofline'* *'nosol'* -'startofline' 'sol' boolean (default on) +'startofline' 'sol' boolean (default off) global When "on" the commands listed below move the cursor to the first non-blank of the line. When off the cursor is kept in the same column @@ -5990,6 +6025,8 @@ A jump table for the options with a short description can be found at |Q_op|. vsplit Just like "split" but split vertically. newtab Like "split", but open a new tab page. Overrules "split" when both are present. + uselast If included, jump to the previously used window when + jumping to errors with |quickfix| commands. *'synmaxcol'* *'smc'* 'synmaxcol' 'smc' number (default 3000) @@ -6149,6 +6186,14 @@ A jump table for the options with a short description can be found at |Q_op|. match Match case smart Ignore case unless an upper case letter is used + *'tagfunc'* *'tfu'* +'tagfunc' 'tfu' string (default: empty) + local to buffer + This option specifies a function to be used to perform tag searches. + The function gets the tag pattern and should return a List of matching + tags. See |tag-function| for an explanation of how to write the + function and an example. + *'taglength'* *'tl'* 'taglength' 'tl' number (default 0) global @@ -6620,22 +6665,18 @@ A jump table for the options with a short description can be found at |Q_op|. *'wildmenu'* *'wmnu'* *'nowildmenu'* *'nowmnu'* 'wildmenu' 'wmnu' boolean (default on) global - When 'wildmenu' is on, command-line completion operates in an enhanced - mode. On pressing 'wildchar' (usually <Tab>) to invoke completion, - the possible matches are shown just above the command line, with the - first match highlighted (overwriting the status line, if there is - one). Keys that show the previous/next match, such as <Tab> or - CTRL-P/CTRL-N, cause the highlight to move to the appropriate match. - When 'wildmode' is used, "wildmenu" mode is used where "full" is - specified. "longest" and "list" do not start "wildmenu" mode. - You can check the current mode with |wildmenumode()|. - If there are more matches than can fit in the line, a ">" is shown on - the right and/or a "<" is shown on the left. The status line scrolls - as needed. - The "wildmenu" mode is abandoned when a key is hit that is not used - for selecting a completion. - While the "wildmenu" is active the following keys have special - meanings: + Enables "enhanced mode" of command-line completion. When user hits + <Tab> (or 'wildchar') to invoke completion, the possible matches are + shown in a menu just above the command-line (see 'wildoptions'), with + the first match highlighted (overwriting the statusline). Keys that + show the previous/next match (<Tab>/CTRL-P/CTRL-N) highlight the + match. + 'wildmode' must specify "full": "longest" and "list" do not start + 'wildmenu' mode. You can check the current mode with |wildmenumode()|. + The menu is canceled when a key is hit that is not used for selecting + a completion. + + While the menu is active these keys have special meanings: <Left> <Right> - select previous/next match (like CTRL-P/CTRL-N) <Down> - in filename/menu name completion: move into a @@ -6645,15 +6686,12 @@ A jump table for the options with a short description can be found at |Q_op|. <Up> - in filename/menu name completion: move up into parent directory or parent menu. - This makes the menus accessible from the console |console-menus|. - - If you prefer the <Left> and <Right> keys to move the cursor instead - of selecting a different match, use this: > + If you want <Left> and <Right> to move the cursor instead of selecting + a different match, use this: > :cnoremap <Left> <Space><BS><Left> :cnoremap <Right> <Space><BS><Right> < - The "WildMenu" highlighting is used for displaying the current match - |hl-WildMenu|. + |hl-WildMenu| highlights the current match. *'wildmode'* *'wim'* 'wildmode' 'wim' string (default: "full") @@ -6908,7 +6946,6 @@ A jump table for the options with a short description can be found at |Q_op|. global The number of milliseconds to wait for each character sent to the screen. When positive, characters are sent to the UI one by one. - When negative, all redrawn characters cause a delay, even if the - character already was displayed by the UI. For debugging purposes. + See 'redrawdebug' for more options. For debugging purposes. vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt index 3ae6d9461f..61e090cc78 100644 --- a/runtime/doc/quickfix.txt +++ b/runtime/doc/quickfix.txt @@ -109,6 +109,36 @@ processing a quickfix or location list command, it will be aborted. list for the current window is used instead of the quickfix list. + *:cabo* *:cabove* +:[count]cabo[ve] Go to the [count] error above the current line in the + current buffer. If [count] is omitted, then 1 is + used. If there are no errors, then an error message + is displayed. Assumes that the entries in a quickfix + list are sorted by their buffer number and line + number. If there are multiple errors on the same line, + then only the first entry is used. If [count] exceeds + the number of entries above the current line, then the + first error in the file is selected. + + *:lab* *:labove* +:[count]lab[ove] Same as ":cabove", except the location list for the + current window is used instead of the quickfix list. + + *:cbe* *:cbelow* +:[count]cbe[low] Go to the [count] error below the current line in the + current buffer. If [count] is omitted, then 1 is + used. If there are no errors, then an error message + is displayed. Assumes that the entries in a quickfix + list are sorted by their buffer number and line + number. If there are multiple errors on the same + line, then only the first entry is used. If [count] + exceeds the number of entries below the current line, + then the last error in the file is selected. + + *:lbe* *:lbelow* +:[count]lbe[low] Same as ":cbelow", except the location list for the + current window is used instead of the quickfix list. + *:cnf* *:cnfile* :[count]cnf[ile][!] Display the first error in the [count] next file in the list that includes a file name. If there are no diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt index 87cb9b54f5..224f14a18b 100644 --- a/runtime/doc/quickref.txt +++ b/runtime/doc/quickref.txt @@ -47,6 +47,7 @@ N is used to indicate an optional count that can be given before the command. |g$| N g$ to last character in screen line (differs from "$" when lines wrap) |gm| gm to middle of the screen line +|gM| gM to middle of the line |bar| N | to column N (default: 1) |f| N f{char} to the Nth occurrence of {char} to the right |F| N F{char} to the Nth occurrence of {char} to the left @@ -742,6 +743,7 @@ Short explanation of each option: *option-list* 'iskeyword' 'isk' characters included in keywords 'isprint' 'isp' printable characters 'joinspaces' 'js' two spaces after a period with a join command +'jumpoptions' 'jop' specifies how jumping is done 'keymap' 'kmp' name of a keyboard mapping 'keymodel' 'km' enable starting/stopping selection with keys 'keywordprg' 'kp' program to use for the "K" command diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index 7dbbb2d424..e3f0d593a7 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -1270,7 +1270,7 @@ exactly four MessagePack objects: Key Type Def Description ~ rt UInteger 0 Register type: No Description ~ - 0 |characterwise-register| + 0 |charwise-register| 1 |linewise-register| 2 |blockwise-register| rw UInteger 0 Register width. Only valid diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 0a4257e2b2..5424ad00ec 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -4720,18 +4720,19 @@ the same syntax file on all UIs. *bold* *underline* *undercurl* *inverse* *italic* *standout* - *strikethrough* + *nocombine* *strikethrough* cterm={attr-list} *attr-list* *highlight-cterm* *E418* attr-list is a comma separated list (without spaces) of the following items (in any order): bold underline undercurl curly underline + strikethrough reverse inverse same as reverse italic standout - strikethrough + nocombine override attributes instead of combining them NONE no attributes used (used to reset it) Note that "bold" can be used here and by using a bold font. They diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt index bb3134feb6..b011db3dd3 100644 --- a/runtime/doc/tagsrch.txt +++ b/runtime/doc/tagsrch.txt @@ -838,4 +838,70 @@ Common arguments for the commands above: < For a ":djump", ":dsplit", ":dlist" and ":dsearch" command the pattern is used as a literal string, not as a search pattern. +============================================================================== +7. Using 'tagfunc' *tag-function* + +It is possible to provide Vim with a function which will generate a list of +tags used for commands like |:tag|, |:tselect| and Normal mode tag commands +like |CTRL-]|. + +The function used for generating the taglist is specified by setting the +'tagfunc' option. The function will be called with three arguments: + a:pattern The tag identifier used during the tag search. + a:flags List of flags to control the function behavior. + a:info Dict containing the following entries: + buf_ffname Full filename which can be used for priority. + user_data Custom data String, if stored in the tag + stack previously by tagfunc. + +Currently two flags may be passed to the tag function: + 'c' The function was invoked by a normal command being processed + (mnemonic: the tag function may use the context around the + cursor to perform a better job of generating the tag list.) + 'i' In Insert mode, the user was completing a tag (with + |i_CTRL-X_CTRL-]|). + +Note that when 'tagfunc' is set, the priority of the tags described in +|tag-priority| does not apply. Instead, the priority is exactly as the +ordering of the elements in the list returned by the function. + *E987* +The function should return a List of Dict entries. Each Dict must at least +include the following entries and each value must be a string: + name Name of the tag. + filename Name of the file where the tag is defined. It is + either relative to the current directory or a full path. + cmd Ex command used to locate the tag in the file. This + can be either an Ex search pattern or a line number. +Note that the format is similar to that of |taglist()|, which makes it possible +to use its output to generate the result. +The following fields are optional: + kind Type of the tag. + user_data String of custom data stored in the tag stack which + can be used to disambiguate tags between operations. + +If the function returns |v:null| instead of a List, a standard tag lookup will +be performed instead. + +It is not allowed to change the tagstack from inside 'tagfunc'. *E986* + +The following is a hypothetical example of a function used for 'tagfunc'. It +uses the output of |taglist()| to generate the result: a list of tags in the +inverse order of file names. +> + function! TagFunc(pattern, flags, info) + function! CompareFilenames(item1, item2) + let f1 = a:item1['filename'] + let f2 = a:item2['filename'] + return f1 >=# f2 ? + \ -1 : f1 <=# f2 ? 1 : 0 + endfunction + + let result = taglist(a:pattern) + call sort(result, "CompareFilenames") + + return result + endfunc + set tagfunc=TagFunc +< + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index a2f19593ae..d5f4a59ab3 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -201,8 +201,8 @@ the editor. sent from Nvim, like for |ui-cmdline|. ["mode_change", mode, mode_idx] - The mode changed. The first parameter `mode` is a string representing - the current mode. `mode_idx` is an index into the array received in + Editor mode changed. The `mode` parameter is a string representing + the current mode. `mode_idx` is an index into the array emitted in the `mode_info_set` event. UIs should change the cursor style according to the properties specified in the corresponding item. The set of modes reported will change in new versions of Nvim, for @@ -211,11 +211,11 @@ the editor. ["mouse_on"] ["mouse_off"] - Tells the client whether mouse support, as determined by |'mouse'| - option, is considered to be active in the current mode. This is mostly - useful for a terminal frontend, or other situations where Nvim mouse - would conflict with other usages of the mouse. It is safe for a client - to ignore this and always send mouse events. + |'mouse'| was enabled/disabled in the current editor mode. Useful for + a terminal UI, or other situations where Nvim mouse would conflict + with other usages of the mouse. UIs may ignore this and always send + mouse input, because 'mouse' decides the behavior of |nvim_input()| + implicitly. ["busy_start"] ["busy_stop"] diff --git a/runtime/doc/usr_25.txt b/runtime/doc/usr_25.txt index 3a58af6412..2efb67e55f 100644 --- a/runtime/doc/usr_25.txt +++ b/runtime/doc/usr_25.txt @@ -346,12 +346,13 @@ scroll: g0 to first visible character in this line g^ to first non-blank visible character in this line - gm to middle of this line + gm to middle of screen line + gM to middle of the text in this line g$ to last visible character in this line - |<-- window -->| - some long text, part of which is visible ~ - g0 g^ gm g$ + |<-- window -->| + some long text, part of which is visible in one line ~ + g0 g^ gm gM g$ BREAKING AT WORDS *edit-no-break* diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 45a94bb961..64b5830575 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -55,6 +55,7 @@ the differences. - 'showcmd' is enabled - 'sidescroll' defaults to 1 - 'smarttab' is enabled +- 'startofline' is disabled - 'tabpagemax' defaults to 50 - 'tags' defaults to "./tags;,tags" - 'ttimeoutlen' defaults to 50 @@ -168,6 +169,7 @@ Functions: |system()|, |systemlist()| can run {cmd} directly (without 'shell') Highlight groups: + |highlight-blend| controls blend level for a highlight group |expr-highlight| highlight groups (prefixed with "Nvim") |hl-NormalFloat| highlights floating window |hl-NormalNC| highlights non-current windows @@ -206,6 +208,7 @@ Options: 'statusline' supports unlimited alignment sections 'tabline' %@Func@foo%X can call any function on mouse-click 'wildoptions' `pum` flag to use popupmenu for wildmode completion + 'winblend' pseudo-transparency in floating windows |api-floatwin| 'winhighlight' window-local highlights Signs: @@ -296,7 +299,7 @@ coerced to strings. See |id()| for more details, currently it uses |c_CTRL-R| pasting a non-special register into |cmdline| omits the last <CR>. -Lua interface (|if_lua.txt|): +Lua interface (|lua.txt|): - `:lua print("a\0b")` will print `a^@b`, like with `:echomsg "a\nb"` . In Vim that prints `a` and `b` on separate lines, exactly like @@ -307,15 +310,15 @@ Lua interface (|if_lua.txt|): - Lua package.path and package.cpath are automatically updated according to 'runtimepath': |lua-require|. -|input()| and |inputdialog()| support for each other’s features (return on -cancel and completion respectively) via dictionary argument (replaces all -other arguments if used). - -|input()| and |inputdialog()| support user-defined cmdline highlighting. - Commands: |:doautocmd| does not warn about "No matching autocommands". +Functions: + |input()| and |inputdialog()| support for each other’s features (return on + cancel and completion respectively) via dictionary argument (replaces all + other arguments if used). + |input()| and |inputdialog()| support user-defined cmdline highlighting. + Highlight groups: |hl-ColorColumn|, |hl-CursorColumn| are lower priority than most other groups @@ -333,6 +336,11 @@ Macro/|recording| behavior Motion: The |jumplist| avoids useless/phantom jumps. + When the new option |jumpoptions| includes 'stack', the jumplist behaves + like the tagstack or history in a web browser--jumping from the middle of + the jumplist discards the locations after the jumped-from position + (|jumplist-stack|). + Normal commands: |Q| is the same as |gQ| @@ -399,10 +407,10 @@ VimL (Vim script) compatibility: Some legacy Vim features are not implemented: -- |if_py|: *python-bindeval* *python-Function* are not supported -- |if_lua|: the `vim` object is missing some legacy methods -- *if_perl* +- |if_lua|: Nvim Lua API is not compatible with Vim's "if_lua" - *if_mzscheme* +- *if_perl* +- |if_py|: *python-bindeval* *python-Function* are not supported - *if_tcl* ============================================================================== @@ -524,4 +532,4 @@ TUI: always uses 7-bit control sequences. ============================================================================== - vim:tw=78:ts=8:sw=2:noet:ft=help:norl: + vim:tw=78:ts=8:sw=2:et:ft=help:norl: diff --git a/runtime/doc/visual.txt b/runtime/doc/visual.txt index ccbbc092ec..0052382044 100644 --- a/runtime/doc/visual.txt +++ b/runtime/doc/visual.txt @@ -48,7 +48,7 @@ position. ============================================================================== 2. Starting and stopping Visual mode *visual-start* - *v* *characterwise-visual* + *v* *charwise-visual* [count]v Start Visual mode per character. With [count] select the same number of characters or lines as used for the last Visual operation, but at @@ -74,7 +74,7 @@ position. If you use <Esc>, click the left mouse button or use any command that does a jump to another buffer while in Visual mode, the highlighting stops -and no text is affected. Also when you hit "v" in characterwise Visual mode, +and no text is affected. Also when you hit "v" in charwise Visual mode, "CTRL-V" in blockwise Visual mode or "V" in linewise Visual mode. If you hit CTRL-Z the highlighting stops and the editor is suspended or a new shell is started |CTRL-Z|. @@ -477,7 +477,7 @@ Commands in Select mode: Otherwise, typed characters are handled as in Visual mode. When using an operator in Select mode, and the selection is linewise, the -selected lines are operated upon, but like in characterwise selection. For +selected lines are operated upon, but like in charwise selection. For example, when a whole line is deleted, it can later be pasted in the middle of a line. @@ -510,7 +510,7 @@ gV Avoid the automatic reselection of the Visual area selection. *gh* -gh Start Select mode, characterwise. This is like "v", +gh Start Select mode, charwise. This is like "v", but starts Select mode instead of Visual mode. Mnemonic: "get highlighted". diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index 76bb096ee3..977e0daef7 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -201,9 +201,11 @@ CTRL-W CTRL_N *CTRL-W_CTRL-N* |:find|. Doesn't split if {file} is not found. CTRL-W CTRL-^ *CTRL-W_CTRL-^* *CTRL-W_^* -CTRL-W ^ Does ":split #", split window in two and edit alternate file. - When a count is given, it becomes ":split #N", split window - and edit buffer N. +CTRL-W ^ Split the current window in two and edit the alternate file. + When a count N is given, split the current window and edit + buffer N. Similar to ":sp #" and ":sp #N", but it allows the + other buffer to be unnamed. This command matches the behavior + of |CTRL-^|, except that it splits a window first. CTRL-W ge *CTRL-W_ge* Detach the current window as an external window. |