aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2024-09-24 04:46:50 -0700
committerGitHub <noreply@github.com>2024-09-24 04:46:50 -0700
commit3f6bc34e663c62bc8899dcdc65bf204b2ccfdaec (patch)
tree447732924440ecc91783e26232cd77dc80a1049b
parent2276743cb8e13483ba15695ef0a1ea65263e825f (diff)
downloadrneovim-3f6bc34e663c62bc8899dcdc65bf204b2ccfdaec.tar.gz
rneovim-3f6bc34e663c62bc8899dcdc65bf204b2ccfdaec.tar.bz2
rneovim-3f6bc34e663c62bc8899dcdc65bf204b2ccfdaec.zip
docs: lua error patterns #30240
Co-authored-by: Mathias Fussenegger <f.mathias@zignar.net> Co-authored-by: Ananth Bhaskararaman <antsub@gmail.com>
-rw-r--r--.github/workflows/notes.md7
-rw-r--r--CMakeLists.txt1
-rw-r--r--runtime/doc/api.txt41
-rw-r--r--runtime/doc/dev_style.txt31
-rw-r--r--runtime/doc/develop.txt43
-rw-r--r--runtime/doc/lua.txt39
-rw-r--r--runtime/doc/starting.txt4
-rw-r--r--runtime/doc/support.txt3
-rw-r--r--runtime/doc/vim_diff.txt14
-rw-r--r--runtime/lua/vim/_editor.lua6
-rw-r--r--runtime/lua/vim/_meta/api.lua36
-rw-r--r--src/nvim/api/buffer.c8
-rw-r--r--src/nvim/api/vim.c38
13 files changed, 186 insertions, 85 deletions
diff --git a/.github/workflows/notes.md b/.github/workflows/notes.md
index f67a098687..25f4a5fb32 100644
--- a/.github/workflows/notes.md
+++ b/.github/workflows/notes.md
@@ -18,6 +18,8 @@ ${NVIM_VERSION}
2. Run the MSI
3. Run `nvim.exe` on your CLI of choice
+Note: On Windows "Server" you may need to [install vcruntime140.dll](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170).
+
### macOS (x86_64)
1. Download **nvim-macos-x86_64.tar.gz**
@@ -34,11 +36,10 @@ ${NVIM_VERSION}
### Linux (x64)
-Minimum glibc version to run these releases is 2.31. People requiring releases
-that work on older glibc versions can find them at
-https://github.com/neovim/neovim-releases.
+glibc 2.31 or newer is required. Or you may try the (unsupported) [builds for older glibc](https://github.com/neovim/neovim-releases).
#### AppImage
+
1. Download **nvim.appimage**
2. Run `chmod u+x nvim.appimage && ./nvim.appimage`
- If your system does not have FUSE you can [extract the appimage](https://github.com/AppImage/AppImageKit/wiki/FUSE#type-2-appimage):
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d8611c49a5..14bc18931e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,7 @@
# - pitfalls: https://izzys.casa/2019/02/everything-you-never-wanted-to-know-about-cmake/
# - troubleshooting:
# - variable_watch https://cmake.org/cmake/help/latest/command/variable_watch.html
+# - verbose output: cmake --build build --verbose
# Version should match the tested CMAKE_URL in .github/workflows/build.yml.
cmake_minimum_required(VERSION 3.16)
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index e7a8e788b9..828b3e5ec1 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -996,6 +996,9 @@ nvim_input({keys}) *nvim_input()*
input buffer and the call is non-blocking (input is processed
asynchronously by the eventloop).
+ To input blocks of text, |nvim_paste()| is much faster and should be
+ preferred.
+
On execution error: does not fail, but updates v:errmsg.
Note: ~
@@ -1148,21 +1151,35 @@ nvim_out_write({str}) *nvim_out_write()*
• {str} Message
nvim_paste({data}, {crlf}, {phase}) *nvim_paste()*
- Pastes at cursor, in any mode.
+ Pastes at cursor (in any mode), and sets "redo" so dot (|.|) will repeat
+ the input. UIs call this to implement "paste", but it's also intended for
+ use by scripts to input large, dot-repeatable blocks of text (as opposed
+ to |nvim_input()| which is subject to mappings/events and is thus much
+ slower).
- Invokes the `vim.paste` handler, which handles each mode appropriately.
- Sets redo/undo. Faster than |nvim_input()|. Lines break at LF ("\n").
+ Invokes the |vim.paste()| handler, which handles each mode appropriately.
Errors ('nomodifiable', `vim.paste()` failure, …) are reflected in `err`
but do not affect the return value (which is strictly decided by
`vim.paste()`). On error or cancel, subsequent calls are ignored
("drained") until the next paste is initiated (phase 1 or -1).
+ Useful in mappings and scripts to insert multiline text. Example: >vim
+ vim.keymap.set('n', 'x', function()
+ vim.api.nvim_paste([[
+ line1
+ line2
+ line3
+ ]], false, -1)
+ end, { buffer = true })
+<
+
Attributes: ~
not allowed when |textlock| is active
Parameters: ~
- • {data} Multiline input. May be binary (containing NUL bytes).
+ • {data} Multiline input. Lines break at LF ("\n"). May be binary
+ (containing NUL bytes).
• {crlf} Also break lines at CR and CRLF.
• {phase} -1: paste in a single call (i.e. without streaming). To
"stream" a paste, call `nvim_paste` sequentially with these
@@ -1176,7 +1193,8 @@ nvim_paste({data}, {crlf}, {phase}) *nvim_paste()*
• false: Client should cancel the paste.
nvim_put({lines}, {type}, {after}, {follow}) *nvim_put()*
- Puts text at cursor, in any mode.
+ Puts text at cursor, in any mode. For dot-repeatable input, use
+ |nvim_paste()|.
Compare |:put| and |p| which are always linewise.
@@ -2460,10 +2478,11 @@ nvim_buf_set_text({buffer}, {start_row}, {start_col}, {end_row}, {end_col},
`start_row = end_row = row` and `start_col = end_col = col`. To delete the
text in a range, use `replacement = {}`.
- Prefer |nvim_buf_set_lines()| if you are only adding or deleting entire
- lines.
-
- Prefer |nvim_put()| if you want to insert text at the cursor position.
+ Note: ~
+ • Prefer |nvim_buf_set_lines()| (for performance) to add or delete
+ entire lines.
+ • Prefer |nvim_paste()| or |nvim_put()| to insert (instead of replace)
+ text at cursor.
Attributes: ~
not allowed when |textlock| is active
@@ -2476,10 +2495,6 @@ nvim_buf_set_text({buffer}, {start_row}, {start_col}, {end_row}, {end_col},
• {end_col} Ending column (byte offset) on last line, exclusive
• {replacement} Array of lines to use as replacement
- See also: ~
- • |nvim_buf_set_lines()|
- • |nvim_put()|
-
nvim_buf_set_var({buffer}, {name}, {value}) *nvim_buf_set_var()*
Sets a buffer-scoped (b:) variable
diff --git a/runtime/doc/dev_style.txt b/runtime/doc/dev_style.txt
index 6c805963a9..32f7279704 100644
--- a/runtime/doc/dev_style.txt
+++ b/runtime/doc/dev_style.txt
@@ -95,9 +95,9 @@ variable is and what it was initialized to. In particular, initialization
should be used instead of declaration and assignment, e.g. >c
int i;
- i = f(); // BAD: initialization separate from declaration.
+ i = f(); // ❌: initialization separate from declaration.
- int j = g(); // GOOD: declaration has initialization.
+ int j = g(); // ✅: declaration has initialization.
Initialization ~
@@ -107,16 +107,13 @@ but each initialization should be done on a separate line.
>c
int i;
- int j; // GOOD
-
- int i, j; // GOOD: multiple declarations, no initialization.
-
+ int j; // ✅
+ int i, j; // ✅: multiple declarations, no initialization.
int i = 0;
- int j = 0; // GOOD: one initialization per line.
-
- int i = 0, j; // BAD: multiple declarations with initialization.
+ int j = 0; // ✅: one initialization per line.
- int i = 0, j = 0; // BAD: multiple declarations with initialization.
+ int i = 0, j; // ❌: multiple declarations with initialization.
+ int i = 0, j = 0; // ❌: multiple declarations with initialization.
==============================================================================
Nvim-Specific Magic
@@ -152,10 +149,10 @@ Postincrement and Postdecrement ~
Use postfix form (`i++`) in statements. >c
for (int i = 0; i < 3; i++) { }
- int j = ++i; // OK: ++i is used as an expression.
+ int j = ++i; // ✅: ++i is used as an expression.
for (int i = 0; i < 3; ++i) { }
- ++i; // BAD: ++i is used as a statement.
+ ++i; // ❌: ++i is used as a statement.
Use of const ~
@@ -217,7 +214,7 @@ Booleans ~
Use `bool` to represent boolean values. >c
- int loaded = 1; // BAD: loaded should have type bool.
+ int loaded = 1; // ❌: loaded should have type bool.
Conditions ~
@@ -382,7 +379,7 @@ Filenames should be all lowercase and can include underscores (`_`).
Use underscores to separate words. Examples of acceptable file names: >
my_useful_file.c
- getline_fix.c // OK: getline refers to the glibc function.
+ getline_fix.c // ✅: getline refers to the glibc function.
C files should end in `.c` and header files should end in `.h`.
@@ -415,10 +412,10 @@ instance: `my_exciting_local_variable`.
For example: >c
- string table_name; // OK: uses underscore.
- string tablename; // OK: all lowercase.
+ string table_name; // ✅: uses underscore.
+ string tablename; // ✅: all lowercase.
- string tableName; // BAD: mixed case.
+ string tableName; // ❌: mixed case.
<
Struct Variables ~
diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt
index 41bb90299b..9dbdaec31c 100644
--- a/runtime/doc/develop.txt
+++ b/runtime/doc/develop.txt
@@ -307,19 +307,36 @@ See also |dev-naming|.
easier to inspect and print, and inherently compatible with all Lua plugins.
(This guideline doesn't apply to opaque, non-data objects like `vim.cmd`.)
- stdlib functions should follow these common patterns:
- - accept iterable instead of table
- - exception: in some cases iterable doesn't make sense, e.g. spair() sorts
- the input by definition, so there is no reason for it to accept an
- iterable, because the input needs to be "reified"; it can't operate on
- a "stream".
- - return iterable instead of table
- - mimic the pairs() or ipairs() interface if the function is intended to be
- used in a "for" loop.
- - when a result-or-error interface is needed, return `result|nil, nil|errmsg`: >
- ---@return Foo|nil # Result object, or nil if not found.
- ---@return nil|string # Error message on failure, or nil on success.
-<
- - Examples: |vim.ui.open()| |io.open()| |luv-error-handling|
+ - Return |lua-result-or-message| (`any|nil,nil|string`) to communicate
+ failure, or choose from |dev-error-patterns| when appropriate.
+ - Accept iterable instead of only table.
+ - Note: in some cases iterable doesn't make sense, e.g. spair() sorts the
+ input by definition, so there is no reason for it to accept an iterable,
+ because the input needs to be "reified"; it can't operate on a "stream".
+ - Return an iterable (generator) instead of table, if possible.
+ - Mimic the pairs() or ipairs() interface if the function is intended for
+ use in a |for-in| loop.
+
+ *dev-error-patterns*
+To communicate failure to a consumer, choose from these patterns (in order of
+preference):
+1. `retval, errmsg`
+ - When failure is normal, or when it is practical for the consumer to
+ continue (fallback) in some other way. See |lua-result-or-message|.
+2. optional result, no errormsg
+ - Special case of 1. When there is only a single case of "doesn't exist"
+ (e.g. cache lookup, dict lookup).
+3. `error("no luck")`
+ - For invalid state ("must not happen"), when failure is exceptional, or at
+ a low level where the consumers are unlikely to handle it in a meaningful
+ way. Advantage is that propagation happens for free and it's harder to
+ accidentally swallow errors. (E.g. using
+ `uv_handle/pipe:write()` without checking return values is common.)
+4. `on_error` parameter
+ - For async and "visitors" traversing a graph, where many errors may be
+ collected while work continues.
+5. `vim.notify` (sometimes with optional `opts.silent` (async, visitors ^))
+ - High-level / application-level messages. End-user invokes these directly.
*dev-patterns*
Interface conventions ~
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index f3a40cf17a..5a70852649 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -67,7 +67,7 @@ See https://luajit.org/ext_profiler.html or the `p.lua` source for details: >
==============================================================================
LUA CONCEPTS AND IDIOMS *lua-concepts*
-Lua is very simple: this means that, while there are some quirks, once you
+Lua is very simple, and _consistent_: while there are some quirks, once you
internalize those quirks, everything works the same everywhere. Scopes
(closures) in particular are very consistent, unlike JavaScript or most other
languages.
@@ -85,6 +85,36 @@ https://www.lua.org/doc/cacm2018.pdf
- Stackful coroutines enable cooperative multithreading, generators, and
versatile control for both Lua and its host (Nvim).
+ *lua-error-handling*
+Lua functions may throw |lua-errors| for exceptional (unexpected) failures,
+which you can handle with |pcall()|.
+ *lua-result-or-message*
+When failure is normal and expected, it's idiomatic to return `nil` which
+signals to the caller that failure is not "exceptional" and must be handled.
+This "result-or-message" pattern is expressed as the multi-value return type
+`any|nil,nil|string`, or in LuaLS notation: >
+
+ ---@return any|nil # result on success, nil on failure.
+ ---@return nil|string # nil on success, error message on failure.
+<
+Examples of the "result-or-message" pattern:
+- |vim.ui.open()|
+- |io.open()|
+- |luv-error-handling|
+
+When a caller can't proceed on failure, it's idiomatic to `assert()` the
+"result-or-message" result: >lua
+
+ local value = assert(fn())
+
+Guidance: use the "result-or-message" pattern for...
+- Functions where failure is expected, especially when communicating with the
+ external world. E.g. HTTP requests or LSP requests often fail because of
+ server problems, even if the caller did everything right.
+- Functions that return a value, e.g. Foo:new().
+- When there is a list of known error codes which can be returned as a third
+ value (like |luv-error-handling|).
+<
*iterator*
An iterator is just a function that can be called repeatedly to get the "next"
value of a collection (or any other |iterable|). This interface is expected by
@@ -1666,8 +1696,11 @@ vim.on_key({fn}, {ns_id}) *vim.on_key()*
callbacks if on_key() is called without arguments.
vim.paste({lines}, {phase}) *vim.paste()*
- Paste handler, invoked by |nvim_paste()| when a conforming UI (such as the
- |TUI|) pastes text into the editor.
+ Paste handler, invoked by |nvim_paste()|.
+
+ Note: This is provided only as a "hook", don't call it directly; call
+ |nvim_paste()| instead, which arranges redo (dot-repeat) and invokes
+ `vim.paste`.
Example: To remove ANSI color codes when pasting: >lua
vim.paste = (function(overridden)
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index fb8ed0344b..3b0fa2b371 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -422,6 +422,10 @@ argument.
Start |RPC| server on pipe or TCP address {addr}. Sets the
primary listen address |v:servername| to {addr}. |serverstart()|
+ To start the server on-demand with systemd, use a systemd
+ socket unit and associated service unit running: >
+ systemd-socket-proxyd --exit-idle-time
+<
==============================================================================
Initialization *initialization* *startup*
diff --git a/runtime/doc/support.txt b/runtime/doc/support.txt
index 3f9a358962..dace2fe945 100644
--- a/runtime/doc/support.txt
+++ b/runtime/doc/support.txt
@@ -25,6 +25,9 @@ Note: Windows 10 "Version 1809" or later is required for |:terminal|. To check
your Windows version, run the "winver" command and look for "Version xxxx"
(NOT "OS Build").
+Note: On Windows "Server" you may need to install vcruntime140.dll:
+https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170
+
Support types ~
* Tier 1: Officially supported and tested with CI. Any contributed patch
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index d0868b5605..d8369cd6ce 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -67,7 +67,7 @@ Defaults *nvim-defaults*
- 'langremap' is disabled
- 'laststatus' defaults to 2 (statusline is always shown)
- 'listchars' defaults to "tab:> ,trail:-,nbsp:+"
-- 'mouse' defaults to "nvi"
+- 'mouse' defaults to "nvi", see |default-mouse| for details
- 'mousemodel' defaults to "popup_setpos"
- 'nrformats' defaults to "bin,hex"
- 'path' defaults to ".,,". The C ftplugin adds "/usr/include" if it exists.
@@ -101,12 +101,14 @@ Defaults *nvim-defaults*
DEFAULT MOUSE
*default-mouse* *disable-mouse*
-By default the mouse is enabled, and <RightMouse> opens a |popup-menu| with
-standard actions ("Cut", "Copy", "Paste", …). Mouse is NOT enabled in
-|command-mode| or the |more-prompt|, so you can temporarily disable it just by
-typing ":".
+By default the mouse is enabled. This means |scroll-mouse-wheel| will scroll
+the window instead of moving the cursor; <LeftMouse> click places the cursor;
+and <RightMouse> click opens the default |popup-menu| with standard actions.
+
+Mouse is NOT enabled in |Cmdline-mode| or the |more-prompt|, so you can
+temporarily disable it just by typing ":". Or if you want to partially or
+fully disable the mouse or popup-menu, do any of the following:
-Or you can disable the popup-menu using any of the following:
- Disable mouse completely by unsetting the 'mouse' option: >vim
set mouse=
- Change the 'mousemodel', so <RightMouse> extends selection instead of
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index 7b5570cc99..cb864bd974 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -208,8 +208,10 @@ vim.inspect = vim.inspect
do
local tdots, tick, got_line1, undo_started, trailing_nl = 0, 0, false, false, false
- --- Paste handler, invoked by |nvim_paste()| when a conforming UI
- --- (such as the |TUI|) pastes text into the editor.
+ --- Paste handler, invoked by |nvim_paste()|.
+ ---
+ --- Note: This is provided only as a "hook", don't call it directly; call |nvim_paste()| instead,
+ --- which arranges redo (dot-repeat) and invokes `vim.paste`.
---
--- Example: To remove ANSI color codes when pasting:
---
diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua
index b53a9ad321..a9430078a8 100644
--- a/runtime/lua/vim/_meta/api.lua
+++ b/runtime/lua/vim/_meta/api.lua
@@ -744,11 +744,6 @@ function vim.api.nvim_buf_set_option(buffer, name, value) end
--- `start_row = end_row = row` and `start_col = end_col = col`. To delete the
--- text in a range, use `replacement = {}`.
---
---- Prefer `nvim_buf_set_lines()` if you are only adding or deleting entire
---- lines.
----
---- Prefer `nvim_put()` if you want to insert text at the cursor position.
----
--- @param buffer integer Buffer handle, or 0 for current buffer
--- @param start_row integer First line index
--- @param start_col integer Starting column (byte offset) on first line
@@ -1484,6 +1479,9 @@ function vim.api.nvim_get_vvar(name) end
--- input buffer and the call is non-blocking (input is processed
--- asynchronously by the eventloop).
---
+--- To input blocks of text, `nvim_paste()` is much faster and should be
+--- preferred.
+---
--- On execution error: does not fail, but updates v:errmsg.
---
--- @param keys string to be typed
@@ -1809,17 +1807,34 @@ function vim.api.nvim_parse_cmd(str, opts) end
--- @return table<string,any>
function vim.api.nvim_parse_expression(expr, flags, highlight) end
---- Pastes at cursor, in any mode.
+--- Pastes at cursor (in any mode), and sets "redo" so dot (`.`) will repeat
+--- the input. UIs call this to implement "paste", but it's also intended for
+--- use by scripts to input large, dot-repeatable blocks of text (as opposed
+--- to `nvim_input()` which is subject to mappings/events and is thus much
+--- slower).
---
---- Invokes the `vim.paste` handler, which handles each mode appropriately.
---- Sets redo/undo. Faster than `nvim_input()`. Lines break at LF ("\n").
+--- Invokes the `vim.paste()` handler, which handles each mode appropriately.
---
--- Errors ('nomodifiable', `vim.paste()` failure, …) are reflected in `err`
--- but do not affect the return value (which is strictly decided by
--- `vim.paste()`). On error or cancel, subsequent calls are ignored
--- ("drained") until the next paste is initiated (phase 1 or -1).
---
---- @param data string Multiline input. May be binary (containing NUL bytes).
+--- Useful in mappings and scripts to insert multiline text. Example:
+---
+--- ```vim
+--- vim.keymap.set('n', 'x', function()
+--- vim.api.nvim_paste([[
+--- line1
+--- line2
+--- line3
+--- ]], false, -1)
+--- end, { buffer = true })
+--- ```
+---
+---
+--- @param data string Multiline input. Lines break at LF ("\n"). May be binary
+--- (containing NUL bytes).
--- @param crlf boolean Also break lines at CR and CRLF.
--- @param phase integer -1: paste in a single call (i.e. without streaming). To
--- "stream" a paste, call `nvim_paste` sequentially with these
@@ -1830,7 +1845,8 @@ function vim.api.nvim_parse_expression(expr, flags, highlight) end
--- @return boolean
function vim.api.nvim_paste(data, crlf, phase) end
---- Puts text at cursor, in any mode.
+--- Puts text at cursor, in any mode. For dot-repeatable input, use
+--- `nvim_paste()`.
---
--- Compare `:put` and `p` which are always linewise.
---
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 3baf8a97d9..9480292d9a 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -462,12 +462,8 @@ end:
/// = row` and `start_col = end_col = col`. To delete the text in a range, use
/// `replacement = {}`.
///
-/// Prefer |nvim_buf_set_lines()| if you are only adding or deleting entire lines.
-///
-/// Prefer |nvim_put()| if you want to insert text at the cursor position.
-///
-/// @see |nvim_buf_set_lines()|
-/// @see |nvim_put()|
+/// @note Prefer |nvim_buf_set_lines()| (for performance) to add or delete entire lines.
+/// @note Prefer |nvim_paste()| or |nvim_put()| to insert (instead of replace) text at cursor.
///
/// @param channel_id
/// @param buffer Buffer handle, or 0 for current buffer
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index b31accd3b0..ae649e55d6 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -344,9 +344,10 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_ks)
}
}
-/// Queues raw user-input. Unlike |nvim_feedkeys()|, this uses a low-level
-/// input buffer and the call is non-blocking (input is processed
-/// asynchronously by the eventloop).
+/// Queues raw user-input. Unlike |nvim_feedkeys()|, this uses a low-level input buffer and the call
+/// is non-blocking (input is processed asynchronously by the eventloop).
+///
+/// To input blocks of text, |nvim_paste()| is much faster and should be preferred.
///
/// On execution error: does not fail, but updates v:errmsg.
///
@@ -1212,17 +1213,30 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
}
}
-/// Pastes at cursor, in any mode.
+/// Pastes at cursor (in any mode), and sets "redo" so dot (|.|) will repeat the input. UIs call
+/// this to implement "paste", but it's also intended for use by scripts to input large,
+/// dot-repeatable blocks of text (as opposed to |nvim_input()| which is subject to mappings/events
+/// and is thus much slower).
+///
+/// Invokes the |vim.paste()| handler, which handles each mode appropriately.
+///
+/// Errors ('nomodifiable', `vim.paste()` failure, …) are reflected in `err` but do not affect the
+/// return value (which is strictly decided by `vim.paste()`). On error or cancel, subsequent calls
+/// are ignored ("drained") until the next paste is initiated (phase 1 or -1).
///
-/// Invokes the `vim.paste` handler, which handles each mode appropriately.
-/// Sets redo/undo. Faster than |nvim_input()|. Lines break at LF ("\n").
+/// Useful in mappings and scripts to insert multiline text. Example:
///
-/// Errors ('nomodifiable', `vim.paste()` failure, …) are reflected in `err`
-/// but do not affect the return value (which is strictly decided by
-/// `vim.paste()`). On error or cancel, subsequent calls are ignored
-/// ("drained") until the next paste is initiated (phase 1 or -1).
+/// ```vim
+/// vim.keymap.set('n', 'x', function()
+/// vim.api.nvim_paste([[
+/// line1
+/// line2
+/// line3
+/// ]], false, -1)
+/// end, { buffer = true })
+/// ```
///
-/// @param data Multiline input. May be binary (containing NUL bytes).
+/// @param data Multiline input. Lines break at LF ("\n"). May be binary (containing NUL bytes).
/// @param crlf Also break lines at CR and CRLF.
/// @param phase -1: paste in a single call (i.e. without streaming).
/// To "stream" a paste, call `nvim_paste` sequentially with
@@ -1276,7 +1290,7 @@ theend:
return retval;
}
-/// Puts text at cursor, in any mode.
+/// Puts text at cursor, in any mode. For dot-repeatable input, use |nvim_paste()|.
///
/// Compare |:put| and |p| which are always linewise.
///