Commit Graph

4988 Commits

Author SHA1 Message Date
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
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
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
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
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
43b666cb27 vim-patch:770eb7d: runtime(doc): clarify expandcmd() and "~" behaviour
fixes: vim/vim#20793

770eb7db17

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
2026-07-26 09:01:32 +08:00
Barrett Ruth
1594ca2368 fix(dir): preserve environment variables in paths 2026-07-25 18:02:55 -05:00
Barrett Ruth
ac4e5460b1 feat(vim.fs): dir(opts.normalize) 2026-07-25 18:02:55 -05:00
Barrett Ruth
22d44ef875 fix(api): add lhs option for keymap deletion 2026-07-25 10:36:56 -07:00
Justin M. Keyes
715d8887ec docs: misc #40847
Co-authored-by: Barrett Ruth <br@barrettruth.com>
Co-authored-by: Nathan Zeng <nathan.j.zeng@gmail.com>
2026-07-25 12:47:51 -04:00
zeertzjq
db41e4c74f vim-patch:0c1a214: runtime(doc): Fix truncated sentence in :h map()
fixes: vim/vim#20725

0c1a214497

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-07-25 06:32:03 +08:00
zeertzjq
19c89b6d68 vim-patch:9.2.0849: filetype: osquery config files are not recognized
Problem:  filetype: osquery config files are not recognized.
Solution: Detect osquery.conf as jsonc filetype (Fionn Fitzmaurice).

Reference:
https://osquery.readthedocs.io/en/stable/deployment/configuration/#configuration-components

closes: vim/vim#20826

ea183ce4e5

Co-authored-by: Fionn Fitzmaurice <fionn@github.com>
2026-07-25 06:29:04 +08:00
Olivia Kinnear
bb104ba4db feat(health): improvements to :checkhealth #40935
Changes:
- Removed the blank line before the first healthcheck header.
- Fixed a bug where the entire "Terminal" section of `vim.health` would
  not appear if the `infocmp` executable was not found.
- Fixed a typo in `vim.lsp` when displaying the LSP log level.
2026-07-24 11:54:12 -04:00
Justin M. Keyes
f8cfd7f06a feat(options): schema, "dict" options, messages
Problem:
Options parsing is still painful for dict-style options.

Solution:
schema-maxxing => better `opt:get()` (will be the basis for `vim.o()`),
unified (and more-detailed) err msgs.

- Drop bespoke structure-builder in `_core/options.lua`.
- Define `schema` for all non-primitive options (except 'guicursor' and
  statusline-style options); generate reified keysets `OptKeyDict`).
  - Generate 'fillchars' => `fcs_tab`, 'listchars' => `lcs_tab`.
- `nvim_set_option_value`:
  - Return the improved structures. Also from `vim.opt.x:get()`.
  - Eliminate api <=> lua roundtrip, centralize option structure
    handling.
- Improve/unify errors.
  - Bump ERR_BUFLEN 80 → 256 so the "one of" list isn't truncated.
- Eliminate old 'diffopt' order-dependence (`iwhiteall` before `iwhite`)

Error samples:

    Typed-key path (opt_strings_check → diffopt/mousescroll/breakindentopt):
    E474: Unknown item 'foo'
    E474: 'context' requires a number
    E474: 'ver' number is out of range
    E474: 'algorithm' must be one of: myers, minimal, patience, histogram
    E474: 'filler' does not take a value

Related:

- #31084
- #34661
- #31820
- #14739
- #20107
- fix #18875
  - :get() returns `{ sbr = true, shift = '3' }` (reified-keyset) instead of `{'sbr', 'shift:3'}`
  - Setting via table now works too. `object_as_optval_for` `is_map` now recognizes struct options.
- fix #30296
  - instead of `E474: Invalid argument`, errors now look like:
    ```
    E474: Invalid value 'x', expected one of: single, double: ambiwidth=x
    E474: Unknown item 'foo': diffopt=foo
    E474: 'context' requires a number: diffopt=context:x
    ```

simplify `win_float_parse_option` from #26799.
2026-07-24 13:05:20 +02:00
Barrett Ruth
ce9cc43f23 fix(dir): open CWD from unnamed buffer with - mapping #40926 2026-07-24 06:45:13 -04:00
Maria Solano
66441e549d fix(text): validate opts.expandtab in vim.text.indent() #40936 2026-07-24 03:52:19 -04:00
glepnir
f95bd73935 feat(float): 'previewpopup' option #26799
Problem:
The preview-window (:pedit, etc.) always uses a split, but it would be
useful as a floatwin (or "popup").

Solution:
Support Vim's 'previewpopup' option.
2026-07-23 17:27:14 -04:00
zeertzjq
b81c60c3fa vim-patch:9.2.0830: the completion menu is not used on terminals without colors (#40917)
Problem:  When the terminal reports no colors ("t_Co" is 0 or 1) the
          insert mode completion popup menu is not shown at all, while
          the command line completion popup menu ('wildoptions' contains
          "pum") is shown.  In 'wildmenu' completion the current match
          cannot be told apart from the other matches (Maxim Kim)
Solution: Show the insert mode completion popup menu regardless of the
          number of colors and add "term" attributes to the default
          highlighting of Pmenu, PmenuSel and PmenuThumb.  The wildmenu
          is drawn with the attributes of the status line, which is
          reversed, and on most terminals the standout mode is the same
          as the reverse mode, thus use the underline mode for the
          default highlighting of WildMenu (Hirohito Higashi).

fixes:  vim/vim#20800
closes: vim/vim#20803

52485e0d24

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 07:40:11 +00:00
zeertzjq
05c5cf7e40 vim-patch:9.2.0836: filetype: .git-blame-ignore-revs file is not recognized (#40912)
Problem:  filetype: .git-blame-ignore-revs file is not recognized
Solution: Detect .git-blame-ignore-revs file as gitrevlist filetype,
          include syntax and filetype plugins (Fionn Fitzmaurice)

A Git revision list is

> a list of object names (i.e. one unabbreviated SHA-1 per line)...,
> comments (#), empty lines, and any leading and trailing whitespace are
> ignored.

(from Git's fsck.skipList documentation).

The default output of git rev-list will match this. It is also suitable
as input to git blame --ignore-revs-file.

This adds filetype detection matching .git-blame-ignore-revs files,
syntax highlighting and basic filetype settings.

closes: vim/vim#20702

a8d5be9284

Co-authored-by: Fionn Fitzmaurice <fionn@github.com>
2026-07-23 09:03:07 +08:00
Barrett Ruth
ada2007453 feat(dir): provider framework #40738
Problem:
The core behaviors of `nvim.dir` cannot be reused by consumers
such as the archive plugin, ssh browser, etc.

Solution:
- Define a basic "provider" shape.
- Extract the filesystem provider.
2026-07-22 13:21:39 -04:00
phanium
526365a8d1 fix(help): handle escape edge cases #40901
* fix(help): preserve multi-letter CTRL modifiers in :help subject

Problem: After PR 39537 normalized `CTRL-U-default` by excluding
`-` from the trigger char class, the regex `(CTRL%-[^{])([^-_\\])`
also fires between `CTRL-S` and the `H` of the `SHIFT` modifier
in tags like `c_CTRL-SHIFT-V`, splitting it into the non-existent
`c_CTRL-S_HIFT-V`.

Solution: Exclude uppercase letters from the char class so a
multi-letter modifier following `CTRL-X` (e.g. `SHIFT`, `ALT`) is
no longer split. The `-` exclusion from 39537 is preserved so
`i_CTRL-U-default` still works.

* fix(help): escape ~ in expr-=~? exception to keep regex valid

Problem: The `expr-=~?` exception in the tag alias table maps to
`=~?`, but in Vim's regex engine `~` refers to the previous
substitute pattern. With no prior substitute the pattern fails to
compile, so `:help expr-=~?` returns E149 even though the tag exists.

Solution: Escape `~` as \\\~` so the alias expands to a valid
regex (`=\\\~?`) that substring-matches the `expr-=~?` tag. Other
`expr-X?` entries are unaffected since they don't contain `~`.

* fix(help): don't insert _ before CTRL- when preceded by -

Problem: The rule `([^_])CTRL%- -> %1_CTRL-` inserts an underscore
between any non-underscore char and `CTRL-`, which wrongly rewrites
tags like `map-CTRL-C` and `telnet-CTRL-]` (where `CTRL-` is
literal text in the tag, not a key chord).

Solution: Exclude `-` from the trigger char class so a hyphen
immediately before `CTRL-` is preserved. The existing behavior for
`iCTRL-GCTRL-J` -> `i_CTRL-G_CTRL-J` is unaffected because the
`G` before `CTRL-J` is not `-`.

* fix(help): only treat ^X as caret notation for valid control chars

Problem: The regex `%^([^_])` converts any `^X` to `CTRL-X`,
including `:set^=` where `^=` is literal text in the tag, not a
caret-notation control character.

Solution: Restrict the transformation to caret-notation chars
(`%a` or one of `?@[\\]^{}`). This matches the C reference
behavior where `^X` is only converted when X is alphanumeric or one
of the control-notation punctuation chars. `{` is retained so
`^{char}` still maps to the `CTRL-{char}` placeholder tag.
2026-07-22 07:26:09 -04:00
zeertzjq
a277c08d98 vim-patch:9.2.0821: filetype: msmtp system-wide rc file not detected (#40895)
Problem:  filetype: msmtp system-wide rc file not detected (chdiza).
Solution: Detect 'msmtprc' as filetype msmtp, like '.msmtprc'
          (Doug Kearns).

fixes:  vim/vim#20751
closes: vim/vim#20752

88440f9a34

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2026-07-21 23:16:33 +00:00
Artem Krinitsyn
9180c6e093 fix(lsp): guard linked_editing_range refresh on attach (#40888)
Problem:
on_attach() calls refresh(), but there is no guarantee the attached
buffer is the current buffer. This can make linked editing request
handling assume the wrong window.

Solution:
Call refresh() only if the current buffer is attached. This keeps the
initial highlighting behavior while avoiding making incorrect request.
2026-07-21 10:32:13 -07:00
Sanzhar Kuandyk
a87e91677c fix(system): use native path for Windows executables #40885
Problem:
When 'shellslash' is set, exepath() returns forward-slashed paths.
Passing that path to vim.system() can prevent cmd.exe from launching.

Solution:
Convert the resolved executable path to native separators before spawning.
Add a Windows regression test for cmd.exe with 'shellslash' enabled.
2026-07-21 07:58:44 -04:00
Barrett Ruth
16c145d240 fix(ui2): preserve Visual mode messages #40828
Problem:
The existing `showmode` overlay can immediately cover messages emitted while
Visual mode is active, including the `g CTRL-G` word count.

Solution:
Protect Visual mode messages with the existing message delay and temporarily
hide the previous last-line overlay until it is restored.
2026-07-20 15:44:37 -04:00
Barrett Ruth
d343a1e230 fix(ui2): position message windows without autocmds (#40867)
Problem:  Fix applied in b2bb60d7 does not properly replace the normal command.
Solution: Restore normal command with `noautocmd` to resolve #40780.
2026-07-20 19:58:30 +02:00
Justin M. Keyes
317c5ddda6 fix(lsp): incorrect rendering of markdown codeblock #40861
Problem:
LSP hover erroneously drops blank lines before a 4-space-indented
codeblock, which is not valid Markdown. This causes incorrect parsing
and wrong display.

Solution:
Fix `split_lines` so that it doesn't drop the blank line just before
a 4-space-indented codeblock.

fix https://github.com/neovim/neovim/issues/40860
2026-07-20 10:03:11 -04:00
PinkLea
a56b74bde3 feat(lua): Iter:count() #40831 2026-07-20 09:53:06 -04:00
penglei
84fd9214cc fix(diagnostic): skip out-of-range lnum in underline handler #40839
Problem:
`vim.diagnostic.handlers.underline.show` throws `E565: Index out of bounds` when
it tries to underline a diagnostic whose `lnum` is past the end of the buffer.
This happens with stale diagnostics set on an unloaded buffer (e.g. via
`bufadd()`) that are drawn only after the buffer is loaded: by then the file on
disk can be shorter than the `lnum` the diagnostic carried. File pickers
(snacks.nvim) that open files via `bufadd` + `:buffer` hit this whenever an LSP
server has already emitted diagnostics for that URI.


Solution:
Skip diagnostics with an out-of-range `lnum` in the underline handler.

Other handlers `M.virtual_text.show()`, `M.signs.show()`, have a similar condition.
2026-07-20 06:59:21 -04:00
Rocco Vaccone
01c4d37959 fix(lsp): preview window converted to normal window is auto-closed (#40770)
Problem:
A floating preview window (hover, signature help) converted to a normal
window (e.g. with CTRL-W_H or nvim_win_set_config()) is still closed by
the open_floating_preview() autocommands, and a later preview may focus
or close it as if it were still a float.

Solution:
When the preview window is no longer floating, remove its auto-close
autocommands and stop tracking it as the buffer's floating preview.

Closes #36659
2026-07-19 17:16:56 -07:00
Justin M. Keyes
239125b8c8 feat(eval): declare more "fast" functions #40834 2026-07-19 10:03:53 -04:00
Justin M. Keyes
6f5fae3f8c fix(lua): vim.keycode cleanup #40817 2026-07-18 14:31:36 -04:00
altermo
a2dfa195b2 feat(lua): vim.keycode() gets structured parse result #38636
Problems:
1. Can't get individual parts of a key-chord separately: modifiers, key.
2. Can't separate a key-combo into individual key-chords.

Solution:
Enhance `vim.keycode()` to optionally return a structured parse result
as a list of key-chords:
- `key_raw` the key-chord (problem 2)
- `mod` the modifiers of `key_raw` (problem 1)
- `key_orig` the key part of the key-chord, only here if differing from `key`
  (this doesn't solve any of the above mentioned problems, but it may provide
  useful and it's (in terms of code) free)
- `key` a normalized version of `key_orig` (solving problem 1), example(the
  first is `key_orig` and second is `key`): `lt` and `<`, `Bar` and `|` (in
  `<C-Bar>`)
2026-07-18 12:20:41 -04:00
zeertzjq
721569dd9b vim-patch:9.2.0788: filetype: hip files are not recognized (#40809)
Problem:  filetype: hip files are not recognized
Solution: Detect *.hip files as hip filetype, include filetype, syntax
          and indent plugins, update makemenu.vim and synmenu.vim (Young)

Round out HIP (Heterogeneous-compute Interface for Portability) support
to mirror the existing CUDA files:

- autoload/dist/ft.vim: detect the ".hip" extension as filetype "hip"
- ftplugin/hip.vim: behave like C++ by sourcing ftplugin/cpp.vim
- indent/hip.vim: use cindent, like indent/cuda.vim
- makemenu.vim / synmenu.vim: add a Syntax menu entry

The syntax/hip.vim file already sources syntax/cpp.vim and adds the
HIP-specific keywords, matching syntax/cuda.vim.

closes: vim/vim#20773

b3ad239038

Co-authored-by: Young <young20050727@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 22:19:48 +08:00
Barrett Ruth
b2bb60d70a fix(ui2): avoid ModeChanged in message window #40788 2026-07-18 07:33:38 -04:00
zeertzjq
1520a4e3e6 vim-patch:9.2.0786: filetype: Containerfile is not recognized (#40807)
Problem:  filetype: Containerfile is not recognized
Solution: Detect *.[Cc]ontainerfiles as dockerfile filetype
          (Omer Tuchfeld)

closes: vim/vim#20783

Supported by AI.

6b62ae68c6

Co-authored-by: Omer Tuchfeld <omer@tuchfeld.dev>
2026-07-18 17:59:52 +08:00
Justin M. Keyes
446b9d8c55 docs: misc, remove some old help tags #40214
- Remove old help tags: they add noise to cmdline completion.

Co-authored-by: acehinnnqru <acehinnnqru@gmail.com>
Co-authored-by: KangaZero <samuelyongw@gmail.com>
Co-authored-by: Simone Ragusa <hi@interrato.dev>
Co-authored-by: Chinmay Dalal <~chinmay/public-inbox@lists.sr.ht>
Co-authored-by: coyaSONG <66289470+coyaSONG@users.noreply.github.com>
Co-authored-by: Olivia Kinnear <git@superatomic.dev>
2026-07-18 04:29:51 -04:00
Barrett Ruth
12e8db3847 fix(restart): distinguish v:exitreason for :restart! #40801 2026-07-18 04:07:14 -04:00
glepnir
9fae7234f6 feat(completion): support completionList.applyKind #40769
Problem: values from completionList.itemDefaults always replace the
item's own commitCharacters and data. Since 3.18 a server can ask for
them to be merged instead.

Solution: Handle CompletionList.applyKind and advertise applyKindSupport.
Drop itemDefaults once folded into the items: get_items() runs twice on
the same result and a Merge isn't idempotent.

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#completionItemApplyKinds
2026-07-17 21:07:01 -04:00
Justin M. Keyes
e0e7f65b74 refactor(detach): eliminate nvim__ui_detach #40793
Problem:
`nvim__ui_detach` was added in 85e0559d46 in order to implement
`detach_others` from Lua. Using Lua in this case is doing more harm than
good.

Solution:
Extract `ui_detach_channel`, which also allows it to be used for the
"self detach" path from `ex_detach`.

Bonus: the old MSWIN path always called `os_swap_to_hidden_console()`;
now `ui_detach_channel` only does so for a stdio channel. For the common
stdio TUI this is identical; for a socket UI it's more correct (no
parent console to swap).
2026-07-17 16:37:45 -04:00
Jason Woodland
85e0559d46 feat(ui): ":%detach!" detaches all other UIs #39216
Problem:
Not easy for one UI to kick the others off a shared Nvim server.

Solution:
Treat `:%detach` as detach-other-UIs.
2026-07-17 15:23:34 -04:00
Olivia Kinnear
58fe621cfc feat(health): rearrange vim.ui.img checks #40782 2026-07-17 07:09:04 -04:00