Commit Graph

5677 Commits

Author SHA1 Message Date
Yi Ming
bbd0fdd36d perf(lsp): avoid unnecessary string allocations when parsing content-length 2026-04-25 19:02:06 +08:00
Kyle
66149ca668 feat(tui): restore 'ttyfast' to control tty requests #38699
Problem:
When running nvim on a remote machine over SSH, if there is high ping,
then bg detection may not complete in time. This results in a warning
every time nvim is started. #38648

Solution:
Restore 'ttyfast' option and allow it to control whether or not bg
detection is performed. Because this is during startup and before any
user config or commands, we use the environment variable
`NVIM_NOTTYFAST` to allow disabling `ttyfast` during initialization.
2026-04-24 14:45:20 -04:00
Peter Cardenas
27191e0f4f feat(api): nvim_echo(percent=nil) means "unknown" progress #39029
Problem:
No way to signal "unknown" or "indeterminate" progress percentage.

Solution:
Treat percent=nil as "indeterminate" percent.
2026-04-24 11:57:35 -04:00
Justin M. Keyes
5c88492a13 fix(trust): always use "/" slashes in filepaths #39355
Problem:
We should not use "\" (backslashes) except where absolutely required.
See references in https://github.com/neovim/neovim/pull/37729

Solution:
There is no reason to use "\" slashes in the trust db, so don't.
2026-04-24 07:37:21 -04:00
Olivia Kinnear
645a588aa6 feat(excmd): add :uptime command #39331
Problem
Nvim marks its v:starttime, but there is no user-friendly way to get Nvim's uptime.

Solution
Add :uptime (based loosely on uptime(1)).
2026-04-23 17:11:59 -04:00
geril07
790a8be5f3 fix(lsp): malformed edit if apply_text_edits() is called twice #34954
Problem:
Use vim.lsp.util.apply_text_edits to re-apply the same textedit causes
an incorrect edit, because apply_text_edits silently modifies the
parameter.

Solution:
- Avoid changing `text_edit._index`.
- Document this fun feature.

Helped-by: Riley Bruins <ribru17@hotmail.com>
Helped-by: Yi Ming <ofseed@foxmail.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-04-23 16:01:44 +00:00
Evgeni Chasnovski
f8c94bb8cf fix(pack): only use tags that strictly comply with semver spec #39342
Problem: Using `version=vim.version.range(...)` in plugin specification
  is meant to use semver-like tags. Whether a tag is semver-like was
  decided by a plain `vim.version.parse` which is not strict by default.
  This allowed treating tags like `nvim-0.6` (which is usually reserved
  for the latest revision compatible with Nvim<=0.6 version) like semver
  tags and resulted in confusing behavior (preferring `nvim-0.6` tag
  over `v0.2.2`, for example).

Solution: Use `vim.version.range(x, { strict = true })` to decide if the
  tag name is semver-like or not. This allows tags like both `v1.2.3`
  and `1.2.3` while being consistent in what Nvim thinks is a semver
  string.

  This is technically not a breaking change since it was documented that
  only tags like `v<major>.<minor>.<patch>` will be recognized as
  semver.
2026-04-23 11:14:06 -04:00
Justin M. Keyes
82198d0a66 ci: drop cirrus #39321
Problem:
cirrus will shutdown soon, and we are running out of minutes anyway,
which causes ci failures.

Solution:
Drop cirrus config.
2026-04-22 18:25:07 -04:00
altermo
451811b1be feat(treesitter): expand selection to sibling node #38938
Problem:
Can't expand treesitter-incremental-selection to the next and previous
sibling nodes.

Solution:
Pressing `]N` in visual mode will expand the selection to the next
sibling node, and `[N` will do the same with the previous node.
2026-04-22 17:10:24 -04:00
Justin M. Keyes
28ba068372 feat(:restart): v:starttime, v:exitreason #39282
Problem:
- The `ZR` feature makes it more obvious that we need some sort of flag so that
  an `ExitPre` / `QuitPre` / `VimLeave` handler can handle restarts differently
  than a normal exit. For example, it's common that users want `:mksession` on
  restart, but perhaps not on a normal exit.
- Nvim has no way to report its "uptime".

Solution:
- Introduce `v:starttime`
- Introduce `v:exitreason`
2026-04-22 13:40:41 -04:00
Yi Ming
558204d87b perf(lsp): clear table by table.clear() #39222
benchmark: https://gist.github.com/ofseed/6224529d77c016c36f7ab2f977059848

    local rounds = tonumber(arg[1]) or 1000
    local count = tonumber(arg[2]) or 1000

    -- Load the table.clear function.
    local clear = require("table.clear")

    local function fill(t, n)
      for i = 1, n do
        t[i] = i
      end
    end

    local function bench_reassign(n_rounds, n_items)
      local t = {}
      local start = os.clock()

      for _ = 1, n_rounds do
        t = {}
        collectgarbage("collect")
        fill(t, n_items)
      end

      return os.clock() - start
    end

    local function bench_reassign_no_gc(n_rounds, n_items)
      local t = {}
      local start = os.clock()

      for _ = 1, n_rounds do
        t = {}
        fill(t, n_items)
      end

      return os.clock() - start
    end

    local function bench_clear(n_rounds, n_items)
      local t = {}
      local start = os.clock()

      for _ = 1, n_rounds do
        clear(t)
        fill(t, n_items)
      end

      return os.clock() - start
    end

    -- Warm up LuaJIT before the real benchmark.
    do
      local t = {}
      for _ = 1, 2000 do
        clear(t)
        fill(t, count)
      end
    end

    collectgarbage("collect")

    local reassign_time = bench_reassign(rounds, count)
    collectgarbage("collect")

    local reassign_no_gc_time = bench_reassign_no_gc(rounds, count)
    collectgarbage("collect")

    local clear_time = bench_clear(rounds, count)

    print(string.format("rounds=%d count=%d", rounds, count))
    print(string.format("t = {} + GC   : %.6f s", reassign_time))
    print(string.format("t = {}        : %.6f s", reassign_no_gc_time))
    print(string.format("table.clear   : %.6f s", clear_time))
    print(string.format("vs + GC       : %.2fx", reassign_time / clear_time))
    print(string.format("vs no GC      : %.2fx", reassign_no_gc_time / clear_time))

benchmark result:

    rounds=1000 count=1000
    t = {} + GC   : 0.022469 s
    t = {}        : 0.002570 s
    table.clear   : 0.000387 s
    vs + GC       : 58.06x
    vs no GC      : 6.64x

`count` is how many items the table has, and `round` is how many rounds we fill
the table, clear, and then refill it. `table = {}` is clear the table by
resigning a new empty one, because this script does not run persistently like
nvim so GC is not triggered, so I added another extreme control group that
manually triggers GC.
2026-04-22 11:38:58 -04:00
luukvbaal
2ca31eddae docs(quickfix): quickfix window location #39300
Problem:  Documentation for quickfix window location is outdated (since 6256adde).
Solution: Update quickfix.txt.
2026-04-22 07:08:05 -04:00
Nick Krichevsky
e68e769352 fix(options): default 'titlestring' shows CWD #39233
Problem:
In the default 'titlestring', if the containing directory is the CWD, it renders as "."

Solution:
Add `:p` to the titlestring.
2026-04-22 05:56:23 -04:00
zeertzjq
25b7fe5ada vim-patch:3918f32: runtime(doc): fix incorrect description of 'scrolloffpad'
closes: vim/vim#20029

3918f3232f
2026-04-22 10:14:53 +08:00
zeertzjq
8f1e14ffa2 vim-patch:9.2.0356: Cannot apply 'scrolloff' context lines at end of file
Problem:  Cannot apply 'scrolloff' context lines at end of file
Solution: Add the 'scrolloffpad' option to keep 'scrolloff' context even
          when at the end of the file (McAuley Penney).

closes: vim/vim#19040

a414630393

Co-authored-by: McAuley Penney <jacobmpenney@gmail.com>
2026-04-22 10:14:52 +08:00
Barrett Ruth
8efe4f9ac1 fix(incsearch): support c_CTRL-{G,T} with an offset (#39097)
vim-patch:9.2.0374: c_CTRL-{G,T} does not handle offset

Problem:  c_CTRL-{G,T} does not handle offset, when cycling between
          matches
Solution: Refactor parsing logic into parse_search_pattern_offset() and
          handle offsets, note: highlighting does not handle offsets
          yet (Barrett Ruth).

fixes:  vim/vim#19991
closes: vim/vim#19998

c62342e5cf
2026-04-22 01:24:49 +00:00
luukvbaal
ff68fd6b8a fix(messages): "progress" kind for busy messages #39280
Problem:  The "Scanning:" completion, bufwrite, and indent (there may be
          more) messages which indicate progress can use the "progress" kind
          for their msg_show event. Indent message does not have a kind.

Solution: Emit these messages with the "progress" kind. Set the message id
          to the replaced kind so that a UI knows to replace it (and to provide
          a migration path in case a UI was distinguishing these messages for
          whatever reason).
2026-04-21 16:11:41 -04:00
bfredl
fe60268258 Merge pull request #39076 from bfredl/zig0.16
IT IS HAPPENING: Zig 0.16
2026-04-21 20:09:57 +02:00
Justin M. Keyes
a1c8b81672 feat(normal): normal-mode ZR does :restart
Make it a normal-mode command instead of a default mapping.
2026-04-21 15:54:08 +02:00
Mike J. McGuirk
2551c7a8b1 feat(defaults): map ZR to restart
Problem: No default mapping for :restart.

Solution: Map to ZR in defaults.

Closes: https://github.com/neovim/neovim/issues/38942
2026-04-21 15:54:08 +02:00
bfredl
52693e7af3 fix(build): more changes to make zig 0.16.0 work 2026-04-21 12:46:01 +02:00
Justin M. Keyes
2b52acfb8a docs: misc #39207 2026-04-20 07:09:37 -04:00
glepnir
01861c2f95 fix(api): expose fg_indexed/bg_indexed in nvim_get_hl #39210
Problem: fg_indexed/bg_indexed were dropped from nvim_get_hl output due
to a wrong short_keys guard. HL_FG_INDEXED also wasn't cleared in
hl_blend_attrs, and HLATTRS_DICT_SIZE was too small.

Solution: Remove the short_keys guard, clear HL_FG_INDEXED in
hl_blend_attrs, bump HLATTRS_DICT_SIZE to 24, and clarify docs that
these flags mean rgb is an approximation of the cterm palette index.
2026-04-20 05:12:52 -04:00
luukvbaal
fe986e5dd0 feat(options): add 'winpinned' to pin a window #39157
Problem:
- Unable to "pin" a window to prevent closing without specifically
  being targeted.
- :fclose closes hidden windows (even before visible windows).

Solution:
- Add 'winpinned' window-local option. When set, window is skipped by
  :fclose and :only. Pin the ui2 cmdline window (which should always be
  visible), so that it is not closed by :only/fclose.
- Skip over hidden (and pinned) windows with :fclose.

Co-authored-by: glepnir <glephunter@gmail.com>
2026-04-19 20:36:55 -04:00
Maria Solano
e8b3968774 docs(lsp): description for on_list example #39230 2026-04-19 18:30:45 -04:00
Olivia Kinnear
c6209e5542 feat(excmd): add EXX error codes for :lsp, :log #39135
Also remove the `--add-comments` flag from `xgettext` because
it dumped a bunch of comments from Lua files into the `.pot` files.
2026-04-19 10:40:49 -04:00
Ashley Hauck
4b54bca3df feat(events): trigger MarkSet autocmd in :delmarks #39156
Problem:
`api.nvim_buf_del_mark` already emits a `MarkSet` event with `col` and `line` set to 0. However, `:delmarks` currently emits no events.

Solution:
Change `:delmarks` to emit the same `col==line==0` event.
2026-04-19 07:42:08 -04:00
Justin M. Keyes
54398c5874 docs: misc #39045 2026-04-18 15:38:59 -04:00
Aditya Malik
2cb240319b docs(events): Lua types for autocmd event-data #38518
Problem:
  No LuaLS types for event-data fields (ev.data). Types are only
  documented ad hoc in scattered locations.

Solution:
  Add runtime/lua/vim/_meta/events.lua defining vim.event.<name>.data
  classes for events that provide ev.data. Reference the types from
  each event's help in autocmd.txt, lsp.txt, and pack.txt.
2026-04-18 13:17:45 -04:00
Justin M. Keyes
3ebfa2a3cb feat(vimfn): use Lua for more excmds/vimfns
Problem:
Too much boilerplate needed to use Lua to impl an excmd or f_xx
function.

Solution:
- Add `nlua_call_vimfn` which takes the args typval, executes
  Lua, and returns a typval.
- refactor(excmd): lua impl for :log, :lsp
2026-04-18 16:57:37 +02:00
zeertzjq
674f4b35ab vim-patch:e666597: runtime(doc): make window option description a bit less vague (#39173)
Say explicitly that ":setlocal" sets the local value, while ":set" also
sets the global value.

related: vim/vim#19993

e666597622
2026-04-18 07:28:12 +08:00
Justin M. Keyes
0d4d285bd2 perf(vim.fn): call Lua-implemented vim.fn.xx() directly #39166
Problem:
- Builtin "Vimscript" functions (f_xx) are mostly implemented in C.
  Partly that's because there is some boilerplate required to call out
  to Lua.
- Calls to `vim.fn.foo()` always marshall over the Lua <=> Vimscript
  ("typval") bridge, even if `fn.foo()` is implemented entirely in Lua:
  ```
  Lua => typval => Object => Lua => Object => typval => Lua.
  ```

Solution:
Functions declared in eval.lua with `func_lua` are implemented in
entirely in Lua (`_core/vimfn.lua`).

- `gen_eval.lua` wires `func_lua` entries to `lua_wrapper`, which handles
  the typval conversion for Vimscript callers (slow path).
- `nlua_call()` detects `func_lua` functions and calls the Lua
  implementation directly. This eliminates all conversion overhead for
  Lua callers (fast path).
- Validate at build-time that `func`, `func_float`, and `func_lua` are
  mutually exclusive.
- Migrate `hostname()` as a toy example, to show the idea.
2026-04-17 19:10:20 -04:00
zeertzjq
fefad0721a test: include test path in summary (#39141)
Ref: https://github.com/neovim/neovim/pull/38486#discussion_r3088483987
2026-04-17 21:20:36 +08:00
zeertzjq
39410ef42b vim-patch:8.2.2440: documentation based on patches is outdated (#39144)
Problem:    Documentation based on patches is outdated.
Solution:   Add changes to documentation in a patch.

853886722c

Trailing space was removed in later patches.
Also fix a few more misplaced error numbers from #8155.

Co-authored-by: Bram Moolenaar <Bram@vim.org>
2026-04-17 09:50:03 +08:00
Yi Ming
a61a0bf407 refactor(lsp): provide a default list handler example #39005
Problem:
Difficult for us to provide default handlers for functions like
`vim.lsp.buf.definition`. When users wanted to fine-tune the default behavior,
they don't know how.

Solution:
- Document an example providing `on_list` boilerplate to make it easier for
  users to modify and override.
- Also, considering that the parameters of the previous
  `on_list`(`vim.lsp.ListOpts.OnList`) are compatible with the parameters of
  `setqflist`, remove that custom type in favor of passing
  `vim.fn.setqflist.what`.
2026-04-16 15:15:04 -04:00
Justin M. Keyes
bc6d946cca test: lint EXX error codes #8155
Problem:
- Choosing a new EXX error code is tedious.
- It's possible to accidentally use an EXX error code for different
  purposes.

Solution:
Add a lint check which requires EXX error codes to have a :help tag.
This also avoids duplicates because `make doc` does `:helptags ++t doc`
which fails if duplicates are found.
2026-04-16 10:48:11 -04:00
Evgeni Chasnovski
42e9d8dfd1 docs(pack): improve "Synchronize across machines" steps #39122
Problem: Sometimes automatic lockfile synchronization after `:restart`
  might fail, like due to bad/absent Internet connection. This would
  remove failed to install entries from the lockfile (since they are not
  on disk and lockfile is meant to lock the latest plugin version on
  disk).

Solution: Document that this should be treated as an unwanted update and
  use steps similar to "Revert plugin after an update" use case.
2026-04-16 10:33:20 -04:00
Evgeni Chasnovski
711f3cc299 docs(diagnostic): severity names are sometimes allowed #39120
Problem: Using severity names (like "ERROR", "WARN") in functions like
  `vim.diganostic.get()` and `vim.diagnostic.config()` is allowed and
  tested for many years now. But documentation about it can be clearer.

Solution: Explicitly mention that severity names are allowed in some
  situations. Ideally, it would also require updating typing for
  `vim.diagnostic.SeverityFilter`, but that looks problematic to do
  robustly.
2026-04-16 10:32:35 -04:00
zeertzjq
3cca237984 vim-patch:e6a84bb: runtime(tar): missing g:tar_secure in tar#Extract() (#39123)
e6a84bb6b0

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-04-16 22:19:48 +08:00
Justin M. Keyes
11a1ec7df3 test: lint naming conventions #39117
Problem:
Naming conventions are not automatically checked.

Solution:
Add a check to the doc generator. Eventually we should extract this
somehow, but that will require refactoring the doc generator...

Note: this also checks non-public functions, basically anything that
passes through `gen_eval_files.lua` and `gen_vimdoc.lua`. And that's
a good thing.
2026-04-16 09:35:58 -04:00
Justin M. Keyes
6b1a918038 Merge #39078 render class dot members as module functions 2026-04-16 05:42:33 -04:00
Yi Ming
37aa66c1a2 feat(docs): render class dot members as module functions
AI-assisted: Codex
2026-04-16 16:50:36 +08:00
Justin M. Keyes
71ac4db335 refactor(api): rename "window" to "win" (positional parameters) #39083
continues d0af4cd909.

This commit renames positional parameters. This is only "cosmetic", but
is intended to make it extra clear which name is preferred, since people
often copy existing code despite the guidelines in `:help dev-naming`.
2026-04-15 13:31:17 -04:00
Yi Ming
1740d51ede feat(lsp): highlight foldtext via treesitter #38789
Problem:
To support `collapsedText`, which allows the LSP server to determine the
content of the foldtext, we provided `vim.lsp.foldtext()`. However, such
content does not have highlighting.

Solution
Treat the filetype of `collapsedText` as the filetype of the corresponding
buffer and use tree-sitter to highlight it.
2026-04-15 10:27:44 -04:00
Justin M. Keyes
d0af4cd909 refactor(api): rename buffer to buf (positional parameters) #39013
In 3a4a66017b, 4d3a67cd62, df8d98173c we renamed "buffer" to "buf"
in dict parameters and return-values.

This commit renames positional parameters. This is only "cosmetic", but
is intended to make it extra clear which name is preferred, since people
often copy existing code despite the guidelines in `:help dev-naming`.
2026-04-15 09:48:21 -04:00
Yi Ming
481e70550c revert: "docs: vim.range, vim.pos #38869"
This reverts commit c530fd8e75.
2026-04-15 20:46:46 +08:00
Lewis Russell
55f9c2136e test: replace busted with local harness
Replace the busted-based Lua test runner with a repo-local harness.

The new harness runs spec files directly under `nvim -ll`, ships its own
reporter and lightweight `luassert` shim, and keeps the helper/preload
flow used by the functional and unit test suites.

Keep the file boundary model shallow and busted-like by restoring `_G`,
`package.loaded`, `package.preload`, `arg`, and the process environment
between files, without carrying extra reset APIs or custom assertion
machinery.

Update the build and test entrypoints to use the new runner, add
black-box coverage for the harness itself, and drop the bundled
busted/luacheck dependency path.

AI-assisted: Codex
2026-04-15 12:09:25 +01:00
Lewis Russell
e289f9579c fix(lua): make vim.deep_equal cycle-safe
AI-assisted: Codex
2026-04-15 09:26:45 +01:00
luukvbaal
5d3cda472c feat(api): use zindex to determine dimmed cursor shape #39054
Problem:  The cursor shape is changed to indicate when it is behind an
          unfocused floating window (since a2b92a5e). This behavior
          cannot be controlled by a floating window that doesn't want
          to dim the cursor.

Solution: Assign a zindex-offset of 50 to the zindex of the current
          window. To not dim the cursor when creating a floating window
          on top of the current window one can assign the zindex
          accordingly.
2026-04-14 16:08:36 -04:00
Justin M. Keyes
d77808ec59 docs: lsp, options, api #38980
docs: lsp, options

- revert bogus change to `_meta/builtin_types.lua` from 3a4a66017b

Close #38991

Co-authored-by: David Mejorado <david.mejorado@gmail.com>
2026-04-14 06:09:54 -04:00