diff options
Diffstat (limited to 'runtime/lua/vim/_editor.lua')
-rw-r--r-- | runtime/lua/vim/_editor.lua | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index c6aa303124..3167721a70 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -651,7 +651,7 @@ do end end -local on_key_cbs = {} --- @type table<integer,function> +local on_key_cbs = {} --- @type table<integer,[function, table]> --- Adds Lua function {fn} with namespace id {ns_id} as a listener to every, --- yes every, input key. @@ -664,34 +664,37 @@ local on_key_cbs = {} --- @type table<integer,function> --- it won't be invoked for those keys. ---@note {fn} will not be cleared by |nvim_buf_clear_namespace()| --- ----@param fn fun(key: string, typed: string)? Function invoked for every input key, +---@param fn nil|fun(key: string, typed: string): string? Function invoked for every input key, --- after mappings have been applied but before further processing. Arguments --- {key} and {typed} are raw keycodes, where {key} is the key after mappings --- are applied, and {typed} is the key(s) before mappings are applied. --- {typed} may be empty if {key} is produced by non-typed key(s) or by the --- same typed key(s) that produced a previous {key}. ---- When {fn} is `nil` and {ns_id} is specified, the callback associated with ---- namespace {ns_id} is removed. +--- If {fn} returns an empty string, {key} is discarded/ignored. +--- When {fn} is `nil`, the callback associated with namespace {ns_id} is removed. ---@param ns_id integer? Namespace ID. If nil or 0, generates and returns a --- new |nvim_create_namespace()| id. +---@param opts table? Optional parameters --- ---@see |keytrans()| --- ---@return integer Namespace id associated with {fn}. Or count of all callbacks ---if on_key() is called without arguments. -function vim.on_key(fn, ns_id) +function vim.on_key(fn, ns_id, opts) if fn == nil and ns_id == nil then return vim.tbl_count(on_key_cbs) end vim.validate('fn', fn, 'callable', true) vim.validate('ns_id', ns_id, 'number', true) + vim.validate('opts', opts, 'table', true) + opts = opts or {} if ns_id == nil or ns_id == 0 then ns_id = vim.api.nvim_create_namespace('') end - on_key_cbs[ns_id] = fn + on_key_cbs[ns_id] = fn and { fn, opts } return ns_id end @@ -700,12 +703,23 @@ end function vim._on_key(buf, typed_buf) local failed_ns_ids = {} local failed_messages = {} + local discard = false for k, v in pairs(on_key_cbs) do - local ok, err_msg = pcall(v, buf, typed_buf) + local ok, rv = pcall(v[1], buf, typed_buf) + if ok and rv ~= nil then + if type(rv) == 'string' and #rv == 0 then + discard = true + -- break -- Without break deliver to all callbacks even when it eventually discards. + -- "break" does not make sense unless callbacks are sorted by ???. + else + ok = false + rv = 'return string must be empty' + end + end if not ok then vim.on_key(nil, k) table.insert(failed_ns_ids, k) - table.insert(failed_messages, err_msg) + table.insert(failed_messages, rv) end end @@ -718,6 +732,7 @@ function vim._on_key(buf, typed_buf) ) ) end + return discard end --- Convert UTF-32, UTF-16 or UTF-8 {index} to byte index. |