aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
authorFamiu Haque <famiuhaque@protonmail.com>2022-04-20 17:02:18 +0600
committerFamiu Haque <famiuhaque@protonmail.com>2022-05-31 20:55:05 +0600
commit46536f53e82967dcac8d030ee3394cdb156f9603 (patch)
tree4444067831639a6a1eb1916ca9cd5002261932ec /runtime
parente9803e1de6497ee21f77f45cf2670c2fe4e8ab22 (diff)
downloadrneovim-46536f53e82967dcac8d030ee3394cdb156f9603.tar.gz
rneovim-46536f53e82967dcac8d030ee3394cdb156f9603.tar.bz2
rneovim-46536f53e82967dcac8d030ee3394cdb156f9603.zip
feat: add preview functionality to user commands
Adds a Lua-only `preview` flag to user commands which allows the command to be incrementally previewed like `:substitute` when 'inccommand' is set.
Diffstat (limited to 'runtime')
-rw-r--r--runtime/doc/api.txt2
-rw-r--r--runtime/doc/map.txt106
-rw-r--r--runtime/doc/options.txt10
-rw-r--r--runtime/doc/vim_diff.txt2
4 files changed, 116 insertions, 4 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index 965b8e6492..6c8c35486e 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -760,6 +760,8 @@ nvim_create_user_command({name}, {command}, {*opts})
when a Lua function is used for {command}.
• force: (boolean, default true) Override any
previous definition.
+ • preview: (function) Preview callback for
+ 'inccommand' |:command-preview|
nvim_del_current_line() *nvim_del_current_line()*
Deletes the current line.
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index 98da68b76a..9776304c8e 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -1430,6 +1430,112 @@ Possible values are (second column is the short name used in listing):
-addr=other ? other kind of range
+Incremental preview ~
+ *:command-preview* {nvim-api}
+Commands can show an 'inccommand' (as-you-type) preview by defining a preview
+handler (only from Lua, see |nvim_create_user_command()|).
+
+The preview callback must be a Lua function with this signature: >
+
+ function cmdpreview(opts, ns, buf)
+<
+where "opts" has the same form as that given to |nvim_create_user_command()|
+callbacks, "ns" is the preview namespace id for highlights, and "buf" is the
+buffer that your preview routine will directly modify to show the previewed
+results (for "inccommand=split", or nil for "inccommand=nosplit").
+
+Your command preview routine must implement this protocol:
+
+1. Modify the current buffer as required for the preview (see
+ |nvim_buf_set_text()| and |nvim_buf_set_lines()|).
+2. If preview buffer is provided, add necessary text to the preview buffer.
+3. Add required highlights to the current buffer. If preview buffer is
+ provided, add required highlights to the preview buffer as well. All
+ highlights must be added to the preview namespace which is provided as an
+ argument to the preview callback (see |nvim_buf_add_highlight()| and
+ |nvim_buf_set_extmark()| for help on how to add highlights to a namespace).
+4. Return an integer (0, 1, 2) which controls how Nvim behaves as follows:
+ 0: No preview is shown.
+ 1: Preview is shown without preview window (even with "inccommand=split").
+ 2: Preview is shown and preview window is opened (if "inccommand=split").
+ For "inccommand=nosplit" this is the same as 1.
+
+After preview ends, Nvim discards all changes to the buffer and all highlights
+in the preview namespace.
+
+Here's an example of a command to trim trailing whitespace from lines that
+supports incremental command preview:
+>
+ -- Trims trailing whitespace in the current buffer.
+ -- Also performs 'inccommand' preview if invoked as a preview callback
+ -- (preview_ns is non-nil).
+ local function trim_space(opts, preview_ns, preview_buf)
+ local line1 = opts.line1
+ local line2 = opts.line2
+ local buf = vim.api.nvim_get_current_buf()
+ local lines = vim.api.nvim_buf_get_lines(buf, line1 - 1, line2, 0)
+ local new_lines = {}
+ local preview_buf_line = 0
+
+ for i, line in ipairs(lines) do
+ local startidx, endidx = string.find(line, '%s+$')
+
+ if startidx ~= nil then
+ -- Highlight the match if in command preview mode
+ if preview_ns ~= nil then
+ vim.api.nvim_buf_add_highlight(
+ buf, preview_ns, 'Substitute', line1 + i - 2, startidx - 1,
+ endidx
+ )
+
+ -- Add lines and highlight to the preview buffer
+ -- if inccommand=split
+ if preview_buf ~= nil then
+ local prefix = string.format('|%d| ', line1 + i - 1)
+
+ vim.api.nvim_buf_set_lines(
+ preview_buf, preview_buf_line, preview_buf_line, 0,
+ { prefix .. line }
+ )
+ vim.api.nvim_buf_add_highlight(
+ preview_buf, preview_ns, 'Substitute', preview_buf_line,
+ #prefix + startidx - 1, #prefix + endidx
+ )
+
+ preview_buf_line = preview_buf_line + 1
+ end
+ end
+ end
+
+ if not preview_ns then
+ new_lines[#new_lines+1] = string.gsub(line, '%s+$', '')
+ end
+ end
+
+ -- Don't make any changes to the buffer if previewing
+ if not preview_ns then
+ vim.api.nvim_buf_set_lines(buf, line1 - 1, line2, 0, new_lines)
+ end
+
+ -- When called as a preview callback, return the value of the
+ -- preview type
+ if preview_ns ~= nil then
+ return 2
+ end
+ end
+
+ -- Create the user command
+ vim.api.nvim_create_user_command(
+ 'TrimTrailingWhitespace',
+ trim_space,
+ { nargs = '?', range = '%', addr = 'lines', preview = trim_space }
+ )
+<
+Note that in the above example, the same function is used as both the command
+callback and the preview callback, but you could instead use separate
+functions.
+
+
Special cases ~
*:command-bang* *:command-bar*
*:command-register* *:command-buffer*
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index a21d3bbce7..eebbc3f73a 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -3266,8 +3266,9 @@ A jump table for the options with a short description can be found at |Q_op|.
'inccommand' 'icm' string (default "nosplit")
global
- When nonempty, shows the effects of |:substitute|, |:smagic|, and
- |:snomagic| as you type.
+ When nonempty, shows the effects of |:substitute|, |:smagic|,
+ |:snomagic| and user commands with the |:command-preview| flag as you
+ type.
Possible values:
nosplit Shows the effects of a command incrementally in the
@@ -3275,8 +3276,9 @@ A jump table for the options with a short description can be found at |Q_op|.
split Like "nosplit", but also shows partial off-screen
results in a preview window.
- If the preview is too slow (exceeds 'redrawtime') then 'inccommand' is
- automatically disabled until |Command-line-mode| is done.
+ If the preview for built-in commands is too slow (exceeds
+ 'redrawtime') then 'inccommand' is automatically disabled until
+ |Command-line-mode| is done.
*'include'* *'inc'*
'include' 'inc' string (default "^\s*#\s*include")
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index c079b83c29..8e67cb0923 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -183,6 +183,7 @@ Commands:
|:sign-define| accepts a `numhl` argument, to highlight the line number
|:match| can be invoked before highlight group is defined
|:source| works with Lua and anonymous (no file) scripts
+ User commands can support |:command-preview| to show results as you type
Events:
|RecordingEnter|
@@ -235,6 +236,7 @@ Options:
"horizdown", "vertleft", "vertright", "verthoriz"
'foldcolumn' supports up to 9 dynamic/fixed columns
'inccommand' shows interactive results for |:substitute|-like commands
+ and |:command-preview| commands
'laststatus' global statusline support
'pumblend' pseudo-transparent popupmenu
'scrollback'