aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BSDmakefile4
-rw-r--r--CONTRIBUTING.md8
-rw-r--r--runtime/doc/deprecated.txt3
-rw-r--r--runtime/doc/develop.txt41
-rw-r--r--runtime/doc/lua.txt35
-rw-r--r--runtime/doc/starting.txt12
-rw-r--r--runtime/doc/vim_diff.txt24
-rw-r--r--src/nvim/getchar.c4
-rw-r--r--src/nvim/lua/executor.c12
-rw-r--r--src/nvim/lua/vim.lua51
-rw-r--r--src/nvim/main.c2
-rw-r--r--test/functional/api/server_notifications_spec.lua8
-rw-r--r--test/functional/lua/vim_spec.lua72
13 files changed, 140 insertions, 136 deletions
diff --git a/BSDmakefile b/BSDmakefile
index 93b7dc7f3d..f81223bafa 100644
--- a/BSDmakefile
+++ b/BSDmakefile
@@ -1,4 +1,4 @@
.DONE:
- @echo "Please use GNU Make (gmake) to build neovim"
+ @echo "Use GNU Make (gmake) to build neovim"
.DEFAULT:
- @echo "Please use GNU Make (gmake) to build neovim"
+ @echo "Use GNU Make (gmake) to build neovim"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4d93c979ed..2a565574fa 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -29,10 +29,10 @@ Reporting problems
Developer guidelines
--------------------
-- Nvim developers should read `:help dev`.
-- External UI developers should read `:help dev-ui`.
-- API client developers should read `:help dev-api-client`.
-- Nvim developers are _strongly encouraged_ to install `ninja` for faster builds.
+- Read `:help dev` if you are working on Nvim core.
+- Read `:help dev-ui` if you are developing a UI.
+- Read `:help dev-api-client` if you are developing an API client.
+- Install `ninja` for faster builds of Nvim.
```
sudo apt-get install ninja-build
make distclean
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt
index 3b5287ee44..861aed4884 100644
--- a/runtime/doc/deprecated.txt
+++ b/runtime/doc/deprecated.txt
@@ -14,6 +14,7 @@ updated.
API ~
*nvim_buf_clear_highlight()* Use |nvim_buf_clear_namespace()| instead.
+*nvim_buf_set_virtual_text()* Use |nvim_buf_set_extmark()| instead.
*nvim_command_output()* Use |nvim_exec()| instead.
*nvim_execute_lua()* Use |nvim_exec_lua()| instead.
@@ -54,6 +55,8 @@ Functions ~
without stopping the job. Use chanclose(id) to close
any socket.
+Lua ~
+*vim.register_keystroke_callback()* Use |vim.on_key()| instead.
Modifiers ~
*cpo-<*
diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt
index 60a3f870a9..14f35acce3 100644
--- a/runtime/doc/develop.txt
+++ b/runtime/doc/develop.txt
@@ -127,14 +127,20 @@ Sometimes a GUI or other application may want to force a provider to
DOCUMENTATION *dev-doc*
-- Do not prefix help tags with "nvim-". Use |vim_diff.txt| to document
- differences from Vim; no other distinction is necessary.
-- If a Vim feature is removed, delete its help section and move its tag to
- |vim_diff.txt|.
-- Move deprecated features to |deprecated.txt|.
+- "Just say it". Avoid mushy, colloquial phrasing in all documentation
+ (docstrings, user manual, website materials, newsletters, …). Don't mince
+ words. Personality and flavor, used sparingly, are welcome--but in general,
+ optimize for the reader's time and energy: be "precise yet concise".
+ - Prefer the active voice: "Foo does X", not "X is done by Foo".
+- Vim differences:
+ - Do not prefix help tags with "nvim-". Use |vim_diff.txt| to catalog
+ differences from Vim; no other distinction is necessary.
+ - If a Vim feature is removed, delete its help section and move its tag to
+ |vim_diff.txt|.
+- Mention deprecated features in |deprecated.txt| and delete their old doc.
- Use consistent language.
- - "terminal" in a help tag always means "the embedded terminal emulator", not
- "the user host terminal".
+ - "terminal" in a help tag always means "the embedded terminal emulator",
+ not "the user host terminal".
- Use "tui-" to prefix help tags related to the host terminal, and "TUI"
in prose if possible.
- Docstrings: do not start parameter descriptions with "The" or "A" unless it
@@ -222,13 +228,13 @@ 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.
+ want to learn a big, fancy inheritance hierarchy. Thus avoid specialized
+ objects; tables or values are usually better.
API *dev-api*
-Use this template to name new API functions:
+Use this template to name new RPC |API| functions:
nvim_{thing}_{action}_{arbitrary-qualifiers}
If the function acts on an object then {thing} is the name of that object
@@ -356,4 +362,19 @@ External UIs are expected to implement these common features:
published in this event. See also "mouse_on", "mouse_off".
+NAMING *dev-naming*
+
+Naming is important. Consistent naming in the API and UI helps both users and
+developers discover and intuitively understand related concepts ("families"),
+and reduces cognitive burden. Discoverability encourages code re-use and
+likewise avoids redundant, overlapping mechanisms, which reduces code
+surface-area, and thereby minimizes bugs...
+
+Naming conventions ~
+
+Use the "on_" prefix to name event handlers and also the interface for
+"registering" such handlers (on_key). The dual nature is acceptable to avoid
+a confused collection of naming conventions for these related concepts.
+
+
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index a44b2e42f5..5d600eae99 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -576,11 +576,11 @@ If you want to exclude visual selections from highlighting on yank, use
vim.highlight.on_yank({opts}) *vim.highlight.on_yank()*
Highlights the yanked text. The fields of the optional dict {opts}
control the highlight:
- - {higroup} highlight group for yanked region (default `"IncSearch"`)
+ - {higroup} highlight group for yanked region (default |hl-IncSearch|)
- {timeout} time in ms before highlight is cleared (default `150`)
- {on_macro} highlight when executing macro (default `false`)
- {on_visual} highlight when yanking visual selection (default `true`)
- - {event} event structure (default `vim.v.event`)
+ - {event} event structure (default |v:event|)
vim.highlight.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {rtype}, {inclusive})
*vim.highlight.range()*
@@ -1243,37 +1243,6 @@ region({bufnr}, {pos1}, {pos2}, {regtype}, {inclusive}) *vim.region()*
Return: ~
region lua table of the form {linenr = {startcol,endcol}}
- *vim.register_keystroke_callback()*
-register_keystroke_callback({fn}, {ns_id})
- Register a lua {fn} with an {id} to be run after every
- keystroke.
-
- If {fn} is nil, it removes the callback for the associated
- {ns_id}
- Note:
- {fn} will not be cleared from |nvim_buf_clear_namespace()|
-
- Note:
- {fn} will receive the keystrokes after mappings have been
- evaluated
-
- Parameters: ~
- {fn} function: Function to call. It should take one
- argument, which is a string. The string will contain
- the literal keys typed. See |i_CTRL-V|
- {ns_id} number? Namespace ID. If not passed or 0, will
- generate and return a new namespace ID from
- |nvim_create_namesapce()|
-
- Return: ~
- number Namespace ID associated with {fn}
-
- Note:
- {fn} will be automatically removed if an error occurs
- while calling. This is to prevent the annoying situation
- of every keystroke erroring while trying to remove a
- broken callback.
-
schedule_wrap({cb}) *vim.schedule_wrap()*
Defers callback `cb` until the Nvim API is safe to call.
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index d6b54fbd01..87a48e6d2a 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -329,12 +329,12 @@ argument.
-w{number} Set the 'window' option to {number}.
*-w*
--w {scriptout} All the characters that you type are recorded in the file
- "scriptout", until you exit Vim. This is useful if you want
- to create a script file to be used with "vim -s" or
- ":source!". When the "scriptout" file already exists, new
- characters are appended. See also |complex-repeat|.
- {scriptout} cannot start with a digit.
+-w {scriptout} All keys that you type are recorded in the file "scriptout",
+ until you exit Vim. Useful to create a script file to be used
+ with "vim -s" or ":source!". Appends to the "scriptout" file
+ if it already exists. {scriptout} cannot start with a digit.
+ See also |vim.on_key()|.
+ See also |complex-repeat|.
*-W*
-W {scriptout} Like -w, but do not append, overwrite an existing file.
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 4b134926a2..a5fcef2800 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -6,16 +6,16 @@
Differences between Nvim and Vim *vim-differences*
-Nvim differs from Vim in many ways, although editor and VimL features are
-mostly identical. This document is a complete and centralized reference of
-the differences.
+Nvim differs from Vim in many ways, although editor and Vimscript (not
+Vim9script) features are mostly identical. This document is a complete and
+centralized reference of the differences.
Type |gO| to see the table of contents.
==============================================================================
1. Configuration *nvim-config*
-- Use `$XDG_CONFIG_HOME/nvim/init.vim` instead of `.vimrc` for configuration.
+- Use `$XDG_CONFIG_HOME/nvim/init.vim` instead of `.vimrc` for your |config|.
- Use `$XDG_CONFIG_HOME/nvim` instead of `.vim` to store configuration files.
- Use `$XDG_DATA_HOME/nvim/shada/main.shada` instead of `.viminfo` for persistent
session information. |shada|
@@ -78,6 +78,8 @@ the differences.
Default Mappings ~
*default-mappings*
+Nvim creates the following default mappings at |startup|. You can disable any
+of these in your config by simply removing the mapping, e.g. ":unmap Y".
>
nnoremap Y y$
nnoremap <C-L> <Cmd>nohlsearch<Bar>diffupdate<CR><C-L>
@@ -101,17 +103,19 @@ nvim_cmdwin:
MAJOR COMPONENTS ~
API |API|
-Lua scripting |lua|
Job control |job-control|
-Remote plugins |remote-plugin|
+LSP framework |lsp|
+Lua scripting |lua|
+Parsing engine |treesitter|
Providers
Clipboard |provider-clipboard|
Node.js plugins |provider-nodejs|
Python plugins |provider-python|
Ruby plugins |provider-ruby|
+Remote plugins |remote-plugin|
Shared data |shada|
-Embedded terminal |terminal|
-VimL parser |nvim_parse_expression()|
+Terminal emulator |terminal|
+Vimscript parser |nvim_parse_expression()|
XDG base directories |xdg|
USER EXPERIENCE ~
@@ -160,7 +164,7 @@ FEATURES ~
Command-line highlighting:
The expression prompt (|@=|, |c_CTRL-R_=|, |i_CTRL-R_=|) is highlighted
- using a built-in VimL expression parser. |expr-highlight|
+ using a built-in Vimscript expression parser. |expr-highlight|
*E5408* *E5409*
|input()|, |inputdialog()| support custom highlighting. |input()-highlight|
*g:Nvim_color_cmdline*
@@ -413,7 +417,7 @@ TUI:
UI/Display:
|Visual| selection highlights the character at cursor. |visual-use|
-VimL (Vim script) compatibility:
+Vimscript compatibility:
`count` does not alias to |v:count|
`errmsg` does not alias to |v:errmsg|
`shell_error` does not alias to |v:shell_error|
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 28f58e2c34..11e3b9bc2d 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -1563,8 +1563,8 @@ int vgetc(void)
*/
may_garbage_collect = false;
- // Exec lua callbacks for on_keystroke
- nlua_execute_log_keystroke(c);
+ // Execute Lua on_key callbacks.
+ nlua_execute_on_key(c);
return c;
}
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 5cd9894f9d..a8b10f86f5 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -1499,7 +1499,7 @@ int nlua_expand_pat(expand_T *xp,
lua_getfield(lstate, -1, "_expand_pat");
luaL_checktype(lstate, -1, LUA_TFUNCTION);
- // [ vim, vim._log_keystroke, buf ]
+ // [ vim, vim._on_key, buf ]
lua_pushlstring(lstate, (const char *)pat, STRLEN(pat));
if (lua_pcall(lstate, 1, 2, 0) != 0) {
@@ -1773,7 +1773,7 @@ char_u *nlua_register_table_as_callable(typval_T *const arg)
return name;
}
-void nlua_execute_log_keystroke(int c)
+void nlua_execute_on_key(int c)
{
char_u buf[NUMBUFLEN];
size_t buf_len = special_to_buf(c, mod_mask, false, buf);
@@ -1787,17 +1787,17 @@ void nlua_execute_log_keystroke(int c)
// [ vim ]
lua_getglobal(lstate, "vim");
- // [ vim, vim._log_keystroke ]
- lua_getfield(lstate, -1, "_log_keystroke");
+ // [ vim, vim._on_key]
+ lua_getfield(lstate, -1, "_on_key");
luaL_checktype(lstate, -1, LUA_TFUNCTION);
- // [ vim, vim._log_keystroke, buf ]
+ // [ vim, vim._on_key, buf ]
lua_pushlstring(lstate, (const char *)buf, buf_len);
if (lua_pcall(lstate, 1, 0, 0)) {
nlua_error(
lstate,
- _("Error executing vim.log_keystroke lua callback: %.*s"));
+ _("Error executing vim.on_key Lua callback: %.*s"));
}
// [ vim ]
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
index 34b314b40d..c6bbdee7ad 100644
--- a/src/nvim/lua/vim.lua
+++ b/src/nvim/lua/vim.lua
@@ -4,6 +4,7 @@
-- 1. runtime/lua/vim/ (the runtime): For "nice to have" features, e.g. the
-- `inspect` and `lpeg` modules.
-- 2. runtime/lua/vim/shared.lua: Code shared between Nvim and tests.
+-- (This will go away if we migrate to nvim as the test-runner.)
-- 3. src/nvim/lua/: Compiled-into Nvim itself.
--
-- Guideline: "If in doubt, put it in the runtime".
@@ -426,26 +427,35 @@ function vim.notify(msg, log_level, _opts)
end
-local on_keystroke_callbacks = {}
+function vim.register_keystroke_callback()
+ error('vim.register_keystroke_callback is deprecated, instead use: vim.on_key')
+end
+
+local on_key_cbs = {}
---- Register a lua {fn} with an {id} to be run after every keystroke.
+--- Adds Lua function {fn} with namespace id {ns_id} as a listener to every,
+--- yes every, input key.
---
----@param fn function: Function to call. It should take one argument, which is a string.
---- The string will contain the literal keys typed.
---- See |i_CTRL-V|
+--- The Nvim command-line option |-w| is related but does not support callbacks
+--- and cannot be toggled dynamically.
---
+---@param fn function: Callback function. It should take one string argument.
+--- On each key press, Nvim passes the key char to fn(). |i_CTRL-V|
--- If {fn} is nil, it removes the callback for the associated {ns_id}
----@param ns_id number? Namespace ID. If not passed or 0, will generate and return a new
---- namespace ID from |nvim_create_namesapce()|
+---@param ns_id number? Namespace ID. If nil or 0, generates and returns a new
+--- |nvim_create_namesapce()| id.
---
----@return number Namespace ID associated with {fn}
+---@return number Namespace id associated with {fn}. Or count of all callbacks
+---if on_key() is called without arguments.
---
----@note {fn} will be automatically removed if an error occurs while calling.
---- This is to prevent the annoying situation of every keystroke erroring
---- while trying to remove a broken callback.
----@note {fn} will not be cleared from |nvim_buf_clear_namespace()|
----@note {fn} will receive the keystrokes after mappings have been evaluated
-function vim.register_keystroke_callback(fn, ns_id)
+---@note {fn} will be removed if an error occurs while calling.
+---@note {fn} will not be cleared by |nvim_buf_clear_namespace()|
+---@note {fn} will receive the keys after mappings have been evaluated
+function vim.on_key(fn, ns_id)
+ if fn == nil and ns_id == nil then
+ return #on_key_cbs
+ end
+
vim.validate {
fn = { fn, 'c', true},
ns_id = { ns_id, 'n', true }
@@ -455,20 +465,19 @@ function vim.register_keystroke_callback(fn, ns_id)
ns_id = vim.api.nvim_create_namespace('')
end
- on_keystroke_callbacks[ns_id] = fn
+ on_key_cbs[ns_id] = fn
return ns_id
end
---- Function that executes the keystroke callbacks.
+--- Executes the on_key callbacks.
---@private
-function vim._log_keystroke(char)
+function vim._on_key(char)
local failed_ns_ids = {}
local failed_messages = {}
- for k, v in pairs(on_keystroke_callbacks) do
+ for k, v in pairs(on_key_cbs) do
local ok, err_msg = pcall(v, char)
if not ok then
- vim.register_keystroke_callback(nil, k)
-
+ vim.on_key(nil, k)
table.insert(failed_ns_ids, k)
table.insert(failed_messages, err_msg)
end
@@ -476,7 +485,7 @@ function vim._log_keystroke(char)
if failed_ns_ids[1] then
error(string.format(
- "Error executing 'on_keystroke' with ns_ids of '%s'\n With messages: %s",
+ "Error executing 'on_key' with ns_ids '%s'\n Messages: %s",
table.concat(failed_ns_ids, ", "),
table.concat(failed_messages, "\n")))
end
diff --git a/src/nvim/main.c b/src/nvim/main.c
index b73f5aad76..716434f32e 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -334,7 +334,7 @@ int main(int argc, char **argv)
// prepare screen now, so external UIs can display messages
starting = NO_BUFFERS;
screenclear();
- TIME_MSG("initialized screen early for UI");
+ TIME_MSG("init screen for UI");
}
init_default_mappings(); // Default mappings.
diff --git a/test/functional/api/server_notifications_spec.lua b/test/functional/api/server_notifications_spec.lua
index 279ede81f7..6367cc5caa 100644
--- a/test/functional/api/server_notifications_spec.lua
+++ b/test/functional/api/server_notifications_spec.lua
@@ -78,10 +78,10 @@ describe('notify', function()
end)
it('cancels stale events on channel close', function()
- if isCI() then
- pending('Sporadic hangs on CI (c.f., #14083). Skip until it is fixed.')
- return
- end
+ if isCI() then
+ pending('hangs on CI #14083 #15251')
+ return
+ end
if helpers.pending_win32(pending) then return end
local catchan = eval("jobstart(['cat'], {'rpc': v:true})")
local catpath = eval('exepath("cat")')
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 0ea914880f..2bedbd1453 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -6,6 +6,7 @@ local funcs = helpers.funcs
local meths = helpers.meths
local dedent = helpers.dedent
local command = helpers.command
+local insert = helpers.insert
local clear = helpers.clear
local eq = helpers.eq
local ok = helpers.ok
@@ -1881,7 +1882,7 @@ describe('lua stdlib', function()
end)
it('vim.region', function()
- helpers.insert(helpers.dedent( [[
+ insert(helpers.dedent( [[
text tααt tααt text
text tαxt txtα tex
text tαxt tαxt
@@ -1889,65 +1890,67 @@ describe('lua stdlib', function()
eq({5,15}, exec_lua[[ return vim.region(0,{1,5},{1,14},'v',true)[1] ]])
end)
- describe('vim.execute_on_keystroke', function()
- it('should keep track of keystrokes', function()
- helpers.insert([[hello world ]])
+ describe('vim.on_key', function()
+ it('tracks keystrokes', function()
+ insert([[hello world ]])
exec_lua [[
- KeysPressed = {}
+ keys = {}
- vim.register_keystroke_callback(function(buf)
+ vim.on_key(function(buf)
if buf:byte() == 27 then
buf = "<ESC>"
end
- table.insert(KeysPressed, buf)
+ table.insert(keys, buf)
end)
]]
- helpers.insert([[next 🤦 lines å ]])
+ insert([[next 🤦 lines å ]])
-- It has escape in the keys pressed
- eq('inext 🤦 lines å <ESC>', exec_lua [[return table.concat(KeysPressed, '')]])
+ eq('inext 🤦 lines å <ESC>', exec_lua [[return table.concat(keys, '')]])
end)
- it('should allow removing trackers.', function()
- helpers.insert([[hello world]])
+ it('allows removing on_key listeners', function()
+ insert([[hello world]])
exec_lua [[
- KeysPressed = {}
+ keys = {}
- return vim.register_keystroke_callback(function(buf)
+ return vim.on_key(function(buf)
if buf:byte() == 27 then
buf = "<ESC>"
end
- table.insert(KeysPressed, buf)
+ table.insert(keys, buf)
end, vim.api.nvim_create_namespace("logger"))
]]
- helpers.insert([[next lines]])
+ insert([[next lines]])
- exec_lua("vim.register_keystroke_callback(nil, vim.api.nvim_create_namespace('logger'))")
+ eq(1, exec_lua('return vim.on_key()'))
+ exec_lua("vim.on_key(nil, vim.api.nvim_create_namespace('logger'))")
+ eq(0, exec_lua('return vim.on_key()'))
- helpers.insert([[more lines]])
+ insert([[more lines]])
-- It has escape in the keys pressed
- eq('inext lines<ESC>', exec_lua [[return table.concat(KeysPressed, '')]])
+ eq('inext lines<ESC>', exec_lua [[return table.concat(keys, '')]])
end)
- it('should not call functions that error again.', function()
- helpers.insert([[hello world]])
+ it('skips any function that caused an error', function()
+ insert([[hello world]])
exec_lua [[
- KeysPressed = {}
+ keys = {}
- return vim.register_keystroke_callback(function(buf)
+ return vim.on_key(function(buf)
if buf:byte() == 27 then
buf = "<ESC>"
end
- table.insert(KeysPressed, buf)
+ table.insert(keys, buf)
if buf == 'l' then
error("Dumb Error")
@@ -1955,35 +1958,30 @@ describe('lua stdlib', function()
end)
]]
- helpers.insert([[next lines]])
- helpers.insert([[more lines]])
+ insert([[next lines]])
+ insert([[more lines]])
-- Only the first letter gets added. After that we remove the callback
- eq('inext l', exec_lua [[ return table.concat(KeysPressed, '') ]])
+ eq('inext l', exec_lua [[ return table.concat(keys, '') ]])
end)
- it('should process mapped keys, not unmapped keys', function()
+ it('processes mapped keys, not unmapped keys', function()
exec_lua [[
- KeysPressed = {}
+ keys = {}
vim.cmd("inoremap hello world")
- vim.register_keystroke_callback(function(buf)
+ vim.on_key(function(buf)
if buf:byte() == 27 then
buf = "<ESC>"
end
- table.insert(KeysPressed, buf)
+ table.insert(keys, buf)
end)
]]
+ insert("hello")
- helpers.insert("hello")
-
- local next_status = exec_lua [[
- return table.concat(KeysPressed, '')
- ]]
-
- eq("iworld<ESC>", next_status)
+ eq('iworld<ESC>', exec_lua[[return table.concat(keys, '')]])
end)
end)