Commit Graph

11295 Commits

Author SHA1 Message Date
zeertzjq
318d6a7f59 vim-patch:2c0318d: runtime(doc): fix typo in netrw help file (#41228)
closes: vim/vim#20968

2c0318d285

Co-authored-by: Rochish Manda <28740792+Rochish-Manda@users.noreply.github.com>
2026-08-08 09:26:00 +08:00
Justin M. Keyes
33a688f9fe fix(messages): dangling progress-messages #41222
Problem:
Some builtin features emit progress-messages which never "complete".
- On failure, `:write` does not complete the progress-msg it started.
- ins-completion never ends its "Scanning..." message.

Solution:
- `buf_write()` emits "failed" status on failure.
- `ins_compl_stop()` ends the completion one.
2026-08-07 16:10:02 -04:00
Mike J McGuirk
fe3aa64945 feat(lsp): pass target buffer to reuse_client predicate #41163
Problem: The reuse_client predicate does not pass the target buffer,
preventing decisions from being truly made per buffer.

Solution: Pass the target buffer.
2026-08-07 11:27:19 -04:00
Justin M. Keyes
2e0a5a596a fix(terminal): spawn in effective CWD #41211
Problem:
`:terminal` does not respect the invocation-time CWD.
This wasn't noticeable with `:lcd` because the window-local CWD gets
applied to the new terminal buffer. But it is noticeable with `:bcd`.

Solution:
Specify `cwd` in the job spec.
2026-08-07 07:44:19 -04:00
Justin M. Keyes
a4a544032a feat(cwd)!: :lcd! (bang), rearrange :bcd/:lcd/… scope precedence #41194
Problem:
- buf-local CWD scope is lower priority than :lcd, which is weird.
  ```
  win > buf > tab > global
  ```
- No way to clear current CWD at a given scope.

Solution:
- Rerrange scope precedence to:
  ```
  buf > win > tab > global
  ```
- Introduce "bang" variants (`:bcd!`/`:lcd!`/`:tcd!`) which clears the
  local CWD for the given scope.
2026-08-07 04:41:37 -04:00
zeertzjq
9c738cb718 vim-patch:9.2.0920: filetype: json-ld files are not recognized
Problem:  filetype: json-ld files are not recognized
Solution: Detect *.jsonld files as jsonld filetype, include
          filetype, indent and syntax plugins (Bogdan Barbu).

Reference:
https://www.w3.org/TR/json-ld11/

closes: vim/vim#20954

a1e2198a2c

Co-authored-by: Bogdan Barbu <l4b.bogdan.barbu@gmail.com>
2026-08-07 12:36:41 +08:00
zeertzjq
925ddb190f vim-patch:90e8cb0: runtime(sh): Fix shFunctionTwo and shFunctionFour definitions for Bash
Claim e.g. "function f () { :; }" as shFunctionTwo while
observing that parentheses after the function name are
optional when the "function" word is used and do not delimit
its body if the latter follows them in "{}" (which should
not be taken for granted with limited backtracking).

closes: vim/vim#20878

90e8cb0094

Co-authored-by: Aliaksei Budavei <0x000c70@gmail.com>
2026-08-07 12:35:04 +08:00
zeertzjq
ba823836cf vim-patch:bfc7604: runtime(sh): Do not conflate comments and function declarations in Bash
Bash identifiers declared in scripts cannot have a leading
"#" in their names.  And neither "namespace" nor "function"
can be followed by a newline before an identifier.

related: vim/vim#20878

bfc7604678

Co-authored-by: Aliaksei Budavei <0x000c70@gmail.com>
Co-authored-by: Christoffer Aasted <dezzadk@gmail.com>
Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2026-08-07 12:34:54 +08:00
Justin M. Keyes
eb19a52b7c feat(vim._with): keepcwd 2026-08-06 13:17:07 +02:00
Justin M. Keyes
1c1dc0558f feat(cwd): support explicit chdir (:bcd/:tcd/…) in temp context
Problem:
- Explicit `:bcd` (etc.) persists from `nvim_buf_call()` but not from an
  autocmd handler targeting a hidden buf (`LspAttach`, `TermRequest`, …),
  which needs a `vim.schedule()` workaround.
- `vim._with()` is supposed to work as a "sandbox", discarding
  side-effects, but it leaks CWD changes: `:lcd` from a `win` context,
  any chdir from a visible-buffer context.

Solution:
- Explicit :cd/:tcd/:bcd during a temp context persists by default.
  - "Ambient" directory changes ('autochdir', existing win-local CWD,
    etc.) are still undone, as before.
- Add `kCtxKeepDirs`: snapshot/restore the target's full CWD state
  (w/b/tp-local, global, cwd). Used by `vim._with()` and `'inccommand'`,
  which must not leak state.
2026-08-06 13:17:07 +02:00
Justin M. Keyes
9a93ac6533 refactor(vim.fs): slug() minor cleanup 2026-08-06 10:27:29 +02:00
Justin M. Keyes
7d2249c579 docs: misc, :bcd, slug() 2026-08-06 10:27:29 +02:00
Barrett Ruth
8b0f33a1ab feat(dir): set buffer-local CWD #41174 2026-08-06 03:39:53 -04:00
zeertzjq
139ffd91de vim-patch:8c93e2d: runtime(make): variables in make target lists use wrong highlighting (#41183)
Problem:  Variables in make target lists are highlighted as targets when
          the prerequisite list is non-empty.
Solution: Match target lists separately from prerequisite regions so
          that contained identifiers are highlighted correctly.  Add
          regression test.

closes: vim/vim#20947

8c93e2d50d

Co-authored-by: Bogdan Barbu <l4b.bogdan.barbu@gmail.com>
2026-08-06 08:06:25 +08:00
Olivia Kinnear
6107629c5b feat(fs): vim.fs.normalize{plain:boolean} #41127
`opts.plain=true` does not expand tildes in addition to environment
variables, unlike `opts.expand_env=false`.

`opts.expand_env=false` is soft-deprecated.
2026-08-05 16:11:13 -04:00
Justin M. Keyes
ab80ea92cc fix(ui2): pager handling #41179
- Avoid shared state. Pass `focus` to set_pos()/expand_msg() instead of
  a shared `pager_focus` flag: the flag is only cleared when set_pos()
  actually enters the pager, so ":messages" from inside the pager left
  it set.
- pager_shown(): the pager window is invalid after leaving it with "q".
- Reuse pager_shown() in expand_msg().
2026-08-05 15:07:19 -04:00
Erdiansyah
a29a9130a9 fix(ui2): do not steal focus when consecutive cmds emit messages #41062
Problem:  A message emitted while a previous expanded message is still
          visible opens the pager and enters it, moving focus away from
          the buffer window without an explicit request (#41061).
Solution: Only enter the pager when it was explicitly requested ("g<",
          :messages, or entered from the expanded cmdline). An unfocused
          pager is dismissed by the cmdline key handler, which stays armed
          across the cmdline and no longer dismisses on non-typed keys
          (#39221).
2026-08-05 14:07:59 -04:00
Oleh Kostiuk
23525dd4e3 fix(editorconfig): avoid trim_trailing_whitespace in insert-mode #41175
Problem:
During insert-mode / replace-mode, `autowrite` may trigger. If it does, the
cursor position can shift due to the automatic removal of trailing spaces on the
current line. When I resume typing, the space between the last word and the new
word is suddenly gone.

Solution:
Disable the "remove trailing spaces" handler during Insert (or a similar) mode.
Autosave logic is not affected.
2026-08-05 14:06:28 -04:00
Barrett Ruth
69664a0aca fix(zip): preserve alternate file #41178 2026-08-05 13:37:24 -04:00
Barrett Ruth
9127ed41a5 fix(dir): preserve alternate file #41177 2026-08-05 13:36:58 -04:00
zeertzjq
743a8d448c vim-patch:5a1124e: runtime(c): compound literal braces are highlighted as errors
Problem: Braces in C compound literals and initializers inside parentheses
         and brackets are highlighted as errors.

Solution: Recognize those initializer blocks while preserving syntax recovery
          for malformed parentheses.

fixes:  vim/vim#18709
closes: vim/vim#20842

5a1124e4f5

Co-authored-by: Bogdan Barbu <l4b.bogdan.barbu@gmail.com>
2026-08-05 07:02:22 +08:00
zeertzjq
e795115351 vim-patch:aeac948: runtime: Update Syntax Menus
Update makemenu.vim and re-generate synmenu.vim (using make menu).

closes:  vim/vim#20932
related: vim/vim#20930

aeac948c62

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-08-05 07:00:46 +08:00
zeertzjq
7fd2c868f7 vim-patch:f620c30: runtime(dart): Update compiler plugins
Use the unified dart command for all.

closes: vim/vim#20936

f620c30018

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2026-08-05 07:00:46 +08:00
Willaaaaaaa
7b03df5d54 feat(lua): vim.fs.slug() #41005
Problem:
Several subsystems need to derive a short, filesystem-safe identifier from an
arbitrary path, and each reinvents it ad-hoc:
- `'undodir'` and `swapfiles` encode the full path into a single filename, which
  may exceed filesystem length-limits.
- `:connect ssh://` needs the SSH ControlPath socket name to stay under the
  104-byte `sun_path` limit on macOS; today the path overflows it.
- the upcoming :terminal state dir.
- arbitrary plugin purposes.

Solution:
Provide `vim.fs.slug()`, which generates a bounded, one-way filename from an
arbitrary string. The input is normalized so equivalent paths produce the
same result. An 8-char hash is appended for uniqueness
2026-08-04 15:24:35 -04:00
Justin M. Keyes
9cd4dd1c19 fix(:bcd): do not "inherit" buffer-local dir
Problem:
Buffer-local CWD (:bcd) is "sticky", similar to window-local CWD (:lcd).
But this contradicts one of its main benefits: per-buffer "project root"
for LSP, OSC7.

Other problems:
- A buffer created with :edit/:enew/:new silently inherits b_localdir
  (and b_prevdir) from the previous buffer.
- curbuf_reusable() refuses to recycle a scratch buffer that has
  `b_localdir`.
- After :new/:vnew/:tabnew the CWD sticks to previous buffer's
  `b_localdir` even though the new curbuf has none, so :new is not
  equivalent to ":split | enew", and getcwd() disagrees with
  haslocaldir().
- Requires "which buffer spawned this buffer" semantics that no other
  buffer-local state has.

Solution:
Drop sticky/inherit behavior of buffer-local CWD (:bcd).

- do_ecmd: always apply the new curbuf's dir (`fix_current_dir`), like
  `do_autochdir` already does. :tabnew from a :bcd buffer now reverts to
  global CWD (and fires DirChanged), same as :tabnew from a :lcd window.
- curbuf_reusable(): recycling a scratch buffer frees its b_localdir.

To get sticky/inherit behavior of CWD, use `:lcd`.
2026-08-04 20:48:44 +02:00
Justin M. Keyes
46ca236525 fix(cwd): validate getcwd(…, -1) 2026-08-04 20:48:44 +02:00
Justin M. Keyes
db2e86fba4 refactor(editor): cleanup change-directory (:bcd) logic 2026-08-04 20:48:05 +02:00
saher
ea3868bcf9 feat(editor): :bcd changes buffer-local directory
Problem:
No way to set a buffer-local directory.
Use-cases:
- "Root dir" for LSP (and the "project" concept).
- `:terminal` OSC 7

Solution:
Add `:bcd` command.

- Extend `getcwd()` to take a third arg; `getcwd(-1, -1, bunfr)` returns
  the buffer-local working directory.
- Buffer-local directories have less priority than window-local
  ones, and more priority than tab-local ones.

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-08-04 20:09:48 +02:00
Justin M. Keyes
dab5fab948 Merge #41114 from epithet/default-ruler-as-expression 2026-08-04 06:51:34 -04:00
Justin M. Keyes
8589447159 feat(detach): opt-in to "server keeps running" #41133
Problem:
By default, `nvim` does not survive if its host terminal dies. This is
inconvenient if you want to use Nvim as a "session manager" (like tmux).

Solution:
Let users opt-in to the "survive" behavior via `:detach!` (bang "!").
This marks the current UI as "detachable", so the server will not
self-exit if the UI channel closes.
2026-08-04 06:20:16 -04:00
Sébastien Hoffmann
ca07e505f9 refactor(ruler)!: replace C implementation with 'rulerformat' expression
Problem:
The default 'ruler' is implemented in C instead of the 'statusline' DSL.

Solution:
Replace the C implementation with a default 'rulerformat' expression.
This is a continuation of #1248 and #33036.

Advantages:
- configuration is more discoverable, the default being a useful example
- users and plugins can augment the default
- code reuse and less C code to maintain
- ui2: due to the use of an item group with `minwid`, it can expand
  instead of truncating when the content gets too long, which is
  particularly useful for locales with long translations of Top/Bot/All

Implementation details:
As is the case for 'statusline', when trying to set 'rulerformat' to an
empty string, the default expression is restored instead, mimicking how
previously the default C implementation would have been activated.
Just like before, `:set rulerformat=` and `:set rulerformat&` have the
same effect, and the ruler is disabled with `:set noruler`.

The default expression uses an item group with `%=`, unlike the fallback
in the previous default statusline `%-14.(%l,%c%V%) %P`, because the
total width and how it is configured is immediately clear without
documentation, it is a more useful pattern in general that works when
both sides have flexible width, and it also works for vim, which is
useful for configuration sharing/reuse.

A truncation marker `%<` is added at the end to mimic how at small
screen widths, the scroll percentage would disappear first, so that the
cursor position can remain fully visible.

BREAKING CHANGES:
- `&rulerformat` can no longer be set to an empty string
- ui2: the default ruler is no longer of fixed width, but can expand
- at very small screen widths (< 36 columns)
  - ui2: it will no longer try to shrink white-space before truncating
  - it truncates gradually from the right, whereas previously, the
    scroll percentage would disappear all at once
- l10n can no longer add a space after the comma between line and column
  (this was only done for one language: Ukrainian)
2026-08-04 12:12:23 +02:00
bfredl
0abc9ccc19 Merge pull request #40772 from Rawan10101/wasm-browser
feat(wasm-emcc): add browser support for Neovim
2026-08-04 12:11:17 +02:00
Barrett Ruth
a29297ac53 docs(api): buffer columns are byte indices #41137 2026-08-04 05:19:54 -04:00
Rocco Vaccone
d0644230f1 fix(lsp): ignore (and log once) invalid documentSelector globs #41055
Problem:
Client:_get_registrations() errors if a documentSelector pattern is not
a valid glob (e.g. "**/**.dart" from dartls). The error discards
already-matched registrations and propagates to supports_method() and
the client/registerCapability handler, disabling capabilities unrelated
to the offending pattern.

Solution:
Skip invalid globs. Treat them as non-matching, and log once per client.

(Similar approach was taken for filewatcher globs: 4d9e5acfb5)
2026-08-04 05:14:15 -04:00
Justin M. Keyes
c875b16714 Merge #41112 from erdivartanovich/dir-failed-open-recovery 2026-08-04 05:04:07 -04:00
Justin M. Keyes
434792787b Merge #41093 from barrettruth/feat/zip-finish 2026-08-04 04:46:33 -04:00
Sébastien Hoffmann
259e6fa9cc fix(ruler)!: consistent width in last line and statusline
Problem: Traditionally, the ruler in the last line is one cell shorter
than in the statusline, leaving the last cell of the screen blank.
According to code comments, this is in order to prevent unwanted
scrolling on "some" (unspecified, but presumably ancient) terminals.
Berkeley vi is more specific in its `vs_modeline` function: dumb
terminals with hardware scroll, SunOS 4.1.1 and Ultrix 4.2 curses.
(n)curses still has a similar limitation in `(w)addstr`, but apparently
only for historical reasons.

Maintaining the different widths leads to awkward inconsistencies when
the ruler is configured with 'rulerformat', except for the special case
where it contains a top-level `%=`. Shifting the ruler in the last line
to the left would be a solution, but the empty cell at the end doesn't
seem to be relevant anymore.

Solution: extend the ruler in the last line all the way to the right
edge of the screen, just like in the statusline. The exact same amount
of place will be available to the rest of the UI as before.

BREAKING CHANGE:
- the default ruler width is now 18 cells
- the last cell of the screen is no longer empty

Closes #41076
2026-08-04 06:36:58 +02:00
zeertzjq
8d2b50c0ce vim-patch:c0da866: runtime: Add TOML entry to the syntax menu (#41145)
fixes:  vim/vim#20927
closes: vim/vim#20930

c0da86685a

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2026-08-04 08:41:13 +08:00
Barrett Ruth
755abbc8d5 fix(zip): only refuse a cwd unzip on Windows 2026-08-03 15:35:30 -05:00
Barrett Ruth
886a270e7f refactor(zip)!: address entries with zip:// paths
Problem:
`zipfile://{archive}::{entry}` is ambiguous: `::` is legal in both an
archive path and an entry path, so the separator cannot be identified.
Splitting at the last `::` reads archives correctly but breaks entries
that contain it, and the plugin then emits buffer names it cannot read
back.

Solution:
Address entries as `zip://{archive}/{entry}`, joining the two paths.
Resolve the split by walking components: the first one that is a regular
file is the archive, because a regular file cannot have children on disk.
Entry paths may then contain any character, and no escaping is needed.

zipPlugin.vim keeps its own scheme, so the Java ftplugin emits whichever
form matches the active plugin until the legacy package is removed.
2026-08-03 15:22:25 -05:00
Barrett Ruth
8787b8b9b6 fix(zip): do not run unzip from the current directory
Problem:
Windows searches the current directory before $PATH, so opening an archive
in a directory that also contains an `unzip` executable runs that one. The
legacy plugin refused this; the port dropped the check.

Solution:
Refuse to run `unzip` when it resolves to the current directory.
2026-08-03 15:22:25 -05:00
Justin M. Keyes
794886aae7 Merge #41088 from barrettruth/feat/zip-health-encryption
feat(zip): checkhealth and encrypted entries
2026-08-03 16:05:41 -04:00
Maria Solano
1e6d4479d2 fix(lsp): only send didSave to clients attached to the buffer (#41126) 2026-08-03 11:43:33 -07:00
erdivartanovich
0e44ef231a fix(dir): do not swallow errors raised after the list callback
Problem:  An error raised after the list handler ran (e.g. while
          rendering) unwinds through the pcall around provider.list()
          and is routed back into the now no-op handler: silently
          discarded.
Solution: Re-raise the error when the handler has already run.
2026-08-04 01:57:21 +08:00
erdivartanovich
d80121327f fix(dir): keep a listing buffer when the initial listing fails
Problem:  A failed initial directory listing discards the listing state:
          the user is left in an empty modifiable non-listing buffer, and
          the BufEnter autocmd retries the failing open, repeating the
          error on every re-entry.
Solution: Render the failure as an empty listing with state and handlers
          intact: the error is reported once and "R" or :edit retries the
          listing. Keep the error on the listing state so a failed
          listing is distinguishable from an empty one; the next list
          clears it.
2026-08-04 01:57:21 +08:00
Barrett Ruth
1e757a2feb fix(zip): do not warn when zip.lua is disabled 2026-08-03 11:53:20 -05:00
Barrett Ruth
d03b4cfb7a feat(zip): checkhealth and encrypted entries
Problem:
There is no health check. Encrypted entries cannot be read at all, since
Info-ZIP takes a password only from a terminal and `-P` would expose it
in the process arguments.

Solution:
Add `:checkhealth nvim.zip`, reporting the backend and which
implementation is handling archives. Prompt for the password on a pty,
extracting to a file so the entry's bytes stay off the terminal. Report
Info-ZIP's exit code rather than inferring a cause, so an archive using
AES is not reported as a failed decryption.
2026-08-03 11:53:20 -05:00
rawan10101
5079787993 docs: mention wasm32-emscripten build target in news.txt 2026-08-03 15:40:16 +03:00
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