Commit Graph

11247 Commits

Author SHA1 Message Date
Freddie Haddad
67839a72f7 fix(treesitter): make TSHighlighter.new() idempotent for an active buffer #41090
Problem:
Calling vim.treesitter.start() a second time on a buffer that already
has an active TSHighlighter creates a brand new instance instead of
reusing it, whether the parser tree is unchanged (e.g. calling start()
twice) or different (e.g. switching languages). Either way the old
instance is silently discarded without calling :destroy() on it, so
its on_bytes/on_changedtree/on_detach callbacks stay registered and
its buffer-local state (spelloptions, decoration namespace) is never
restored, both leaking indefinitely for an orphaned instance that
nothing references anymore.

Solution:
Return the existing instance when TSHighlighter.active[source] is
already set for the same parser tree, instead of unconditionally
constructing a new one. When the tree differs instead (e.g. a language
switch), destroy() the old instance first, matching stop() semantics,
before constructing the new one.
2026-08-02 14:42:47 -04:00
Ro
3b85a689ab docs(api): rpc examples #41077 2026-08-02 08:19:29 -04:00
Justin M. Keyes
f7fbe0e0c8 Merge #41106 from altermo/selection-refactor-fix 2026-08-02 05:33:17 -04:00
zeertzjq
e9190e9c4f vim-patch:9.2.0894: filetype: ed script files not recognised (#41109)
Problem:  filetype: ed script files not recognised.
Solution: Add filetype detection for *.ed files and shebang lines,
          include syntax script and syntax tests.

Features of the ed syntax file:
- BSD and GNU extensions are supported
- Andrew L. Moore's ed extensions are not supported
- Rebuild synmenu.vim

closes: vim/vim#19602

c28515b999

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2026-08-02 09:56:10 +08:00
Justin M. Keyes
98d767cd53 docs: func/expr options, misc #41102 2026-08-01 17:48:32 -04:00
altermo
8695579636 fix(treesitter): handle &selection=exclusive 2026-08-01 18:21:59 +02:00
altermo
77dfa02f3e refactor: combine all visual_selection funcions 2026-08-01 18:20:13 +02:00
AlexCodesApps
b11f1b1f76 feat(vim.fs): abspath({cwd, plain}) #40597
Adds optional parameters to `vim.fs.abspath`:
1. `cwd` to specify directory akin to `--relative-from` in `realpath(1)`.
2. `plain` disables expansion of tilde (~) in paths.
2026-08-01 09:09:21 -04:00
zeertzjq
f129b5428a vim-patch:e31fb9b: runtime(lf): update syntax to support lf version r42 (#41083)
closes: vim/vim#20897

e31fb9bb67

Co-authored-by: CatsDeservePets <145048791+CatsDeservePets@users.noreply.github.com>
2026-08-01 08:25:29 +08:00
Justin M. Keyes
3e01dcddbe refactor(options): memory management
Problem:
Numerous callers have to manually check optval ownership (i.e. whether,
and how, to release) via `is_callback_option`, `option_is_global_local`,
etc. This is fragile, hard to use correctly; and if we introduce another
optval variant in the future, we'll have to redo all of these careful
checks and boilerplate again.

Solution:
Provide a unified system and use it everywhere:

    optval_free_owned
    optval_is_owned
    optval_own
2026-07-31 21:50:04 +02:00
Justin M. Keyes
726d1a92d2 feat(options): lua closure/function options
Problem:
Cannot assign Lua functions/closures to "func" ('completefunc',
'tagfun', …) or "expr" ('foldexpr', 'indentexpr', …) options.

Solution:
- Store "func"/"expr" options as `Callback` instead of string.
- Delete oceans of copy-pasted code.
- BREAKING: LuaRef returned via RPC/Vimscript is now represented as
  `"<Lua N: file:line>"` (like what `:map` shows) instead of `nil`.
- Note: `man.vim` still uses `v:lua` string, bc it's a vimscript ftplugin.

Helped-by: Lewis Russell <lewis6991@gmail.com>
2026-07-31 21:50:04 +02:00
Justin M. Keyes
917232b508 Merge #40953 from barrettruth/feat/zip-extract
feat(zip): extract archive entries
2026-07-31 15:45:14 -04:00
zeertzjq
41378d4610 vim-patch:e241ac0: runtime(zip): fix failure on Windows CI
Problem:  The zip autoload script aborts loading when the "zip"
          command is not available, so even read-only browsing of an
          archive fails with E117 (zip#Browse undefined) on systems
          that have "unzip" but not "zip" (e.g. the Windows CI
          runner).  Regressed in b0e0b22.
Solution: Drop the load-time executable gate and check each command
          per operation instead, so a missing "zip" only affects
          writing.  Update the test to match the reworded message.

e241ac0a62

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-07-31 09:32:40 +08:00
zeertzjq
659259d736 vim-patch:99921ff: runtime(marko): improve syntax highlighting
closes: vim/vim#20874

99921ffc39

Co-authored-by: Brian Carbone <brian@briancarbone.com>
2026-07-31 09:28:56 +08:00
zeertzjq
0e3e15d161 vim-patch:b0e0b22: runtime(zip): Improve Compatibility for powershell 5 and pwsh 7
related: vim/vim#20832

b0e0b22535

Co-authored-by: curbe454 <asu454@outlook.com>
Co-Authored-By: curbe454 <asu454@outlook.com>
2026-07-31 09:28:28 +08:00
Justin M. Keyes
6cdab150bc docs: misc #41063 2026-07-30 15:09:19 -04:00
Barrett Ruth
c1a65ff353 docs(tui): kitty keyboard protocol flags #41056
Nvim has sent CSI > 3 u since 4fb3b57a19, but tui.txt still documented
CSI > 1 u.
2026-07-30 05:50:39 -04:00
zeertzjq
a85cce90e3 vim-patch:partial:b4ae16c: runtime(doc): clarify 'laststatus' effect (#41052)
fixes: vim/vim#20875

b4ae16ca3e

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-07-30 00:11:46 +00:00
zeertzjq
943df84fb6 vim-patch:f26970c: runtime(karel): improve indent plugin (#41053)
closes: vim/vim#20873

f26970ce56

Co-authored-by: Patrick Meiser-Knosowski <knosowski@graeffrobotics.de>
2026-07-29 22:59:15 +00:00
Barrett Ruth
3fdb74748a fix: review 2026-07-29 14:56:26 -05:00
Barrett Ruth
36204b4323 feat(zip): extract archive members 2026-07-29 14:32:37 -05:00
Barrett Ruth
f82cf8fd59 fix(zip): list a valid empty archive as empty 2026-07-29 14:32:36 -05:00
Barrett Ruth
e63cf57106 fix(zip): keep a leading dash from becoming a backend option 2026-07-29 14:32:36 -05:00
Barrett Ruth
e29af9c32f refactor(zip)!: builtin zip.lua plugin #40846
Problem:
The bundled `zip` plugin is implemented in Vimscript, making it harder to
maintain and build on with Nvim's Lua runtime infrastructure.

Solution:
Add an opt-out `zip.lua` browser backed by `nvim.dir`, and disable the legacy
Vimscript implementation by moving it to `pack/dist/opt/zip/`. Load it with
`:packadd zip`.
2026-07-29 12:54:43 -04:00
Nathan Zeng
1dbc766fa7 fix(ui2): clear empty cmdline after backspace #41043
Problem:
Cmdline area shows stale ":" after backspacing out of the command line.

Solution:
Clear the command line for empty commands. Note that `:<CR>` will now
clear the command line too.
2026-07-29 12:40:08 -04:00
flatplum
7b34bca2a6 docs(health): avoid warnings for dynamic filetypes #41036
Problem:
Dynamic filetypes defined by `vim.filetype.add` may show health warnings.

Solution:
Document a way to suppress these harmless warnings.
2026-07-29 09:03:53 -04:00
zeertzjq
1eba3a75da vim-patch:9.2.0870: filetype: marko files are not recognized (#41038)
Problem:  filetype: marko files are not recognized
Solution: Detect *.marko files as marko filetype, include a syntax
          plugin and add syntax tests (Brian Carbone)

References:
https://markojs.com
https://github.com/marko-js/tree-sitter
https://github.com/marko-js/language-server
https://v5.markojs.com/docs/editor-plugins/

closes: vim/vim#20863

95da62a910

Co-authored-by: Brian Carbone <brian@briancarbone.com>
2026-07-29 09:14:48 +08:00
zeertzjq
a8626466e8 vim-patch:70d55cd: runtime(m4): Prevent the m4Disabled region from nesting within itself. (#41037)
closes: vim/vim#20801

70d55cd516

Co-authored-by: Sam Williams <sam@badcow.co>
2026-07-29 09:14:14 +08:00
Barrett Ruth
0d36e61d70 fix(dir): "-" on a non-file buffer opens a bogus path #41034 2026-07-28 13:37:06 -04:00
Evgeni Chasnovski
4bba83b4b7 fix(pack): do not write the lockfile when installing from it #41031
Problem: Installing plugins during lockfile synchronization always
  writes the lockfile, even though its content is used during install.
  This might be a problem if the lockfile (itself or its parent
  directory) is not writeable (can only be read).

Solution: Do not write the lockfile when installing directly from it.
  This is okay since the `src` and `rev` are used directly from the
  lockfile and don't change at this step. While potential change in
  `version` (that must be written to the lockfile) is handled in other
  code path.
2026-07-28 09:46:13 -04:00
glepnir
3fa5904cf2 fix(lsp): multibyte fragment treated as commit char #41019
Problem:
commit_chars_str() reads a 0x80-0xBF byte as a 2-byte lead, so
"\xA9x" makes "x" a commit character. nvim_get_hl() returns
a dict, so `#` on it is 0 whether or not the group exists

Solution:
use vim.str_utf_end() and drop entries that are not one whole
character. use next check dict length.
2026-07-28 08:39:03 -04:00
glepnir
916a6e9546 fix(eval): complete_info() equal, preselect, commit_chars #41022
Problem:  complete_info() does not report "equal", "preselect" or "commit_chars".

Solution: Report them for the items that set them.
2026-07-28 07:24:58 -04:00
Olivia Kinnear
5226e26e99 feat(pos): vim.pos.cursor() without args returns curwin pos #40975 2026-07-28 07:21:45 -04:00
altermo
59296a9fef fix(treesitter): incremental selection: "vin" not always starts "v" #41016 2026-07-28 06:14:32 -04:00
Barrett Ruth
93f427f603 docs(dir): buffer state discarded by 'bufhidden' #41014 2026-07-28 06:12:01 -04:00
zeertzjq
5745ea93f1 vim-patch:9.2.0860: filetype: xilinx design constraint files are not recognized (#41024)
Problem:  filetype: xilinx design constraint files are not recognized
Solution: Detect *.xdc files as tcl filetype (Wu, Zhenyu)

Reference:
https://docs.amd.com/r/en-US/ug903-vivado-using-constraints/About-XDC-Constraints

closes: vim/vim#20853

247a4cb45e

Co-authored-by: Wu, Zhenyu <wuzhenyu@ustc.edu>
2026-07-28 18:11:29 +08:00
Milad Rashidikhah
20ff82d9fc fix(treesitter): clamp unbounded fold ranges
Problem:
Tree-sitter uses UINT32_MAX for full-document ranges, which becomes -1 on 32-bit platforms and reaches _foldupdate as an invalid end row.

Solution:
Treat negative changed-range end rows as unbounded and clamp them to the buffer line count. Add a regression test that simulates the 32-bit sentinel.

AI-assisted: Codex
2026-07-28 11:00:30 +02:00
Barrett Ruth
e3c5974adf feat(dir): open cwd with 1- #40948 2026-07-27 18:30:54 -04:00
Justin M. Keyes
fbcb7a056c feat(exmode): "1q:", :exmode #41010
Problem:
Want `gQ` for _le multicursor_.

Solution:
- Don't use `gQ` for exmode.
- Introduce `:exmode`.
- Introduce `[count]q:` as an alias to `:exmode`.
2026-07-27 11:12:47 -04:00
Josh Hirschkorn
97a71ab484 fix(man): use direct lookup without manpath #40421
Problem:
On NetBSD, `man -w open` can return the exact manpage path, but `:Man`
may still fail when man directories cannot be discovered from `manpath
-q`, bare `man -w`, or `$MANPATH`.

Solution:
Fall back to the direct manpage lookup when directory discovery fails.
Add a test for resolving `open(2)` through `goto_tag()` without manpath
data.
2026-07-27 13:20:46 +00:00
Justin M. Keyes
80cd482577 fix(lua): vim.regex():match_str abort in Luv callback #41008 2026-07-27 11:01:54 +00:00
Justin M. Keyes
359459dec6 refactor(exmode): Ex-mode as cmdwin + Lua #40991
Problem:
POSIX-compatible Ex-mode requires special-cases all over the codebase to
match various quirks that don't actually matter to users.
- The main utility of *interactive* Ex-mode is its REPL behavior, and
  that can be achieved with `cmdwin`, which also gains extra UX
  benefits.
- The main utility of *non-interactive* `nvim -es` is for shell
  scripting, where Ex-mode quirks are mostly unhelpful (e.g. the
  "Entering Ex mode" message).

Solution:
- Reimplement *interactive* Ex-mode as a "persistent, insert-mode
  cmdwin" in Lua.
  - "nvim -e/-E" is simply an alias to "gQ".
- Reframe *non-interactive* Ex-mode (`nvim -es`) as "script mode".
  - Drop POSIX Ex-mode quirks.

Improvements:
- "nvim -V1 -es" output ends with a final newline!
- "nvim -V1 -es" no longer shows the "Entering Ex mode" msg. (This was
  pointless noise, unwanted for scripting purposes.)
- stdin is no longer typeahead. Scripts (":lua io.read()") can read
  stdin as data.
- Empty line is a no-op: a stray blank line no longer moves the cursor
  (deviates from POSIX ex "+1"), no longer exits 1 at EOF (E501).

Preserved behavior:
- cursor starts at "$"
- mode()=="cv" (for non-interactive)
- multiline commands (:append/:function/heredoc pull continuation lines)
- bare-range print
- :print=>stdout
- -V1=>stderr
- CRLF input
- continue-after-error and exit codes

Dropped (regressed) POSIX behavior (non-interactive):
- Event loop only ticks while/between commands, not while blocked
  waiting for a stdin line.
- ":g/pat/visual...Q"
- input()/getchar()/":s/x/y/c" no longer consume stdin lines as
  answers: Nvim stops at end-of-input, skipping the rest of the script,
  exit 0. Use ":lua io.read()" instead.
  - If users care about this they should use interactive Ex-mode (`gQ`).
- ":@r" stops at end of the register instead of continuing to read
  cmdline input from stdin.
2026-07-27 06:25:21 -04:00
zeertzjq
1c83e43f27 vim-patch:916809a: runtime(python): highlight the 'lazy' soft keyword
Lazy imports (PEP 810, to be released in Python 3.15) introduces a
`lazy` soft keyword that's recognized when it precedes a `from` or
`import` keyword.

closes: vim/vim#20342

916809ae1e

Co-authored-by: Jon Parise <jon@indelible.org>
2026-07-27 06:31:58 +08:00
zeertzjq
1d36cf1dbe vim-patch:f88e719: runtime(python): Fix indenting for brackets within python byte strings
Problem:  s:SearchBracket()'s skip-expression matches syntax group
          names ending in "Comment", "Todo", or "String" to decide
          whether a candidate bracket is inside a string/comment
          and should be skipped for indentation purposes. Byte and
          raw-byte string literals (b"...", rb"...") are highlighted
          via the pythonBytes/pythonRawBytes syntax groups, which
          don't end in "String", so brackets inside them (e.g.
          b"[") were never skipped and were counted as real,
          unmatched brackets, producing incorrect indentation.

Solution: Add "Bytes" to the indent script's existing suffix match,
          so pythonBytes/pythonRawBytes are recognized directly, the
          same way pythonString/pythonFString/pythonRawString
          already are.

          This supersedes an earlier version of this fix that
          renamed pythonBytes/pythonRawBytes to
          pythonBytesString/pythonRawBytesString in
          runtime/syntax/python.vim.

fixes:  vim/vim#20812
closes: vim/vim#20827

f88e7191da

Co-authored-by: qwavies <qwavsbusiness@gmail.com>
2026-07-27 06:31:40 +08:00
zeertzjq
ef93e93958 vim-patch:4e3df44: runtime(indent-tests): Annotate timed "search*()"es for tracing
related: vim/vim#17116

4e3df44aa2

Co-authored-by: Aliaksei Budavei <0x000c70@gmail.com>
2026-07-27 06:31:33 +08:00
Rob Pilling
c57818bb43 fix(ui2): avoid flickering fileinfo messages #41002
## Flicker cause

ui2's `check_targets()` function creates the hidden ui2 windows with this call chain:
```
nvim_open_win()
win_set_buf()
do_buffer()
set_curbuf()
enter_buffer()
```

and `enter_buffer()` sets `need_fileinfo`:

fdc09be03c/src/nvim/buffer.c (L1837-L1839)

This is then picked up by `normal_redraw`:

fdc09be03c/src/nvim/normal.c (L1381-L1385)

The fileinfo message then causes a ui2 window to appear to display it:

fdc09be03c/runtime/lua/vim/_core/ui2/messages.lua (L325-L330)

... which ends up calling `set_pos`, which registers an `on_key` handler:

fdc09be03c/runtime/lua/vim/_core/ui2/messages.lua (L726-L728)

This handler closes the ui2 window when the user presses, for example, `l` (because the user's not focusing said window).
The handler eventually calls `check_targets()`:

fdc09be03c/runtime/lua/vim/_core/ui2/messages.lua (L594-L595)

and `check_targets()` takes us back to the beginning, causing the ui2 window flicker

## Repro

```vim
=require("vim._core.ui2").enable()
set ch=0 shm-=F ve=all
e /tmp/x
```

Then hit `Ctrl-G` to show fileinfo (if not already shown) and hold `l`

## Fix

Effectively surround the ui2 window creating with `:silent`
2026-07-26 17:40:06 -04:00
Artem Krinitsyn
fdc09be03c fix(help): g==: 'No code block found' #40990
Problem:
The code block query relied on a bug fixed in commit
7ed5609439, where a trailing newline was
not included in a node's text.

Solution:
Fix the query to expect the newline.
2026-07-26 12:27:30 -04:00
Artem Krinitsyn
dec3d8215d fix(text): indent() ignores expandtab when indent unchanged #40932
Problem:
After expanding tabs with the `expandtab` option, if the old indent
matches the requested one, `vim.text.indent()` returns the input
unchanged.
The optimization path assumes that if old_indent == size, the input
wouldn't be changed, which is not correct when old_indent is formed by
expanded tabs.

Solution:
Apply the optimization only when `expandtab` is not set.
2026-07-26 06:24:39 -04:00
Justin M. Keyes
6539bd6602 Merge #40910 from barrettruth/fix/dir-literal-env-paths 2026-07-26 06:11:01 -04:00
zeertzjq
11cad372ef vim-patch:fb1a2e9: runtime(sh): fix Bash/Ksh array highlighting after an escaped paren
fixes:  vim/vim#18712
closes: vim/vim#20705

fb1a2e9d13

Co-authored-by: frapank <francesco.pankov+github@proton.me>
2026-07-26 09:02:02 +08:00