From c5b34fa55483d84d1de32937ffff0b7cf1aeba78 Mon Sep 17 00:00:00 2001 From: glacambre Date: Sat, 11 Feb 2023 09:45:11 +0100 Subject: refactor: move init_default_autocmds to lua The original motivation for this change came from developping https://github.com/neovim/neovim/pull/22159, which will require adding more autocommand creation to Neovim's startup sequence. This change requires lightly editing a test that expected no autocommand to have been created from lua. --- runtime/lua/vim/_editor.lua | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index da8764fbd4..3f27e61810 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -894,6 +894,26 @@ function vim._init_default_mappings() ]]) end +function vim._init_default_autocmds() + local nvim_terminal_augroup = vim.api.nvim_create_augroup('nvim_terminal', {}) + vim.api.nvim_create_autocmd({ 'bufreadcmd' }, { + pattern = 'term://*', + group = nvim_terminal_augroup, + nested = true, + command = "if !exists('b:term_title')|call termopen(matchstr(expand(\"\"), '\\c\\mterm://\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), {'cwd': expand(get(matchlist(expand(\"\"), '\\c\\mterm://\\(.\\{-}\\)//'), 1, ''))})", + }) + vim.api.nvim_create_autocmd({ 'cmdwinenter' }, { + pattern = '[:>]', + group = vim.api.nvim_create_augroup('nvim_cmdwin', {}), + command = 'syntax sync minlines=1 maxlines=1', + }) +end + +function vim._init_defaults() + vim._init_default_mappings() + vim._init_default_autocmds() +end + require('vim._meta') return vim -- cgit From 5732aa706c639b3d775573d91d1139f24624629c Mon Sep 17 00:00:00 2001 From: Jon Huhn Date: Sat, 25 Feb 2023 03:07:18 -0600 Subject: feat(lsp): implement workspace/didChangeWatchedFiles (#21293) --- runtime/lua/vim/_editor.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 3f27e61810..92444ff550 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -37,6 +37,7 @@ for k, v in pairs({ health = true, fs = true, secure = true, + _watch = true, }) do vim._submodules[k] = v end -- cgit From f0f27e9aef7c237dd55fbb5c2cd47c2f42d01742 Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Sat, 25 Feb 2023 11:17:28 +0100 Subject: Revert "feat(lsp): implement workspace/didChangeWatchedFiles (#21293)" This reverts commit 5732aa706c639b3d775573d91d1139f24624629c. Causes editor to freeze in projects with many watcher registrations --- runtime/lua/vim/_editor.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 92444ff550..3f27e61810 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -37,7 +37,6 @@ for k, v in pairs({ health = true, fs = true, secure = true, - _watch = true, }) do vim._submodules[k] = v end -- cgit From aa16590999a66798eca7d2ba09e971aacdeb54b4 Mon Sep 17 00:00:00 2001 From: Jaehwang Jung Date: Sat, 4 Mar 2023 22:07:39 +0900 Subject: docs(lua): number → integer (#22517) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- runtime/lua/vim/_editor.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 3f27e61810..ab49e26dde 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -386,7 +386,7 @@ end --- Get a table of lines with start, end columns for a region marked by two points --- ----@param bufnr number of buffer +---@param bufnr integer number of buffer ---@param pos1 integer[] (line, column) tuple marking beginning of region ---@param pos2 integer[] (line, column) tuple marking end of region ---@param regtype string type of selection, see |setreg()| @@ -471,7 +471,7 @@ end --- writes to |:messages|. --- ---@param msg string Content of the notification to show to the user. ----@param level number|nil One of the values from |vim.log.levels|. +---@param level integer|nil One of the values from |vim.log.levels|. ---@param opts table|nil Optional parameters. Unused by default. function vim.notify(msg, level, opts) -- luacheck: no unused args if level == vim.log.levels.ERROR then @@ -492,7 +492,7 @@ do --- display a notification. --- ---@param msg string Content of the notification to show to the user. - ---@param level number|nil One of the values from |vim.log.levels|. + ---@param level integer|nil One of the values from |vim.log.levels|. ---@param opts table|nil Optional parameters. Unused by default. ---@return boolean true if message was displayed, else false function vim.notify_once(msg, level, opts) @@ -521,10 +521,10 @@ local on_key_cbs = {} ---@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 nil or 0, generates and returns a new +---@param ns_id integer? Namespace ID. If nil or 0, generates and returns a new --- |nvim_create_namespace()| id. --- ----@return number Namespace id associated with {fn}. Or count of all callbacks +---@return integer Namespace id associated with {fn}. Or count of all callbacks ---if on_key() is called without arguments. --- ---@note {fn} will be removed if an error occurs while calling. -- cgit From ac69ba5fa0081026f2c5e6e29d5788802479b7b9 Mon Sep 17 00:00:00 2001 From: Jon Huhn Date: Sun, 5 Mar 2023 00:52:27 -0600 Subject: feat(lsp): implement workspace/didChangeWatchedFiles (#22405) --- runtime/lua/vim/_editor.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index ab49e26dde..c205451ff9 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -37,6 +37,7 @@ for k, v in pairs({ health = true, fs = true, secure = true, + _watch = true, }) do vim._submodules[k] = v end -- cgit From 79571b92ced968ad27bee2a7515a4a04e84dbad2 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Wed, 27 Jan 2021 09:00:28 +0100 Subject: feat(lua): omnifunc for builting lua interpreter also make implicit submodules "uri" and "_inspector" work with completion this is needed for `:lua=vim.uri_` wildmenu completion to work even before uri or _inspector functions are used. --- runtime/lua/vim/_editor.lua | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index c205451ff9..9516233b45 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -42,6 +42,18 @@ for k, v in pairs({ vim._submodules[k] = v end +-- There are things which have special rules in vim._init_packages +-- for legacy reasons (uri) or for performance (_inspector). +-- most new things should go into a submodule namespace ( vim.foobar.do_thing() ) +vim._extra = { + uri_from_fname = true, + uri_from_bufnr = true, + uri_to_fname = true, + uri_to_bufnr = true, + show_pos = true, + inspect_pos = true, +} + vim.log = { levels = { TRACE = 0, @@ -575,15 +587,13 @@ function vim._on_key(char) end --- Generate a list of possible completions for the string. ---- String starts with ^ and then has the pattern. +--- String has the pattern. --- --- 1. Can we get it to just return things in the global namespace with that name prefix --- 2. Can we get it to return things from global namespace even with `print(` in front. function vim._expand_pat(pat, env) env = env or _G - pat = string.sub(pat, 2, #pat) - if pat == '' then local result = vim.tbl_keys(env) table.sort(result) @@ -644,7 +654,7 @@ function vim._expand_pat(pat, env) local mt = getmetatable(final_env) if mt and type(mt.__index) == 'table' then field = rawget(mt.__index, key) - elseif final_env == vim and vim._submodules[key] then + elseif final_env == vim and (vim._submodules[key] or vim._extra[key]) then field = vim[key] end end @@ -674,6 +684,7 @@ function vim._expand_pat(pat, env) end if final_env == vim then insert_keys(vim._submodules) + insert_keys(vim._extra) end keys = vim.tbl_keys(keys) @@ -745,6 +756,28 @@ vim._expand_pat_get_parts = function(lua_string) return parts, search_index end +do + -- Ideally we should just call complete() inside omnifunc, though there are + -- some bugs, so fake the two-step dance for now. + local matches + + --- Omnifunc for completing lua values from from the runtime lua interpreter, + --- similar to the builtin completion for the `:lua` command. + --- + --- Activate using `set omnifunc=v:lua.vim.lua_omnifunc` in a lua buffer. + function vim.lua_omnifunc(find_start, _) + if find_start == 1 then + local line = vim.api.nvim_get_current_line() + local prefix = string.sub(line, 1, vim.api.nvim_win_get_cursor(0)[2]) + local pos + matches, pos = vim._expand_pat(prefix) + return (#matches > 0 and pos) or -1 + else + return matches + end + end +end + ---Prints given arguments in human-readable format. ---Example: ---
lua
-- 
cgit 


From 673d2b52fa4335aa083c52e6686f0728e25b8ebd Mon Sep 17 00:00:00 2001
From: "Justin M. Keyes" 
Date: Tue, 7 Mar 2023 16:04:57 +0100
Subject: refactor!: rename vim.pretty_print => vim.print

Problem:
The function name `vim.pretty_print`:
1. is verbose, which partially defeats its purpose as sugar
2. does not draw from existing precedent or any sort of convention
   (except external projects like penlight or python?), which reduces
   discoverability, and degrades signaling about best practices.

Solution:
- Rename to `vim.print`.
- Change the behavior so that
  1. strings are printed without quotes
  2. each arg is printed on its own line
  3. tables are indented with 2 instead of 4 spaces
- Example:
  :lua ='a', 'b', 42, {a=3}
  a
  b
  42
  {
    a = 3
  }

Comparison of alternatives:
- `vim.print`:
  - pro: consistent with Lua's `print()`
  - pro: aligns with potential `nvim_print` API function which will
    replace nvim_echo, nvim_notify, etc.
  - con: behaves differently than Lua's `print()`, slightly misleading?
- `vim.echo`:
  - pro: `:echo` has similar "pretty print" behavior.
  - con: inconsistent with Lua idioms.
- `vim.p`:
  - pro: very short, fits with `vim.o`, etc.
  - con: not as discoverable as "echo"
  - con: less opportunity for `local p = vim.p` because of potential shadowing.
---
 runtime/lua/vim/_editor.lua | 39 +++++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 12 deletions(-)

(limited to 'runtime/lua/vim/_editor.lua')

diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index 9516233b45..5445c4e492 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -778,22 +778,37 @@ do
   end
 end
 
----Prints given arguments in human-readable format.
----Example:
----
lua
----  -- Print highlight group Normal and store it's contents in a variable.
----  local hl_normal = vim.pretty_print(vim.api.nvim_get_hl_by_name("Normal", true))
----
----@see |vim.inspect()| ----@return any # given arguments. +---@private function vim.pretty_print(...) - local objects = {} + vim.deprecate('vim.pretty_print', 'vim.print', '0.10') + return vim.print(...) +end + +--- "Pretty prints" the given arguments and returns them unmodified. +--- +--- Example: +---
lua
+---   local hl_normal = vim.print(vim.api.nvim_get_hl_by_name('Normal', true))
+--- 
+--- +--- @see |vim.inspect()| +--- @return any # given arguments. +function vim.print(...) + if vim.in_fast_event() then + print(...) + return ... + end + for i = 1, select('#', ...) do - local v = select(i, ...) - table.insert(objects, vim.inspect(v)) + local o = select(i, ...) + if type(o) == 'string' then + vim.api.nvim_out_write(o) + else + vim.api.nvim_out_write(vim.inspect(o, { newline = '\n', indent = ' ' })) + end + vim.api.nvim_out_write('\n') end - print(table.concat(objects, ' ')) return ... end -- cgit From 210120dde81ec289ae01e1d247df08f0b147c08a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 15 Mar 2023 08:56:13 -0400 Subject: fix(lua): vim.deprecate() shows ":help deprecated" #22677 Problem: vim.deprecate() shows ":help deprecated" for third-party plugins. ":help deprecated" only describes deprecations in Nvim, and is unrelated to any 3rd party deprecations. Solution: If `plugin` is specified, don't show ":help deprecated". fix #22235 --- runtime/lua/vim/_editor.lua | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 5445c4e492..f2875e5646 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -518,11 +518,6 @@ do end end ----@private -function vim.register_keystroke_callback() - error('vim.register_keystroke_callback is deprecated, instead use: vim.on_key') -end - local on_key_cbs = {} --- Adds Lua function {fn} with namespace id {ns_id} as a listener to every, @@ -882,27 +877,33 @@ function vim._cs_remote(rcid, server_addr, connect_error, args) } end ---- Display a deprecation notification to the user. +--- Shows a deprecation message to the user. --- ----@param name string Deprecated function. ----@param alternative string|nil Preferred alternative function. ----@param version string Version in which the deprecated function will ---- be removed. ----@param plugin string|nil Plugin name that the function will be removed ---- from. Defaults to "Nvim". +---@param name string Deprecated feature (function, API, etc.). +---@param alternative string|nil Suggested alternative feature. +---@param version string Version when the deprecated function will be removed. +---@param plugin string|nil Name of the plugin that owns the deprecated feature. +--- Defaults to "Nvim". ---@param backtrace boolean|nil Prints backtrace. Defaults to true. +--- +---@returns Deprecated message, or nil if no message was shown. function vim.deprecate(name, alternative, version, plugin, backtrace) - local message = name .. ' is deprecated' + local msg = ('%s is deprecated'):format(name) plugin = plugin or 'Nvim' - message = alternative and (message .. ', use ' .. alternative .. ' instead.') or message - message = message - .. ' See :h deprecated\nThis function will be removed in ' - .. plugin - .. ' version ' - .. version - if vim.notify_once(message, vim.log.levels.WARN) and backtrace ~= false then + msg = alternative and ('%s, use %s instead.'):format(msg, alternative) or msg + msg = ('%s%s\nThis feature will be removed in %s version %s'):format( + msg, + (plugin == 'Nvim' and ' :help deprecated' or ''), + plugin, + version + ) + local displayed = vim.notify_once(msg, vim.log.levels.WARN) + if displayed and backtrace ~= false then vim.notify(debug.traceback('', 2):sub(2), vim.log.levels.WARN) end + if displayed then + return msg + end end --- Create builtin mappings (incl. menus). -- cgit From 42876ddc7ad7d3dac3e1caf2494f402e7eb25a88 Mon Sep 17 00:00:00 2001 From: Jakub Łuczyński Date: Sat, 25 Mar 2023 09:28:59 +0100 Subject: docs: more details about vim.region (#21116) --- runtime/lua/vim/_editor.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index f2875e5646..fd6a5865ce 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -397,14 +397,17 @@ do vim.t = make_dict_accessor('t') end ---- Get a table of lines with start, end columns for a region marked by two points +--- Get a table of lines with start, end columns for a region marked by two points. +--- Input and output positions are (0,0)-indexed and indicate byte positions. --- ---@param bufnr integer number of buffer ---@param pos1 integer[] (line, column) tuple marking beginning of region ---@param pos2 integer[] (line, column) tuple marking end of region ---@param regtype string type of selection, see |setreg()| ----@param inclusive boolean indicating whether the selection is end-inclusive ----@return table region Table of the form `{linenr = {startcol,endcol}}` +---@param inclusive boolean indicating whether column of pos2 is inclusive +---@return table region Table of the form `{linenr = {startcol,endcol}}`. +--- `endcol` is exclusive, and whole lines are marked with +--- `{startcol,endcol} = {0,-1}`. function vim.region(bufnr, pos1, pos2, regtype, inclusive) if not vim.api.nvim_buf_is_loaded(bufnr) then vim.fn.bufload(bufnr) -- cgit From fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5 Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Sat, 25 Mar 2023 18:58:48 +0200 Subject: feat(api): nvim_exec2(), deprecate nvim_exec() #19032 Problem: The signature of nvim_exec() is not extensible per ":help api-contract". Solution: Introduce nvim_exec2() and deprecate nvim_exec(). --- runtime/lua/vim/_editor.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index fd6a5865ce..db7a6c1d17 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -322,8 +322,8 @@ end --- ---@param command string|table Command(s) to execute. --- If a string, executes multiple lines of Vim script at once. In this ---- case, it is an alias to |nvim_exec()|, where `output` is set to ---- false. Thus it works identical to |:source|. +--- case, it is an alias to |nvim_exec2()|, where `opts.output` is set +--- to false. Thus it works identical to |:source|. --- If a table, executes a single command. In this case, it is an alias --- to |nvim_cmd()| where `opts` is empty. ---@see |ex-cmd-index| @@ -338,7 +338,7 @@ vim.cmd = setmetatable({}, { if type(command) == 'table' then return vim.api.nvim_cmd(command, {}) else - return vim.api.nvim_exec(command, false) + return vim.api.nvim_exec2(command, { output = false }).output end end, __index = function(t, command) -- cgit From 4863ca6b8902c5b0aab95f2af640118cd417d379 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 26 Mar 2023 10:49:32 +0800 Subject: test: use exec_capture() in more places (#22787) Problem: Using `meths.exec2("code", { output = true })` is too verbose. Solution: Use exec_capture() in more places. --- runtime/lua/vim/_editor.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index db7a6c1d17..2ff4d440f0 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -338,7 +338,8 @@ vim.cmd = setmetatable({}, { if type(command) == 'table' then return vim.api.nvim_cmd(command, {}) else - return vim.api.nvim_exec2(command, { output = false }).output + vim.api.nvim_exec2(command, {}) + return '' end end, __index = function(t, command) -- cgit From 2257ade3dc2daab5ee12d27807c0b3bcf103cd29 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 26 Mar 2023 12:42:15 +0200 Subject: feat(lua): add `vim.loader` feat: new faster lua loader using byte-compilation --- runtime/lua/vim/_editor.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 2ff4d440f0..0c4b634f6f 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -28,6 +28,7 @@ for k, v in pairs({ treesitter = true, filetype = true, + loader = true, F = true, lsp = true, highlight = true, -- cgit From 743860de40502227b3f0ed64317eb937d24d4a36 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Tue, 4 Apr 2023 21:59:06 +0200 Subject: test: replace lfs with luv and vim.fs test: replace lfs with luv luv already pretty much does everything lfs does, so this duplication of dependencies isn't needed. --- runtime/lua/vim/_editor.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 0c4b634f6f..fa0980563a 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -36,7 +36,6 @@ for k, v in pairs({ keymap = true, ui = true, health = true, - fs = true, secure = true, _watch = true, }) do -- cgit From 9e86f473e0f4e21c5f40bf990c53194d593a0f9f Mon Sep 17 00:00:00 2001 From: NAKAI Tsuyoshi <82267684+uga-rosa@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:28:46 +0900 Subject: feat(lua): vim.region accepts getpos() arg (#22635) --- runtime/lua/vim/_editor.lua | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index fa0980563a..c922ec93db 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -402,8 +402,8 @@ end --- Input and output positions are (0,0)-indexed and indicate byte positions. --- ---@param bufnr integer number of buffer ----@param pos1 integer[] (line, column) tuple marking beginning of region ----@param pos2 integer[] (line, column) tuple marking end of region +---@param pos1 integer[]|string start of region as a (line, column) tuple or string accepted by |getpos()| +---@param pos2 integer[]|string end of region as a (line, column) tuple or string accepted by |getpos()| ---@param regtype string type of selection, see |setreg()| ---@param inclusive boolean indicating whether column of pos2 is inclusive ---@return table region Table of the form `{linenr = {startcol,endcol}}`. @@ -414,6 +414,24 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive) vim.fn.bufload(bufnr) end + if type(pos1) == 'string' then + local pos = vim.fn.getpos(pos1) + pos1 = { pos[2] - 1, pos[3] - 1 + pos[4] } + end + if type(pos2) == 'string' then + local pos = vim.fn.getpos(pos2) + pos2 = { pos[2] - 1, pos[3] - 1 + pos[4] } + end + + if pos1[1] > pos2[1] or (pos1[1] == pos2[1] and pos1[2] > pos2[2]) then + pos1, pos2 = pos2, pos1 + end + + -- getpos() may return {0,0,0,0} + if pos1[1] < 0 or pos1[2] < 0 then + return {} + end + -- check that region falls within current buffer local buf_line_count = vim.api.nvim_buf_line_count(bufnr) pos1[1] = math.min(pos1[1], buf_line_count - 1) -- cgit From 7e70ca0b4808bb9d8f19c28c8f93e8f2b9e0d0f0 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:52:44 +0200 Subject: feat(lua): vim.keycode (#22960) Using nvim_replace_termcodes is too verbose, add vim.keycode for translating keycodes. Co-authored-by: ii14 --- runtime/lua/vim/_editor.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index c922ec93db..20e813d77c 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -829,6 +829,20 @@ function vim.print(...) return ... end +--- Translate keycodes. +--- +--- Example: +---
lua
+---   local k = vim.keycode
+---   vim.g.mapleader = k''
+--- 
+--- @param str string String to be converted. +--- @return string +--- @see |nvim_replace_termcodes()| +function vim.keycode(str) + return vim.api.nvim_replace_termcodes(str, true, true, true) +end + function vim._cs_remote(rcid, server_addr, connect_error, args) local function connection_failure_errmsg(consequence) local explanation -- cgit From 08991b078267e5de0a19a136d00d4f71ad651a32 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Sat, 13 May 2023 21:33:22 +0200 Subject: docs: small fixes Co-authored-by: Christian Clason Co-authored-by: Gregory Anders Co-authored-by: HiPhish Co-authored-by: Julio B Co-authored-by: T727 <74924917+T-727@users.noreply.github.com> Co-authored-by: camoz Co-authored-by: champignoom <66909116+champignoom@users.noreply.github.com> --- runtime/lua/vim/_editor.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 20e813d77c..b26def5958 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -778,7 +778,7 @@ do -- some bugs, so fake the two-step dance for now. local matches - --- Omnifunc for completing lua values from from the runtime lua interpreter, + --- Omnifunc for completing lua values from the runtime lua interpreter, --- similar to the builtin completion for the `:lua` command. --- --- Activate using `set omnifunc=v:lua.vim.lua_omnifunc` in a lua buffer. -- cgit From 2db719f6c2b677fcbc197b02fe52764a851523b2 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Sat, 3 Jun 2023 11:06:00 +0100 Subject: feat(lua): rename vim.loop -> vim.uv (#22846) --- runtime/lua/vim/_editor.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index b26def5958..7b946a55e4 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -42,6 +42,10 @@ for k, v in pairs({ vim._submodules[k] = v end +-- Remove at Nvim 1.0 +---@deprecated +vim.loop = vim.uv + -- There are things which have special rules in vim._init_packages -- for legacy reasons (uri) or for performance (_inspector). -- most new things should go into a submodule namespace ( vim.foobar.do_thing() ) @@ -159,7 +163,7 @@ do --- - 3: ends the paste (exactly once) ---@returns boolean # false if client should cancel the paste. function vim.paste(lines, phase) - local now = vim.loop.now() + local now = vim.uv.now() local is_first_chunk = phase < 2 local is_last_chunk = phase == -1 or phase == 3 if is_first_chunk then -- Reset flags. @@ -483,7 +487,7 @@ end ---@return table timer luv timer object function vim.defer_fn(fn, timeout) vim.validate({ fn = { fn, 'c', true } }) - local timer = vim.loop.new_timer() + local timer = vim.uv.new_timer() timer:start( timeout, 0, -- cgit From c0952e62fd0ee16a3275bb69e0de04c836b39015 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 7 Jun 2023 13:52:23 +0100 Subject: feat(lua): add `vim.system()` feat(lua): add vim.system() Problem: Handling system commands in Lua is tedious and error-prone: - vim.fn.jobstart() is vimscript and comes with all limitations attached to typval. - vim.loop.spawn is too low level Solution: Add vim.system(). Partly inspired by Python's subprocess module Does not expose any libuv objects. --- runtime/lua/vim/_editor.lua | 99 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 80 insertions(+), 19 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 7b946a55e4..d46b0fbf32 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -42,10 +42,6 @@ for k, v in pairs({ vim._submodules[k] = v end --- Remove at Nvim 1.0 ----@deprecated -vim.loop = vim.uv - -- There are things which have special rules in vim._init_packages -- for legacy reasons (uri) or for performance (_inspector). -- most new things should go into a submodule namespace ( vim.foobar.do_thing() ) @@ -69,13 +65,73 @@ vim.log = { }, } --- Internal-only until comments in #8107 are addressed. --- Returns: --- {errcode}, {output} -function vim._system(cmd) - local out = vim.fn.system(cmd) - local err = vim.v.shell_error - return err, out +-- TODO(lewis6991): document that the signature is system({cmd}, [{opts},] {on_exit}) +--- Run a system command +--- +--- Examples: +---
lua
+---
+---   local on_exit = function(obj)
+---     print(obj.code)
+---     print(obj.signal)
+---     print(obj.stdout)
+---     print(obj.stderr)
+---   end
+---
+---   -- Run asynchronously
+---   vim.system({'echo', 'hello'}, { text = true }, on_exit)
+---
+---   -- Run synchronously
+---   local obj = vim.system({'echo', 'hello'}, { text = true }):wait()
+---   -- { code = 0, signal = 0, stdout = 'hello', stderr = '' }
+---
+--- 
+--- +--- See |uv.spawn()| for more details. +--- +--- @param cmd (string[]) Command to execute +--- @param opts (SystemOpts|nil) Options: +--- - cwd: (string) Set the current working directory for the sub-process. +--- - env: table Set environment variables for the new process. Inherits the +--- current environment with `NVIM` set to |v:servername|. +--- - clear_env: (boolean) `env` defines the job environment exactly, instead of merging current +--- environment. +--- - stdin: (string|string[]|boolean) If `true`, then a pipe to stdin is opened and can be written +--- to via the `write()` method to SystemObj. If string or string[] then will be written to stdin +--- and closed. Defaults to `false`. +--- - stdout: (boolean|function) +--- Handle output from stdout. When passed as a function must have the signature `fun(err: string, data: string)`. +--- Defaults to `true` +--- - stderr: (boolean|function) +--- Handle output from stdout. When passed as a function must have the signature `fun(err: string, data: string)`. +--- Defaults to `true`. +--- - text: (boolean) Handle stdout and stderr as text. Replaces `\r\n` with `\n`. +--- - timeout: (integer) +--- - detach: (boolean) If true, spawn the child process in a detached state - this will make it +--- a process group leader, and will effectively enable the child to keep running after the +--- parent exits. Note that the child process will still keep the parent's event loop alive +--- unless the parent process calls |uv.unref()| on the child's process handle. +--- +--- @param on_exit (function|nil) Called when subprocess exits. When provided, the command runs +--- asynchronously. Receives SystemCompleted object, see return of SystemObj:wait(). +--- +--- @return SystemObj Object with the fields: +--- - pid (integer) Process ID +--- - wait (fun(timeout: integer|nil): SystemCompleted) +--- - SystemCompleted is an object with the fields: +--- - code: (integer) +--- - signal: (integer) +--- - stdout: (string), nil if stdout argument is passed +--- - stderr: (string), nil if stderr argument is passed +--- - kill (fun(signal: integer)) +--- - write (fun(data: string|nil)) Requires `stdin=true`. Pass `nil` to close the stream. +--- - is_closing (fun(): boolean) +function vim.system(cmd, opts, on_exit) + if type(opts) == 'function' then + on_exit = opts + opts = nil + end + return require('vim._system').run(cmd, opts, on_exit) end -- Gets process info from the `ps` command. @@ -85,13 +141,14 @@ function vim._os_proc_info(pid) error('invalid pid') end local cmd = { 'ps', '-p', pid, '-o', 'comm=' } - local err, name = vim._system(cmd) - if 1 == err and vim.trim(name) == '' then + local r = vim.system(cmd):wait() + local name = assert(r.stdout) + if r.code == 1 and vim.trim(name) == '' then return {} -- Process not found. - elseif 0 ~= err then + elseif r.code ~= 0 then error('command failed: ' .. vim.fn.string(cmd)) end - local _, ppid = vim._system({ 'ps', '-p', pid, '-o', 'ppid=' }) + local ppid = assert(vim.system({ 'ps', '-p', pid, '-o', 'ppid=' }):wait().stdout) -- Remove trailing whitespace. name = vim.trim(name):gsub('^.*/', '') ppid = tonumber(ppid) or -1 @@ -109,14 +166,14 @@ function vim._os_proc_children(ppid) error('invalid ppid') end local cmd = { 'pgrep', '-P', ppid } - local err, rv = vim._system(cmd) - if 1 == err and vim.trim(rv) == '' then + local r = vim.system(cmd):wait() + if r.code == 1 and vim.trim(r.stdout) == '' then return {} -- Process not found. - elseif 0 ~= err then + elseif r.code ~= 0 then error('command failed: ' .. vim.fn.string(cmd)) end local children = {} - for s in rv:gmatch('%S+') do + for s in r.stdout:gmatch('%S+') do local i = tonumber(s) if i ~= nil then table.insert(children, i) @@ -1006,4 +1063,8 @@ end require('vim._meta') +-- Remove at Nvim 1.0 +---@deprecated +vim.loop = vim.uv + return vim -- cgit From cce9460524aa17bcd4daa095f4706220b81f8845 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 11 Jun 2023 15:29:51 +0800 Subject: fix(remote): make --remote-expr print to stdout (#23980) --- runtime/lua/vim/_editor.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index d46b0fbf32..dc396b8f65 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -932,7 +932,7 @@ function vim._cs_remote(rcid, server_addr, connect_error, args) or subcmd == 'tab-wait' or subcmd == 'tab-wait-silent' then - return { errmsg = 'E5600: Wait commands not yet implemented in nvim' } + return { errmsg = 'E5600: Wait commands not yet implemented in Nvim' } elseif subcmd == 'tab-silent' then f_tab = true f_silent = true @@ -946,8 +946,9 @@ function vim._cs_remote(rcid, server_addr, connect_error, args) if rcid == 0 then return { errmsg = connection_failure_errmsg('Send expression failed.') } end - print(vim.fn.rpcrequest(rcid, 'nvim_eval', args[2])) - return { should_exit = true, tabbed = false } + local expr = 'string(' .. args[2] .. ')' + local res = vim.fn.rpcrequest(rcid, 'nvim_eval', expr) + return { result = res, should_exit = true, tabbed = false } elseif subcmd ~= '' then return { errmsg = 'Unknown option argument: ' .. args[1] } end -- cgit From bde59e81473f29944ef80ff98f6b2c88010b2df6 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 11 Jun 2023 22:12:32 +0800 Subject: fix(remote): restore previous --remote-expr output formatting (#23988) - Use tostring() as that's what print() uses internally. - Do not append trailing new line. --- runtime/lua/vim/_editor.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index dc396b8f65..1c7eb30b03 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -940,14 +940,13 @@ function vim._cs_remote(rcid, server_addr, connect_error, args) if rcid == 0 then return { errmsg = connection_failure_errmsg('Send failed.') } end - vim.fn.rpcrequest(rcid, 'nvim_input', args[2]) + vim.rpcrequest(rcid, 'nvim_input', args[2]) return { should_exit = true, tabbed = false } elseif subcmd == 'expr' then if rcid == 0 then return { errmsg = connection_failure_errmsg('Send expression failed.') } end - local expr = 'string(' .. args[2] .. ')' - local res = vim.fn.rpcrequest(rcid, 'nvim_eval', expr) + local res = tostring(vim.rpcrequest(rcid, 'nvim_eval', args[2])) return { result = res, should_exit = true, tabbed = false } elseif subcmd ~= '' then return { errmsg = 'Unknown option argument: ' .. args[1] } -- cgit From 0eb02ea90a5a7c2e35bfcf99b701a28ff2901b4b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 12 Jun 2023 20:08:08 +0800 Subject: docs: various clarifications (#23999) Close #18907 Close #20314 Close #23749 --- runtime/lua/vim/_editor.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 1c7eb30b03..1de2ade1a1 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -534,9 +534,9 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive) return region end ---- Defers calling `fn` until `timeout` ms passes. +--- Defers calling {fn} until {timeout} ms passes. --- ---- Use to do a one-shot timer that calls `fn` +--- Use to do a one-shot timer that calls {fn} --- Note: The {fn} is |vim.schedule_wrap()|ped automatically, so API functions are --- safe to call. ---@param fn function Callback to call once `timeout` expires -- cgit From 4e6356559c8cd44dbcaa765d1f39e176064526ec Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 22 Jun 2023 03:44:51 -0700 Subject: test: spellcheck :help (vimdoc) files #24109 Enforce consistent terminology (defined in `gen_help_html.lua:spell_dict`) for common misspellings. This does not spellcheck English in general (perhaps a future TODO, though it may be noisy). --- runtime/lua/vim/_editor.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 1de2ade1a1..e2ed0d980e 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -3,7 +3,7 @@ -- Lua code lives in one of three places: -- 1. runtime/lua/vim/ (the runtime): For "nice to have" features, e.g. the -- `inspect` and `lpeg` modules. --- 2. runtime/lua/vim/shared.lua: pure lua functions which always +-- 2. runtime/lua/vim/shared.lua: pure Lua functions which always -- are available. Used in the test runner, as well as worker threads -- and processes launched from Nvim. -- 3. runtime/lua/vim/_editor.lua: Code which directly interacts with @@ -839,10 +839,10 @@ do -- some bugs, so fake the two-step dance for now. local matches - --- Omnifunc for completing lua values from the runtime lua interpreter, + --- Omnifunc for completing Lua values from the runtime Lua interpreter, --- similar to the builtin completion for the `:lua` command. --- - --- Activate using `set omnifunc=v:lua.vim.lua_omnifunc` in a lua buffer. + --- Activate using `set omnifunc=v:lua.vim.lua_omnifunc` in a Lua buffer. function vim.lua_omnifunc(find_start, _) if find_start == 1 then local line = vim.api.nvim_get_current_line() -- cgit From 49a7585981cdf7403e76a614558e602a98e64301 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 23 Jun 2023 12:16:55 +0200 Subject: docs: autocmds, misc --- runtime/lua/vim/_editor.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index e2ed0d980e..ab20c36b17 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -184,6 +184,7 @@ end --- Gets a human-readable representation of the given object. --- +---@see |vim.print()| ---@see https://github.com/kikito/inspect.lua ---@see https://github.com/mpeterv/vinspect local function inspect(object, options) -- luacheck: no unused @@ -870,6 +871,7 @@ end ---
--- --- @see |vim.inspect()| +--- @see |:=| --- @return any # given arguments. function vim.print(...) if vim.in_fast_event() then -- cgit From abd380e28d48dd155b1e29cd2453f13b28bf7e08 Mon Sep 17 00:00:00 2001 From: Steven Ward Date: Mon, 5 Jun 2023 22:05:51 -0500 Subject: fix(defaults): visual mode star (*,#) is fragile Problem: Visual mode "*", "#" mappings don't work on text with "/", "\", "?", and newlines. Solution: Get the visual selection and escape it as a search pattern. Add functions vim.get_visual_selection and _search_for_visual_selection. Fix #21676 --- runtime/lua/vim/_editor.lua | 84 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 6 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index ab20c36b17..e00d512a2a 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -435,7 +435,7 @@ vim.cmd = setmetatable({}, { do local validate = vim.validate - --@private + ---@private local function make_dict_accessor(scope, handle) validate({ scope = { scope, 's' }, @@ -535,6 +535,55 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive) return region end +--- Gets the content of the visual selection. +--- +--- The result is either a string or, if {list} is `true`, a list of strings. +--- If not in any |visual-mode|, `nil` is returned. +--- +--- @param list boolean|nil +--- Return a list of strings instead of a string. See |getreg()|. +--- Defaults to `false`. +--- @param append_empty boolean|nil +--- Append an empty string to the result when in |linewise-visual| mode and {list} is `true`. +--- This will preserve the trailing newline of the selection when the result is concatenated with `"\n"`. +--- Defaults to `false`. +--- @return string|table +function vim.get_visual_selection(list, append_empty) + list = list or false + append_empty = append_empty or false + + local mode = vim.api.nvim_get_mode().mode + if mode ~= 'v' and mode ~= 'V' and mode:byte() ~= 22 then + return nil + end + + local reg_name_unnamed = '"' + local reg_name_yank = '0' + + local reg_info_unnamed = vim.fn.getreginfo(reg_name_unnamed) + local reg_info_yank = vim.fn.getreginfo(reg_name_yank) + local opt_clipboard = vim.o.clipboard + local opt_report = vim.o.report + + vim.o.clipboard = '' + vim.o.report = vim.v.maxcol + + vim.api.nvim_feedkeys('y', 'nx', false) + + local yanked = vim.fn.getreg(reg_name_yank, 1, list) + + vim.fn.setreg(reg_name_unnamed, reg_info_unnamed) + vim.fn.setreg(reg_name_yank, reg_info_yank) + vim.o.clipboard = opt_clipboard + vim.o.report = opt_report + + if list and append_empty and mode == 'V' then + table.insert(yanked, '') + end + + return yanked +end + --- Defers calling {fn} until {timeout} ms passes. --- --- Use to do a one-shot timer that calls {fn} @@ -985,7 +1034,7 @@ end --- Defaults to "Nvim". ---@param backtrace boolean|nil Prints backtrace. Defaults to true. --- ----@returns Deprecated message, or nil if no message was shown. +---@return Deprecated message, or nil if no message was shown. function vim.deprecate(name, alternative, version, plugin, backtrace) local msg = ('%s is deprecated'):format(name) plugin = plugin or 'Nvim' @@ -1010,9 +1059,28 @@ end function vim._init_default_mappings() -- mappings - --@private + ---@private + local function _search_for_visual_selection(search_prefix) + if search_prefix ~= '/' and search_prefix ~= '?' then + return + end + -- Escape these characters + local replacements = { + [search_prefix] = [[\]] .. search_prefix, + [ [[\]] ] = [[\\]], + ['\t'] = [[\t]], + ['\n'] = [[\n]], + } + local pattern = '[' .. table.concat(vim.tbl_keys(replacements), '') .. ']' + local visual_selection = vim.get_visual_selection(false) + local escaped_visual_selection = string.gsub(visual_selection, pattern, replacements) + local search_cmd = search_prefix .. [[\V]] .. escaped_visual_selection .. '\n' + vim.api.nvim_feedkeys(search_cmd, 'nx', true) + end + + ---@private local function map(mode, lhs, rhs) - vim.api.nvim_set_keymap(mode, lhs, rhs, { noremap = true, desc = 'Nvim builtin' }) + vim.keymap.set(mode, lhs, rhs, { noremap = true, desc = 'Nvim builtin' }) end map('n', 'Y', 'y$') @@ -1020,8 +1088,12 @@ function vim._init_default_mappings() map('n', '', 'nohlsearchdiffupdatenormal! ') map('i', '', 'u') map('i', '', 'u') - map('x', '*', 'y/\\V"') - map('x', '#', 'y?\\V"') + map('x', '*', function() + _search_for_visual_selection('/') + end) + map('x', '#', function() + _search_for_visual_selection('?') + end) -- Use : instead of so that ranges are supported. #19365 map('n', '&', ':&&') -- cgit From f39ca5df232cb6e70b1932b7444840acf42cf87b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 5 Jul 2023 19:47:43 +0200 Subject: refactor(defaults): use vim.region for visual star (*,#) Problem: The parent commit added a new vim.get_visual_selection() function to improve visual star. But that is redundant with vim.region(). Any current limitations of vim.region() should be fixed instead of adding a new function. Solution: Delete vim.get_visual_selection(). Use vim.region() to get the visual selection. TODO: fails with visual "block" selections. --- runtime/lua/vim/_editor.lua | 107 ++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 74 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index e00d512a2a..6f701e9ae9 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -535,55 +535,6 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive) return region end ---- Gets the content of the visual selection. ---- ---- The result is either a string or, if {list} is `true`, a list of strings. ---- If not in any |visual-mode|, `nil` is returned. ---- ---- @param list boolean|nil ---- Return a list of strings instead of a string. See |getreg()|. ---- Defaults to `false`. ---- @param append_empty boolean|nil ---- Append an empty string to the result when in |linewise-visual| mode and {list} is `true`. ---- This will preserve the trailing newline of the selection when the result is concatenated with `"\n"`. ---- Defaults to `false`. ---- @return string|table -function vim.get_visual_selection(list, append_empty) - list = list or false - append_empty = append_empty or false - - local mode = vim.api.nvim_get_mode().mode - if mode ~= 'v' and mode ~= 'V' and mode:byte() ~= 22 then - return nil - end - - local reg_name_unnamed = '"' - local reg_name_yank = '0' - - local reg_info_unnamed = vim.fn.getreginfo(reg_name_unnamed) - local reg_info_yank = vim.fn.getreginfo(reg_name_yank) - local opt_clipboard = vim.o.clipboard - local opt_report = vim.o.report - - vim.o.clipboard = '' - vim.o.report = vim.v.maxcol - - vim.api.nvim_feedkeys('y', 'nx', false) - - local yanked = vim.fn.getreg(reg_name_yank, 1, list) - - vim.fn.setreg(reg_name_unnamed, reg_info_unnamed) - vim.fn.setreg(reg_name_yank, reg_info_yank) - vim.o.clipboard = opt_clipboard - vim.o.report = opt_report - - if list and append_empty and mode == 'V' then - table.insert(yanked, '') - end - - return yanked -end - --- Defers calling {fn} until {timeout} ms passes. --- --- Use to do a one-shot timer that calls {fn} @@ -1034,7 +985,7 @@ end --- Defaults to "Nvim". ---@param backtrace boolean|nil Prints backtrace. Defaults to true. --- ----@return Deprecated message, or nil if no message was shown. +---@return string|nil # Deprecated message, or nil if no message was shown. function vim.deprecate(name, alternative, version, plugin, backtrace) local msg = ('%s is deprecated'):format(name) plugin = plugin or 'Nvim' @@ -1049,9 +1000,7 @@ function vim.deprecate(name, alternative, version, plugin, backtrace) if displayed and backtrace ~= false then vim.notify(debug.traceback('', 2):sub(2), vim.log.levels.WARN) end - if displayed then - return msg - end + return displayed and msg or nil end --- Create builtin mappings (incl. menus). @@ -1060,27 +1009,37 @@ function vim._init_default_mappings() -- mappings ---@private - local function _search_for_visual_selection(search_prefix) - if search_prefix ~= '/' and search_prefix ~= '?' then - return + local function region_chunks(region) + local chunks = {} + local maxcol = vim.v.maxcol + for line, cols in vim.spairs(region) do + local endcol = cols[2] == maxcol and -1 or cols[2] + local chunk = vim.api.nvim_buf_get_text(0, line, cols[1], line, endcol, {})[1] + table.insert(chunks, chunk) end - -- Escape these characters - local replacements = { - [search_prefix] = [[\]] .. search_prefix, - [ [[\]] ] = [[\\]], - ['\t'] = [[\t]], - ['\n'] = [[\n]], - } - local pattern = '[' .. table.concat(vim.tbl_keys(replacements), '') .. ']' - local visual_selection = vim.get_visual_selection(false) - local escaped_visual_selection = string.gsub(visual_selection, pattern, replacements) - local search_cmd = search_prefix .. [[\V]] .. escaped_visual_selection .. '\n' + return chunks + end + + ---@private + local function _visual_search(cmd) + assert(cmd == '/' or cmd == '?') + vim.api.nvim_feedkeys('\27', 'nx', true) -- Escape visual mode. + local region = vim.region(0, "'<", "'>", vim.fn.visualmode(), vim.o.selection == 'inclusive') + local chunks = region_chunks(region) + local esc_chunks = vim + .iter(chunks) + :map(function(v) + return vim.fn.escape(v, [[/\]]) + end) + :totable() + local esc_pat = table.concat(esc_chunks, [[\n]]) + local search_cmd = ([[%s\V%s%s]]):format(cmd, esc_pat, '\n') vim.api.nvim_feedkeys(search_cmd, 'nx', true) end ---@private local function map(mode, lhs, rhs) - vim.keymap.set(mode, lhs, rhs, { noremap = true, desc = 'Nvim builtin' }) + vim.keymap.set(mode, lhs, rhs, { desc = 'Nvim builtin' }) end map('n', 'Y', 'y$') @@ -1088,12 +1047,12 @@ function vim._init_default_mappings() map('n', '', 'nohlsearchdiffupdatenormal! ') map('i', '', 'u') map('i', '', 'u') - map('x', '*', function() - _search_for_visual_selection('/') - end) - map('x', '#', function() - _search_for_visual_selection('?') - end) + vim.keymap.set('x', '*', function() + _visual_search('/') + end, { desc = 'Nvim builtin', silent = true }) + vim.keymap.set('x', '#', function() + _visual_search('?') + end, { desc = 'Nvim builtin', silent = true }) -- Use : instead of so that ranges are supported. #19365 map('n', '&', ':&&') -- cgit From 00d2f4b96eb9c8dcb6b9f67e256bb7faa19354db Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 4 Jul 2023 19:22:04 +0200 Subject: docs: MAINTAIN.md, nvim_get_mark --- runtime/lua/vim/_editor.lua | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 6f701e9ae9..80e7518b01 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -460,17 +460,18 @@ do vim.t = make_dict_accessor('t') end ---- Get a table of lines with start, end columns for a region marked by two points. ---- Input and output positions are (0,0)-indexed and indicate byte positions. +--- Gets a dict of line segment ("chunk") positions for the region from `pos1` to `pos2`. --- ----@param bufnr integer number of buffer ----@param pos1 integer[]|string start of region as a (line, column) tuple or string accepted by |getpos()| ----@param pos2 integer[]|string end of region as a (line, column) tuple or string accepted by |getpos()| ----@param regtype string type of selection, see |setreg()| ----@param inclusive boolean indicating whether column of pos2 is inclusive ----@return table region Table of the form `{linenr = {startcol,endcol}}`. ---- `endcol` is exclusive, and whole lines are marked with ---- `{startcol,endcol} = {0,-1}`. +--- Input and output positions are byte positions, (0,0)-indexed. "End of line" column +--- position (for example, |linewise| visual selection) is returned as |v:maxcol| (big number). +--- +---@param bufnr integer Buffer number, or 0 for current buffer +---@param pos1 integer[]|string Start of region as a (line, column) tuple or |getpos()|-compatible string +---@param pos2 integer[]|string End of region as a (line, column) tuple or |getpos()|-compatible string +---@param regtype string \|setreg()|-style selection type +---@param inclusive boolean Controls whether `pos2` column is inclusive (see also 'selection'). +---@return table region Dict of the form `{linenr = {startcol,endcol}}`. `endcol` is exclusive, and +---whole lines are returned as `{startcol,endcol} = {0,-1}`. function vim.region(bufnr, pos1, pos2, regtype, inclusive) if not vim.api.nvim_buf_is_loaded(bufnr) then vim.fn.bufload(bufnr) @@ -610,18 +611,17 @@ local on_key_cbs = {} --- 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} +---@note {fn} will be removed on error. +---@note {fn} will not be cleared by |nvim_buf_clear_namespace()| +---@note {fn} will receive the keys after mappings have been evaluated +--- +---@param fn fun(key: string) Function invoked on every key press. |i_CTRL-V| +--- Returning nil removes the callback associated with namespace {ns_id}. ---@param ns_id integer? Namespace ID. If nil or 0, generates and returns a new --- |nvim_create_namespace()| id. --- ---@return integer Namespace id associated with {fn}. Or count of all callbacks ---if on_key() is called without arguments. ---- ----@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 @@ -1049,10 +1049,10 @@ function vim._init_default_mappings() map('i', '', 'u') vim.keymap.set('x', '*', function() _visual_search('/') - end, { desc = 'Nvim builtin', silent = true }) + end, { desc = ':help v_star-default', silent = true }) vim.keymap.set('x', '#', function() _visual_search('?') - end, { desc = 'Nvim builtin', silent = true }) + end, { desc = ':help v_#-default', silent = true }) -- Use : instead of so that ranges are supported. #19365 map('n', '&', ':&&') -- cgit From 6318edadc32acce3ed41a6995a5faa5395b5f562 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 8 Jul 2023 15:28:13 +0200 Subject: fix(defaults): visual hash (#) on text with "?" Problem: The default "#" mapping fails on the following example after v$h# with cursor at start of the first line: aa?/\bb aa aa?/\bb Solution: Also escape "?". --- runtime/lua/vim/_editor.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 80e7518b01..0bbbed74bb 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -1029,7 +1029,7 @@ function vim._init_default_mappings() local esc_chunks = vim .iter(chunks) :map(function(v) - return vim.fn.escape(v, [[/\]]) + return vim.fn.escape(v, [[?/\]]) end) :totable() local esc_pat = table.concat(esc_chunks, [[\n]]) -- cgit From b9a0e762f1d79d17631b7d17cf25b6e25006d8c2 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 8 Jul 2023 16:55:27 +0200 Subject: fix(defaults): visual star (*) on text with "?" regression from 6318edadc32acce3ed41a6995a5faa5395b5f562 --- runtime/lua/vim/_editor.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 0bbbed74bb..5a93f5cd60 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -1029,7 +1029,7 @@ function vim._init_default_mappings() local esc_chunks = vim .iter(chunks) :map(function(v) - return vim.fn.escape(v, [[?/\]]) + return vim.fn.escape(v, cmd == '/' and [[/\]] or [[?\]]) end) :totable() local esc_pat = table.concat(esc_chunks, [[\n]]) -- cgit From 766f4978d6cb146511cf0b676c01e5327db46647 Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 10 Jul 2023 19:38:15 +0800 Subject: fix(lint): lint warnings #24226 --- runtime/lua/vim/_editor.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 5a93f5cd60..47215416e0 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -219,7 +219,7 @@ do --- - 1: starts the paste (exactly once) --- - 2: continues the paste (zero or more times) --- - 3: ends the paste (exactly once) - ---@returns boolean # false if client should cancel the paste. + ---@return boolean result false if client should cancel the paste. function vim.paste(lines, phase) local now = vim.uv.now() local is_first_chunk = phase < 2 -- cgit From d0b612f360125785eb95afaa51620c5c7695e381 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Sun, 16 Jul 2023 09:27:39 +0100 Subject: refactor: rename _meta.lua to _options.lua --- runtime/lua/vim/_editor.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 47215416e0..bb0aa97a0d 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -1094,7 +1094,7 @@ function vim._init_defaults() vim._init_default_autocmds() end -require('vim._meta') +require('vim._options') -- Remove at Nvim 1.0 ---@deprecated -- cgit From be74807eef13ff8c90d55cf8b22b01d6d33b1641 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 18 Jul 2023 15:42:30 +0100 Subject: docs(lua): more improvements (#24387) * docs(lua): teach lua2dox how to table * docs(lua): teach gen_vimdoc.py about local functions No more need to mark local functions with @private * docs(lua): mention @nodoc and @meta in dev-lua-doc * fixup! Co-authored-by: Justin M. Keyes --------- Co-authored-by: Justin M. Keyes --- runtime/lua/vim/_editor.lua | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index bb0aa97a0d..4372aef7b3 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -54,6 +54,7 @@ vim._extra = { inspect_pos = true, } +--- @private vim.log = { levels = { TRACE = 0, @@ -187,9 +188,7 @@ end ---@see |vim.print()| ---@see https://github.com/kikito/inspect.lua ---@see https://github.com/mpeterv/vinspect -local function inspect(object, options) -- luacheck: no unused - error(object, options) -- Stub for gen_vimdoc.py -end +vim.inspect = vim.inspect do local tdots, tick, got_line1, undo_started, trailing_nl = 0, 0, false, false, false @@ -328,6 +327,7 @@ function vim.schedule_wrap(cb) end -- vim.fn.{func}(...) +---@private vim.fn = setmetatable({}, { __index = function(t, key) local _fn @@ -345,10 +345,13 @@ vim.fn = setmetatable({}, { end, }) +--- @private vim.funcref = function(viml_func_name) return vim.fn[viml_func_name] end +local VIM_CMD_ARG_MAX = 20 + --- Execute Vim script commands. --- --- Note that `vim.cmd` can be indexed with a command name to return a callable function to the @@ -389,12 +392,6 @@ end --- If a table, executes a single command. In this case, it is an alias --- to |nvim_cmd()| where `opts` is empty. ---@see |ex-cmd-index| -function vim.cmd(command) -- luacheck: no unused - error(command) -- Stub for gen_vimdoc.py -end - -local VIM_CMD_ARG_MAX = 20 - vim.cmd = setmetatable({}, { __call = function(_, command) if type(command) == 'table' then @@ -435,7 +432,6 @@ vim.cmd = setmetatable({}, { do local validate = vim.validate - ---@private local function make_dict_accessor(scope, handle) validate({ scope = { scope, 's' }, @@ -745,7 +741,6 @@ function vim._expand_pat(pat, env) end local keys = {} - ---@private local function insert_keys(obj) for k, _ in pairs(obj) do if type(k) == 'string' and string.sub(k, 1, string.len(match_part)) == match_part then @@ -1008,7 +1003,6 @@ end function vim._init_default_mappings() -- mappings - ---@private local function region_chunks(region) local chunks = {} local maxcol = vim.v.maxcol @@ -1020,7 +1014,6 @@ function vim._init_default_mappings() return chunks end - ---@private local function _visual_search(cmd) assert(cmd == '/' or cmd == '?') vim.api.nvim_feedkeys('\27', 'nx', true) -- Escape visual mode. @@ -1037,7 +1030,6 @@ function vim._init_default_mappings() vim.api.nvim_feedkeys(search_cmd, 'nx', true) end - ---@private local function map(mode, lhs, rhs) vim.keymap.set(mode, lhs, rhs, { desc = 'Nvim builtin' }) end -- cgit From 6a486c44e66f05ae11137ad7a192b89989192566 Mon Sep 17 00:00:00 2001 From: marshmallow Date: Tue, 25 Jul 2023 01:35:19 +1000 Subject: fix(gx): move to to _init_default_mappings #24420 Problem: netrw may conflict with the Nvim default "gx" mapping. Solution: Initialize keymapping earlier by moving it to vim._init_default_mappings(). That also avoids needing to check maparg(). --- runtime/lua/vim/_editor.lua | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'runtime/lua/vim/_editor.lua') diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 4372aef7b3..87f6d6581c 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -1048,6 +1048,33 @@ function vim._init_default_mappings() -- Use : instead of so that ranges are supported. #19365 map('n', '&', ':&&') + -- gx + + -- TODO: use vim.region() when it lands... #13896 #16843 + local function get_visual_selection() + local save_a = vim.fn.getreginfo('a') + vim.cmd([[norm! "ay]]) + local selection = vim.fn.getreg('a', 1) + vim.fn.setreg('a', save_a) + return selection + end + + local function do_open(uri) + local _, err = vim.ui.open(uri) + if err then + vim.notify(err, vim.log.levels.ERROR) + end + end + + local gx_desc = + 'Opens filepath or URI under cursor with the system handler (file explorer, web browser, …)' + vim.keymap.set({ 'n' }, 'gx', function() + do_open(vim.fn.expand('')) + end, { desc = gx_desc }) + vim.keymap.set({ 'x' }, 'gx', function() + do_open(get_visual_selection()) + end, { desc = gx_desc }) + -- menus -- TODO VimScript, no l10n -- cgit From ccb5a76e5a2cc8627da6e3453697d2628ed0c6ac Mon Sep 17 00:00:00 2001 From: zeertzjq