neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit e8ace820934a9eb7f23b7a3f61ccea2c7de02043
parent d0822bbd155796bd04c0ef1fdf051e90a09fa0a7
Author: Justin M. Keyes <justinkz@gmail.com>
Date:   Thu, 12 Feb 2026 08:15:21 -0500

Merge #37096 from justinmk/doc2


Diffstat:
MBUILD.md | 12++++++++++++
MCONTRIBUTING.md | 2+-
MMAINTAIN.md | 12++++--------
Mruntime/doc/channel.txt | 2+-
Mruntime/doc/dev.txt | 2+-
Mruntime/doc/dev_arch.txt | 4++--
Mruntime/doc/dev_style.txt | 2+-
Mruntime/doc/dev_test.txt | 27++++++++++++++++++---------
Mruntime/doc/lsp.txt | 29+++++++++++++++++------------
Mruntime/doc/lua-plugin.txt | 3++-
Mruntime/doc/lua.txt | 58+++++++++++++++++++++++++++++++++-------------------------
Mruntime/doc/map.txt | 4++--
Mruntime/doc/news.txt | 11++++++-----
Mruntime/lua/vim/fs.lua | 48+++++++++++++++++++++++++-----------------------
Mruntime/lua/vim/health/health.lua | 27++++++++++-----------------
Mruntime/lua/vim/lsp.lua | 2+-
Mruntime/scripts/optwin.lua | 2--
Mscripts/collect_typos.lua | 33+++++++++++++++++++++++++++------
Msrc/nvim/api/buffer.c | 38+++++++++++++++++++-------------------
Msrc/nvim/message.h | 2+-
Mtest/functional/lua/fs_spec.lua | 2+-
Mtest/functional/lua/ui_spec.lua | 2+-
Mtest/functional/plugin/optwin_spec.lua | 2++
23 files changed, 187 insertions(+), 139 deletions(-)

diff --git a/BUILD.md b/BUILD.md @@ -70,6 +70,18 @@ make distclean make deps ``` +### PUC Lua + +To build with "PUC Lua" instead of LuaJit: + + make CMAKE_EXTRA_FLAGS="-DPREFER_LUA=ON" DEPS_CMAKE_FLAGS="-DUSE_BUNDLED_LUAJIT=OFF -DUSE_BUNDLED_LUA=ON" + +### Build options + +View the full list of CMake options defined in this project: + + cmake -B build -LH + ## Building on Windows ### Windows / MSVC diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md @@ -235,7 +235,7 @@ See [#549][549] for more details. The Lua [`runtime/lua/vim/_core/`](./runtime/lua/vim/_core/) modules are precompiled to bytecode, so changes won't be usable unless you (1) rebuild Nvim or (2) start Nvim with `--luamod-dev` and `$VIMRUNTIME`. For example try adding -a function to `runtime/lua/vim/editor.lua`, then: +a function to `runtime/lua/vim/_core/editor.lua`, then: ```bash VIMRUNTIME=./runtime ./build/bin/nvim --luamod-dev diff --git a/MAINTAIN.md b/MAINTAIN.md @@ -116,12 +116,7 @@ should be stated explicitly and publicly. Third-party dependencies ------------------------ -For some dependencies we maintain temporary "forks", which are simply private -branches with a few extra patches, while we wait for the upstream project to -merge the patches. This is done instead of maintaining the patches as (fragile) -CMake `PATCH_COMMAND` steps. - -These "bundled" dependencies can be updated by bumping their versions in `cmake.deps/deps.txt`. +"Bundled" dependencies can be updated by bumping their versions in `cmake.deps/deps.txt`. Some can be auto-bumped by `scripts/bump_deps.lua`. * [LuaJIT](https://github.com/LuaJIT/LuaJIT) @@ -136,9 +131,10 @@ Some can be auto-bumped by `scripts/bump_deps.lua`. * [libiconv](https://ftp.gnu.org/pub/gnu/libiconv) * [lua-compat](https://github.com/keplerproject/lua-compat-5.3) * [tree-sitter](https://github.com/tree-sitter/tree-sitter) -* [unibilium](https://github.com/neovim/unibilium) - * The original project [was abandoned](https://github.com/neovim/neovim/issues/10302), so the [neovim/unibilium](https://github.com/neovim/unibilium) fork is considered "upstream" and is maintained on the `master` branch. * [treesitter parsers](https://github.com/neovim/neovim/blob/7e97c773e3ba78fcddbb2a0b9b0d572c8210c83e/cmake.deps/deps.txt#L47-L62) +* (Deprecated) [unibilium](https://github.com/neovim/unibilium) + * The original project [was abandoned](https://github.com/neovim/neovim/issues/10302), so the [neovim/unibilium](https://github.com/neovim/unibilium) fork is considered "upstream" and is maintained on the `master` branch. + * **Note:** unibilium is NOT required. See [BUILD.md](./BUILD.md#build-without-unibilium) to build Nvim without unibilium. ### Vendored dependencies diff --git a/runtime/doc/channel.txt b/runtime/doc/channel.txt @@ -189,7 +189,7 @@ normally only do that in a newly created buffer: >vim The user can edit and input text at the end of the buffer. Pressing Enter in the input section invokes the |prompt_setcallback()| callback, which is typically expected to process the prompt and show results by appending to the -buffer. To input multiline text, use Shift-<Enter> to add a new line without +buffer. To input multiline text, use *Shift-<Enter>* to add a new line without submitting the prompt, or just |put| or |paste| multiline text. Only the section starting with the mark |':| of the buffer (after the prompt) diff --git a/runtime/doc/dev.txt b/runtime/doc/dev.txt @@ -365,7 +365,7 @@ Where possible, these patterns apply to _both_ Lua and the API: If `opts` is omitted (or `nil`) it returns the current configuration. - Example: See |vim.diagnostic.config()|. - "Enable" ("toggle") interface and behavior: - - `enable(…, nil)` and `enable(…, {buf=nil})` are synonyms and control the + - `enable(…, nil)` and `enable(…, {buf=nil})` are synonyms and control the "global" enablement of a feature. - `is_enabled(nil)` and `is_enabled({buf=nil})`, likewise, query the global state of the feature. diff --git a/runtime/doc/dev_arch.txt b/runtime/doc/dev_arch.txt @@ -154,8 +154,8 @@ API *dev-api-fast* API functions and Vimscript "eval" functions may be marked as |api-fast| which -means they are safe to call in Lua callbacks and other scenarios. A functions -CANNOT be marked as "fast" if could trigger `os_breakcheck()`, which may +means they are safe to call in Lua callbacks and other scenarios. A function +CANNOT be marked as "fast" if it could trigger `os_breakcheck()`, which may "yield" the current execution and start a new execution of code not expecting this: - accidentally recursing into a function not expecting this. diff --git a/runtime/doc/dev_style.txt b/runtime/doc/dev_style.txt @@ -6,7 +6,7 @@ Nvim style guide *dev-style* -Style guidelines for developers working Nvim's source code. +Style guidelines for developers working on Nvim's source code. License: CC-By 3.0 https://creativecommons.org/licenses/by/3.0/ diff --git a/runtime/doc/dev_test.txt b/runtime/doc/dev_test.txt @@ -349,17 +349,26 @@ GUIDELINES files. - `#define` constants must be rewritten `const` or `enum` so they can be "visible" to the tests. -- Use `pending()` to skip tests - ([example](https://github.com/neovim/neovim/commit/5c1dc0fbe7388528875aff9d7b5055ad718014de#diff-bf80b24c724b0004e8418102f68b0679R18)). - Do not silently skip the test with `if-else`. If a functional test depends on - some external factor (e.g. the existence of `md5sum` on `$PATH`), _and_ you - can't mock or fake the dependency, then skip the test via `pending()` if the - external factor is missing. This ensures that the _total_ test-count - (success + fail + error + pending) is the same in all environments. +- Use `pending()` or `t.skip()` to skip tests. + - Example: https://github.com/neovim/neovim/commit/5c1dc0fbe7388528875aff9d7b5055ad718014de#diff-bf80b24c724b0004e8418102f68b0679R18 + - Note: If a test is skipped because of a non-actionable reason, we don't + want it to appear in the "pending" list. Include "N/A" in the skip + description, then it won't be added to the "pending" list. For example, if + a test is skipped because it's running on a non-LuaJit system, including + it in the "pending" list is just noise. Thus, its pending reason should + say "N/A": > + pending('N/A: missing LuaJIT FFI') +< + - Do not silently skip the test with `if-else`. If a functional test depends + on some external factor (e.g. the existence of `md5sum` on `$PATH`), _and_ + you can't mock or fake the dependency, then skip the test via `pending()` + if the external factor is missing. This ensures that the _total_ + test-count (success + fail + error + pending) is the same in all + environments. - Note: `pending()` is ignored if it is missing an argument, unless it is [contained in an `it()` block](https://github.com/neovim/neovim/blob/d21690a66e7eb5ebef18046c7a79ef898966d786/test/functional/ex_cmds/grep_spec.lua#L11). Provide empty function argument if the `pending()` call is outside `it()` - ([example](https://github.com/neovim/neovim/commit/5c1dc0fbe7388528875aff9d7b5055ad718014de#diff-bf80b24c724b0004e8418102f68b0679R18)). + Example: https://github.com/neovim/neovim/commit/5c1dc0fbe7388528875aff9d7b5055ad718014de#diff-bf80b24c724b0004e8418102f68b0679R18 WHERE TESTS GO @@ -502,7 +511,7 @@ Number; !must be defined to function properly): - `NVIM_TEST_TRACE_LEVEL` (U) (N): specifies unit tests tracing level: - `0` disables tracing (the fastest, but you get no data if tests crash and - there no core dump was generated), + no core dump was generated), - `1` leaves only C function calls and returns in the trace (faster than recording everything), - `2` records all function calls, returns and executed Lua source lines. diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt @@ -56,7 +56,14 @@ Follow these steps to get LSP features: a |lsp-root_markers| file so the workspace can be recognized. 5. Check that LSP is active ("attached") for the buffer: >vim :checkhealth vim.lsp -6. (Optional) Configure keymaps and autocommands to use LSP features. +6. Please note that certain LSP features are disabled by default, + you may choose to enable them manually. See: + - |lsp-codelens| + - |lsp-document_color| + - |lsp-linked_editing_range| + - |lsp-inlay_hint| + - |lsp-inline_completion| +7. (Optional) Configure keymaps and autocommands to use LSP features. |lsp-attach| ============================================================================== @@ -657,18 +664,16 @@ LspProgress *LspProgress* Redraw the statusline whenever an LSP progress message arrives: >vim autocmd LspProgress * redrawstatus < - Tell the parent terminal to indicate progress using a native progress - indicator (requires a supporting terminal): >lua - vim.api.nvim_create_autocmd('LspProgress', { - callback = function(ev) + Emit a |progress-message| on LSP progress events: >lua + vim.api.nvim_create_autocmd('LspProgress', { buffer = buf, callback = function(ev) local value = ev.data.params.value - if value.kind == 'begin' then - vim.api.nvim_ui_send('\027]9;4;1;0\027\\') - elseif value.kind == 'end' then - vim.api.nvim_ui_send('\027]9;4;0\027\\') - elseif value.kind == 'report' then - vim.api.nvim_ui_send(string.format('\027]9;4;1;%d\027\\', value.percentage or 0)) - end + vim.api.nvim_echo({ { value.message or 'done' } }, false, { + id = 'lsp', + kind = 'progress', + title = value.title, + status = value.kind ~= 'end' and 'running' or 'success', + percent = value.percentage, + }) end, }) < diff --git a/runtime/doc/lua-plugin.txt b/runtime/doc/lua-plugin.txt @@ -142,7 +142,8 @@ initialization may be useful in specific cases: Keep in mind that this approach requires users to call `setup` in order to use your plugin, even if the default configuration is enough for them. Consider carefully whether your plugin benefits from combined `setup()` pattern -before adopting it. +before adopting it. This article chronicles the history and tradeoffs of +`setup()`: https://mrcjkb.dev/posts/2023-08-22-setup.html NOTE: A well designed plugin has minimal impact on startup time. See also |lua-plugin-lazy|. diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt @@ -2462,12 +2462,14 @@ Example: >lua vim.fs.abspath({path}) *vim.fs.abspath()* - Convert path to an absolute path. A tilde (~) character at the beginning - of the path is expanded to the user's home directory. Does not check if - the path exists, normalize the path, resolve symlinks or hardlinks - (including `.` and `..`), or expand environment variables. If the path is - already absolute, it is returned unchanged. Also converts `\` path - separators to `/`. + Converts `path` to an absolute path. Expands tilde (~) at the beginning of + the path to the user's home directory. Does not check if the path exists, + normalize the path, resolve symlinks or hardlinks (including `.` and + `..`), or expand environment variables. If the path is already absolute, + it is returned unchanged. Also converts `\` path separators to `/`. + + Attributes: ~ + Since: 0.11.0 Parameters: ~ • {path} (`string`) Path @@ -2476,7 +2478,7 @@ vim.fs.abspath({path}) *vim.fs.abspath()* (`string`) Absolute path vim.fs.basename({file}) *vim.fs.basename()* - Return the basename of the given path + Gets the basename of the given path (not expanded/resolved). Attributes: ~ Since: 0.8.0 @@ -2488,17 +2490,17 @@ vim.fs.basename({file}) *vim.fs.basename()* (`string?`) Basename of {file} vim.fs.dir({path}, {opts}) *vim.fs.dir()* - Return an iterator over the items located in {path} + Gets an iterator over items found in `path` (normalized via + |vim.fs.normalize()|). Attributes: ~ Since: 0.8.0 Parameters: ~ - • {path} (`string`) An absolute or relative path to the directory to - iterate over. The path is first normalized + • {path} (`string`) Directory to iterate over, normalized via |vim.fs.normalize()|. • {opts} (`table?`) Optional keyword arguments: - • {depth}? (`integer`, default: `1`) How deep the traverse. + • {depth}? (`integer`, default: `1`) How deep to traverse. • {skip}? (`fun(dir_name: string): boolean`) Predicate to control traversal. Return false to stop searching the current directory. Only useful when depth > 1 Return an @@ -2567,18 +2569,17 @@ vim.fs.find({names}, {opts}) *vim.fs.find()* The function should return `true` if the given item is considered a match. • {opts} (`table?`) Optional keyword arguments: - • {path}? (`string`) Path to begin searching from. If - omitted, the |current-directory| is used. + • {path}? (`string`) Path to begin searching from, defaults + to |current-directory|. Not expanded. • {upward}? (`boolean`, default: `false`) Search upward - through parent directories. Otherwise, search through child + through parent directories. Otherwise, search child directories (recursively). • {stop}? (`string`) Stop searching when this directory is reached. The directory itself is not searched. • {type}? (`string`) Find only items of the given type. If omitted, all items that match {names} are included. - • {limit}? (`number`, default: `1`) Stop the search after - finding this many matches. Use `math.huge` to place no - limit on the number of matches. + • {limit}? (`number`, default: `1`) Stop searching after this + many matches. Use `math.huge` for "unlimited". • {follow}? (`boolean`, default: `false`) Follow symbolic links. @@ -2590,6 +2591,7 @@ vim.fs.joinpath({...}) *vim.fs.joinpath()* Concatenates partial paths (one absolute or relative path followed by zero or more relative paths). Slashes are normalized: redundant slashes are removed, and (on Windows) backslashes are replaced with forward-slashes. + Paths are not expanded/resolved. Examples: • "foo/", "/bar" => "foo/bar" @@ -2686,6 +2688,9 @@ vim.fs.relpath({base}, {target}, {opts}) *vim.fs.relpath()* vim.fs.relpath('/var', '/usr/bin') -- nil < + Attributes: ~ + Since: 0.11.0 + Parameters: ~ • {base} (`string`) • {target} (`string`) @@ -2695,19 +2700,22 @@ vim.fs.relpath({base}, {target}, {opts}) *vim.fs.relpath()* (`string?`) vim.fs.rm({path}, {opts}) *vim.fs.rm()* - Remove files or directories + Removes a file or directory. + + Removes symlinks without touching the origin. To remove the origin, + resolve it explicitly with |uv.fs_realpath()|: >lua + vim.fs.rm(vim.uv.fs_realpath('symlink-dir'), { recursive = true }) +< Attributes: ~ Since: 0.11.0 Parameters: ~ - • {path} (`string`) Path to remove. Removes symlinks without touching - the origin. To remove the origin, resolve explicitly with - |uv.fs_realpath()|. + • {path} (`string`) Path to remove (not expanded/resolved). • {opts} (`table?`) A table with the following fields: - • {recursive}? (`boolean`) Remove directories and their - contents recursively - • {force}? (`boolean`) Ignore nonexistent files and arguments + • {recursive}? (`boolean`) Remove directory contents + recursively. + • {force}? (`boolean`) Ignore nonexistent files and arguments. vim.fs.root({source}, {marker}) *vim.fs.root()* Find the first parent directory containing a specific "marker", relative @@ -2738,7 +2746,7 @@ vim.fs.root({source}, {marker}) *vim.fs.root()* Parameters: ~ • {source} (`integer|string`) Buffer number (0 for current buffer) or - file path (absolute or relative to the |current-directory|) + file path (absolute or relative, expanded via `abspath()`) to begin the search from. • {marker} (`(string|string[]|fun(name: string, path: string): boolean)[]|string|fun(name: string, path: string): boolean`) Filename, function, or list thereof, that decides how to diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt @@ -1581,7 +1581,7 @@ supports incremental command preview: preview_ns, 'Substitute', {line1 + i - 2, start_idx - 1}, - {line1 + i - 2, end_idx}, + {line1 + i - 2, end_idx} ) -- Add lines and set highlights in the preview buffer @@ -1601,7 +1601,7 @@ supports incremental command preview: preview_ns, 'Substitute', {preview_buf_line, #prefix + start_idx - 1}, - {preview_buf_line, #prefix + end_idx}, + {preview_buf_line, #prefix + end_idx} ) preview_buf_line = preview_buf_line + 1 end diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt @@ -41,7 +41,7 @@ TREESITTER UI -• `progress` attribute removed form |ui-messages| msg_show event +• `progress` attribute removed from |ui-messages| msg_show event VIMSCRIPT @@ -255,7 +255,7 @@ LSP https://microsoft.github.io/language-server-protocol/specification/#textDocument_colorPresentation • The `textDocument/diagnostic` request now includes the previous id in its parameters. -• |vim.lsp.enable()| start/stops clients as necessary. And detaches +• |vim.lsp.enable()| start/stops clients as necessary and detaches non-applicable LSP clients. • |vim.lsp.is_enabled()| checks if a LSP config is enabled (without "resolving" it). @@ -314,7 +314,7 @@ LUA • |vim.hl.range()| now allows multiple timed highlights. • |vim.tbl_extend()| and |vim.tbl_deep_extend()| now accept a function behavior argument. • |vim.fs.root()| can define "equal priority" via nested lists. -• |vim.version.range()| output can be converted to human-readable string with |tostring()|. +• |vim.version.range()| output can be converted to a human-readable string with |tostring()|. • |vim.version.intersect()| computes intersection of two version ranges. • |Iter:take()| and |Iter:skip()| now optionally accept predicates. • Built-in plugin manager |vim.pack| @@ -359,17 +359,17 @@ PERFORMANCE additional constraints for improved correctness and resistance to backtracking edge cases. • |i_CTRL-R| inserts named/clipboard registers literally, 10x speedup. +• LSP `textDocument/semanticTokens/range` is supported, which requests tokens + for the viewport (visible screen) only. PLUGINS • Customize :checkhealth by handling a `FileType checkhealth` event. |health-usage| - • Simplify Python provider setup to a single step: `uv tool install pynvim` Nvim will detect the plugin's location without user configuration, even if unrelated Python virtual environments are activated. |provider-python| - • |:checkhealth| now checks for an available |vim.ui.open()| handler. STARTUP @@ -407,6 +407,7 @@ UI • "Error detected while processing:" changed to "Error in:". • "Error executing Lua:" changed to "Lua:". • 'busy' status is shown in default statusline with symbol ◐ +• Cursor shape indicates when it is behind an unfocused floating window. • Improved LSP signature help rendering. • Multigrid UIs can call nvim_input_mouse with grid 0 to let Nvim decide the grid. diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua @@ -94,7 +94,7 @@ function M.dirname(file) return dir end ---- Return the basename of the given path +--- Gets the basename of the given path (not expanded/resolved). --- ---@since 10 ---@generic T : string|nil @@ -116,7 +116,7 @@ end --- Concatenates partial paths (one absolute or relative path followed by zero or more relative --- paths). Slashes are normalized: redundant slashes are removed, and (on Windows) backslashes are ---- replaced with forward-slashes. +--- replaced with forward-slashes. Paths are not expanded/resolved. --- --- Examples: --- - "foo/", "/bar" => "foo/bar" @@ -136,7 +136,7 @@ end --- @class vim.fs.dir.Opts --- @inlinedoc --- ---- How deep the traverse. +--- How deep to traverse. --- (default: `1`) --- @field depth? integer --- @@ -152,11 +152,10 @@ end ---@alias Iterator fun(): string?, string? ---- Return an iterator over the items located in {path} +--- Gets an iterator over items found in `path` (normalized via |vim.fs.normalize()|). --- ---@since 10 ----@param path (string) An absolute or relative path to the directory to iterate ---- over. The path is first normalized |vim.fs.normalize()|. +---@param path (string) Directory to iterate over, normalized via |vim.fs.normalize()|. ---@param opts? vim.fs.dir.Opts Optional keyword arguments: ---@return Iterator over items in {path}. Each iteration yields two values: "name" and "type". --- "name" is the basename of the item relative to {path}. @@ -214,25 +213,20 @@ end --- @class vim.fs.find.Opts --- @inlinedoc --- ---- Path to begin searching from. If ---- omitted, the |current-directory| is used. +--- Path to begin searching from, defaults to |current-directory|. Not expanded. --- @field path? string --- ---- Search upward through parent directories. ---- Otherwise, search through child directories (recursively). +--- Search upward through parent directories. Otherwise, search child directories (recursively). --- (default: `false`) --- @field upward? boolean --- ---- Stop searching when this directory is reached. ---- The directory itself is not searched. +--- Stop searching when this directory is reached. The directory itself is not searched. --- @field stop? string --- ---- Find only items of the given type. ---- If omitted, all items that match {names} are included. +--- Find only items of the given type. If omitted, all items that match {names} are included. --- @field type? string --- ---- Stop the search after finding this many matches. ---- Use `math.huge` to place no limit on the number of matches. +--- Stop searching after this many matches. Use `math.huge` for "unlimited". --- (default: `1`) --- @field limit? number --- @@ -416,7 +410,7 @@ end --- --- @since 12 --- @param source integer|string Buffer number (0 for current buffer) or file path (absolute or ---- relative to the |current-directory|) to begin the search from. +--- relative, expanded via `abspath()`) to begin the search from. --- @param marker (string|string[]|fun(name: string, path: string): boolean)[]|string|fun(name: string, path: string): boolean --- Filename, function, or list thereof, that decides how to find the root. To --- indicate "equal priority", specify items in a nested list `{ { 'a.txt', 'b.lua' }, … }`. @@ -727,16 +721,22 @@ end --- @class vim.fs.rm.Opts --- @inlinedoc --- ---- Remove directories and their contents recursively +--- Remove directory contents recursively. --- @field recursive? boolean --- ---- Ignore nonexistent files and arguments +--- Ignore nonexistent files and arguments. --- @field force? boolean ---- Remove files or directories +--- Removes a file or directory. +--- +--- Removes symlinks without touching the origin. To remove the origin, resolve it explicitly +--- with |uv.fs_realpath()|: +--- ```lua +--- vim.fs.rm(vim.uv.fs_realpath('symlink-dir'), { recursive = true }) +--- ``` +--- --- @since 13 ---- @param path string Path to remove. Removes symlinks without touching the origin. ----To remove the origin, resolve explicitly with |uv.fs_realpath()|. +--- @param path string Path to remove (not expanded/resolved). --- @param opts? vim.fs.rm.Opts function M.rm(path, opts) opts = opts or {} @@ -749,11 +749,12 @@ function M.rm(path, opts) end end ---- Convert path to an absolute path. A tilde (~) character at the beginning of the path is expanded +--- Converts `path` to an absolute path. Expands tilde (~) at the beginning of the path --- to the user's home directory. Does not check if the path exists, normalize the path, resolve --- symlinks or hardlinks (including `.` and `..`), or expand environment variables. If the path is --- already absolute, it is returned unchanged. Also converts `\` path separators to `/`. --- +--- @since 13 --- @param path string Path --- @return string Absolute path function M.abspath(path) @@ -801,6 +802,7 @@ end --- vim.fs.relpath('/var', '/usr/bin') -- nil --- ``` --- +--- @since 13 --- @param base string --- @param target string --- @param opts table? Reserved for future use diff --git a/runtime/lua/vim/health/health.lua b/runtime/lua/vim/health/health.lua @@ -543,19 +543,13 @@ local function check_stable_version(nvim_version) if result.code ~= 0 or not result.stdout or result.stdout == '' then return end - local stable_sha = result.stdout:match('(%x+)%s+refs/tags/stable%^{}') - or result.stdout:match('(%x+)%s+refs/tags/stable\n') - if not stable_sha then - return - end - local latest_version = result.stdout:match(stable_sha .. '%s+refs/tags/v?(%d+%.%d+%.%d+)%^{}') - if not latest_version then - return - end - local current_version = nvim_version:match('v?(%d+%.%d+%.%d+)') - if not current_version then - return - end + local stable_sha = assert( + result.stdout:match('(%x+)%s+refs/tags/stable%^{}') + or result.stdout:match('(%x+)%s+refs/tags/stable\n') + ) + local latest_version = + assert(result.stdout:match(stable_sha .. '%s+refs/tags/v?(%d+%.%d+%.%d+)%^{}')) + local current_version = assert(nvim_version:match('v?(%d+%.%d+%.%d+)')) local current = vim.version.parse(current_version) local latest = vim.version.parse(latest_version) if current and latest and vim.version.lt(current, latest) then @@ -576,10 +570,7 @@ local function check_head_hash(commit) if result.code ~= 0 or not result.stdout or result.stdout == '' then return end - local upstream = result.stdout:match('^(%x+)') - if not upstream then - return - end + local upstream = assert(result.stdout:match('^(%x+)')) if not vim.startswith(upstream, commit) then vim.health.warn( ('Build is outdated. Local: %s, Latest: %s'):format(commit, upstream:sub(1, 12)) @@ -621,6 +612,8 @@ local function check_sysinfo() [[ ## Problem + Describe the problem (concisely). + ## Steps to reproduce ``` diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua @@ -198,7 +198,7 @@ end --- provide the root dir, or LSP will not be activated for the buffer. Thus a `root_dir()` function --- can dynamically decide per-buffer whether to activate (or skip) LSP. --- See example at |vim.lsp.enable()|. ---- @field root_dir? string|fun(bufnr: integer, on_dir:fun(root_dir?:string)) +--- @field root_dir? string|fun(bufnr: integer, on_dir:fun(root_dir?:string)) # --- --- [lsp-root_markers]() --- Filename(s) (".git/", "package.json", …) used to decide the workspace root. Unused if `root_dir` diff --git a/runtime/scripts/optwin.lua b/runtime/scripts/optwin.lua @@ -29,7 +29,6 @@ local options_list = { { 'autochdir', N_ 'change to directory of file in buffer' }, { 'wrapscan', N_ 'search commands wrap around the end of the buffer' }, { 'incsearch', N_ 'show match for partly typed search command' }, - { 'magic', N_ 'change the way backslashes are used in search patterns' }, { 'regexpengine', N_ 'select the default regexp engine used' }, { 'ignorecase', N_ 'ignore case when using a search pattern' }, { 'smartcase', N_ "override 'ignorecase' when pattern has upper case characters" }, @@ -438,7 +437,6 @@ local options_list = { { 'eventignorewin', N_ 'list of autocommand events which are to be ignored in a window' }, { 'loadplugins', N_ 'load plugin scripts when starting up' }, { 'exrc', N_ 'enable reading .vimrc/.exrc/.gvimrc in the current directory' }, - { 'gdefault', N_ 'use the \'g\' flag for ":substitute"' }, { 'maxfuncdepth', N_ 'maximum depth of function calls' }, { 'sessionoptions', N_ 'list of words that specifies what to put in a session file' }, { 'viewoptions', N_ 'list of words that specifies what to save for :mkview' }, diff --git a/scripts/collect_typos.lua b/scripts/collect_typos.lua @@ -88,6 +88,21 @@ local function mime_decode(encoded) return vim.trim(result.stdout) end +local function get_commit_msg(close_pr_lines, co_author_lines) + return ('docs: misc\n\n%s\n\n%s\n'):format( + table.concat(close_pr_lines, '\n'), + table.concat(co_author_lines, '\n') + ) +end + +local function get_fail_msg(msg, pr_number, close_pr_lines, co_author_lines) + return ('%s %s\n\nPending commit message:\n%s'):format( + msg, + pr_number or '', + get_commit_msg(close_pr_lines, co_author_lines) + ) +end + local function main() local pr_list = vim.json.decode( run_die( @@ -107,9 +122,10 @@ local function main() local close_pr_lines = {} local co_author_lines = {} for _, pr_number in ipairs(pr_numbers) do + print(('PR #%s'):format(pr_number)) local patch_file = run_die( { 'gh', 'pr', 'diff', tostring(pr_number), '--patch' }, - 'Failed to get patch of PR ' .. pr_number + get_fail_msg('Failed to get patch for PR', pr_number, close_pr_lines, co_author_lines) ) -- Using --3way allows skipping changes already included in a previous commit. -- If there are conflicts, it will fail and need manual conflict resolution. @@ -128,15 +144,20 @@ local function main() end end else - print('Failed to apply patch of PR ' .. pr_number) + print( + get_fail_msg('Failed to apply patch for PR', pr_number, close_pr_lines, co_author_lines) + ) end end - local msg = ('docs: misc\n\n%s\n\n%s\n'):format( - table.concat(close_pr_lines, '\n'), - table.concat(co_author_lines, '\n') + local msg = get_commit_msg(close_pr_lines, co_author_lines) + print( + run_die( + { 'git', 'commit', '--file', '-' }, + get_fail_msg('Failed to create commit', nil, close_pr_lines, co_author_lines), + msg + ) ) - print(run_die({ 'git', 'commit', '--file', '-' }, 'Failed to create commit', msg)) end main() diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c @@ -48,6 +48,22 @@ #include "api/buffer.c.generated.h" +/// Ensures that a buffer is loaded. +static buf_T *api_buf_ensure_loaded(Buffer buffer, Error *err) +{ + buf_T *buf = find_buffer_by_handle(buffer, err); + if (!buf) { + return NULL; + } + + if (buf->b_ml.ml_mfp == NULL && !buf_ensure_loaded(buf)) { + api_set_error(err, kErrorTypeException, "Failed to load buffer"); + return NULL; + } + + return buf; +} + /// @brief <pre>help /// For more information on buffers, see |buffers|. /// @@ -288,22 +304,6 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, return rv; } -static buf_T *require_loaded_buffer(Buffer buffer, Error *err) -{ - buf_T *buf = find_buffer_by_handle(buffer, err); - if (!buf) { - return NULL; - } - - // Load buffer if necessary - if (buf->b_ml.ml_mfp == NULL && !buf_ensure_loaded(buf)) { - api_set_error(err, kErrorTypeException, "Failed to load buffer"); - return NULL; - } - - return buf; -} - /// Sets (replaces) a line-range in the buffer. /// /// Indexing is zero-based, end-exclusive. Negative indices are interpreted @@ -331,7 +331,7 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ FUNC_API_SINCE(1) FUNC_API_TEXTLOCK_ALLOW_CMDWIN { - buf_T *buf = require_loaded_buffer(buffer, err); + buf_T *buf = api_buf_ensure_loaded(buffer, err); if (!buf) { return; @@ -490,7 +490,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In replacement = scratch; } - buf_T *buf = require_loaded_buffer(buffer, err); + buf_T *buf = api_buf_ensure_loaded(buffer, err); if (!buf) { return; } @@ -1116,7 +1116,7 @@ Boolean nvim_buf_set_mark(Buffer buffer, String name, Integer line, Integer col, FUNC_API_SINCE(8) { bool res = false; - buf_T *buf = require_loaded_buffer(buffer, err); + buf_T *buf = api_buf_ensure_loaded(buffer, err); if (!buf) { return res; diff --git a/src/nvim/message.h b/src/nvim/message.h @@ -37,7 +37,7 @@ EXTERN bool msg_ext_skip_flush INIT( = false); EXTERN bool msg_ext_append INIT( = false); /// Set to true when previous message should be overwritten. EXTERN bool msg_ext_overwrite INIT( = false); -/// Set to true to avoid setting "verbose" kind for last set messages. +/// Set to true to avoid setting "verbose" kind for "last set" messages. EXTERN bool msg_ext_skip_verbose INIT( = false); /// allocated grid for messages. Used unless ext_messages is active. diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua @@ -731,7 +731,7 @@ describe('vim.fs', function() vim.uv.fs_rmdir('Xtest_fs-rm') end) - it('works with symlink', function() + it('symlink', function() -- File vim.uv.fs_symlink('Xtest_fs-rm/file-to-link', 'Xtest_fs-rm/file-as-link') vim.fs.rm('Xtest_fs-rm/file-as-link') diff --git a/test/functional/lua/ui_spec.lua b/test/functional/lua/ui_spec.lua @@ -109,7 +109,7 @@ describe('vim.ui', function() eq(true, exec_lua('return (nil == result)')) end) - it('can return opts.cacelreturn when aborted with ESC with cancelreturn opt #18144', function() + it('can return opts.cancelreturn when aborted with ESC with cancelreturn opt #18144', function() feed(':lua result = "on_confirm not called"<cr>') feed(':lua vim.ui.input({ cancelreturn = "CANCEL" }, function(input) result = input end)<cr>') feed('Inputted Text<esc>') diff --git a/test/functional/plugin/optwin_spec.lua b/test/functional/plugin/optwin_spec.lua @@ -68,10 +68,12 @@ describe('optwin.lua', function() 'secure', 'prompt', 'edcompatible', + 'gdefault', 'guioptions', 'guitablabel', 'guitabtooltip', 'insertmode', + 'magic', 'mouseshape', 'imcmdline', 'imdisable',