Commit Graph

976 Commits

Author SHA1 Message Date
luukvbaal
49c19a1fe3 fix(messages): message not flushed at end of command #37904
Problem:  Logic determining messages belonging to the last command to
          show with "g<" does not flush pending messages. This can
          result in clearing the temporary message history before a
          message still belonging to the previous command was emitted.
Solution: Flush pending messages when marking the end of messages
          belonging to previous command.
2026-02-16 11:51:43 -05:00
Maria Solano
6e1745e96e feat(lua): support vim.Range:has(vim.pos) #37879 2026-02-16 11:05:38 -05:00
Sean Dewar
51dc752e6c fix(prompt): wrong changed lnum in init_prompt
Problem: if init_prompt replaces the prompt line at the ': mark, it calls
inserted_bytes with the wrong lnum.

Solution: use the correct lnum. Call appended_lines_mark instead when appending
the prompt at the end.
2026-02-15 23:42:10 +00:00
Sean Dewar
3a10405214 fix(prompt): prompt_setprompt does not adjust extmarks, no on_bytes
Problem: prompt_setprompt does not adjust extmarks or trigger on_bytes
buffer-updates when fixing the prompt line.

Solution: adjust them, trigger on_bytes.

Notably, hides extmarks when replacing the entire line (and clearing user
input). Otherwise, when just replacing the prompt text, hides extmarks there,
but moves those after (in the user input area) to the correct spot.
2026-02-15 23:42:10 +00:00
Sean Dewar
7641177c5f fix(prompt): wrong cursor col after prompt_setprompt, no on_lines
Problem: prompt_setprompt calls coladvance with a byte column, but it expects a
screen column. on_lines buffer-updates aren't fired when fixing the prompt line.

Solution: don't use coladvance. Call changed_lines, which also simplifies the
redraw logic. (and calls changed_cline_bef_curs if needed; added test checks
this)

Unlike https://github.com/neovim/neovim/pull/37743/changes#r2775398744, this
means &modified is set by prompt_setprompt if it fixes the prompt line.
Not setting &modified is inconsistent anyway -- even init_prompt sets it if it
fixes the prompt line.
2026-02-15 23:41:32 +00:00
Dmytro Pletenskyi
01666aae64 feat(diagnostic): fromqflist({merge_lines}) #37416
Problem:
`vim.diagnostic.fromqflist` ignores lines that are `item.valid == 0` (see
`getqflist`). Many qflists have messages that span multiple lines, which look
like this:

    collection/src/Modelling/CdOd/Central.hs|496 col 80| error: [GHC-83865]
    ||     • Couldn't match expected type: InstanceWithForm
    ||                                       (FilePath
    ||                                        -> SelectValidCdInstWithForm
    ...

calling `vim.diagnostic.fromqflist(vim.fn.getqflist)` gets a diagnostic message
like this:

    error: [GHC-83865]

only the first line is kept, but often, the remaing lines are useful as well.

Solution:
Introduce `merge_lines` option, which "squashes" lines from invalid qflist items
into the error message of the previous valid item, so that we get this
diagnostic message instead:

    error: [GHC-83865]
         • Couldn't match expected type: InstanceWithForm
                                           (FilePath
                                            -> SelectValidCdInstWithForm
2026-02-14 06:07:01 -05:00
zeertzjq
9c5ade9212 fix: wait() checks condition twice on each interval (#37837)
Problem:  wait() checks condition twice on each interval.
Solution: Don't schedule the due callback. Also fix memory leak when
          Nvim exits while waiting.

No test that the condition isn't checked twice, as testing for that can
be flaky when there are libuv events from other sources.
2026-02-13 21:02:40 +08:00
Elijah Koulaxis
8a0cbf04d6 feat(iter): peek(), skip(predicate) for non-list iterators #37604
Problem:
Iter:peek() only works if the iterator is a |list-iterator| (internally, an `ArrayIter`).
However, it is possible to implement :peek() support for any iterator.

Solution:
- add `_peeked` buffer for lookahead without actually consuming values
- `peek()` now works for function, pairs(), and array iterators
- `skip(predicate)` stops at the first non matching element without consuming it
- keep existing optimized behavior for `ArrayIter` to maintain backward compatibility
- use `pack`/`unpack` to support iterators that return multiple values
2026-02-12 11:55:16 -05:00
Justin M. Keyes
858576777e docs: lsp, options, promptbuf
Close #37630
Close #37682
Close #37762
Close #37785

Co-authored-by: Daniel Schmitt <d.schmitt@lansoftware.de>
Co-authored-by: Duane Hilton <duane9@gmail.com>
Co-authored-by: NeOzay <colpaert.benoit@gmail.com>
Co-authored-by: Yi Ming <ofseed@foxmail.com>
Co-authored-by: "Justin M. Keyes" <justinkz@gmail.com>
2026-02-12 13:46:45 +01:00
skewb1k
6b4ec2264e feat(stdlib): vim.json.decode() can allow comments #37795
Problem:
`vim.json.decode()` could not parse JSONC (JSON with Comments)
extension, which is commonly used in configuration files.

Solution:
Introduce an `skip_comments` option, which is disabled by default. When
enabled, allows JavaScript-style comments within JSON data.
2026-02-11 06:54:57 -05:00
Olivia Kinnear
0c46ea7d38 feat(lua): add Iter:unique() (#37592) 2026-02-10 11:43:47 -06:00
Evgeni Chasnovski
14c708634e fix(vim.fs): make rm() work with symlink to a directory 2026-02-10 16:40:12 +00:00
zeertzjq
1906da52db fix(lua): close vim.defer_fn() timer if vim.schedule() failed (#37647)
Problem:
Using vim.defer_fn() just before Nvim exit leaks luv handles.

Solution:
Make vim.schedule() return an error message if scheduling failed.
Make vim.defer_fn() close timer if vim.schedule() failed.
2026-02-01 21:29:19 +08:00
zeertzjq
1f0dbfea2f fix(tui): log chdir failure properly #37591 2026-01-28 05:44:17 -05:00
luukvbaal
d30d91f3a4 fix(ui): only internal messages are unsafe #37462
Problem:  Fast context for msg_show event inhibits vim.ui_attach from
          displaying a stream of messages from a single command.

Solution: Remove fast context from msg_show events emitted as a result
          of explicit API/command calls. The fast context was originally
          introduced to prevent issues with internal messages.
2026-01-26 18:18:51 -05:00
Tristan Knight
d2ca90d87e fix(glob): handle numeric literals in pattern matching (#37257)
Problem:
vim.glob.to_lpeg() errors when patterns contain numeric literals
(like the '1' in '.ps*1') because LPeg interprets numeric strings
as indexed grammar rule references. For example:
  vim.glob.to_lpeg('.ps*1')
  E5108: Lua: rule '1' undefined in given grammar

Solution:
Prefix all rule names with '_' in the end_seg() function to prevent
literal numbers from being interpreted as LPeg indexed rules. This
ensures pattern components like '1', '2', etc. are treated as
regular rule names rather than special references.
2026-01-12 10:58:01 -08:00
zeertzjq
7a6e8d4430 docs: misc (#37281)
Close #37289
Close #37348

Co-authored-by: Marc Jakobi <marc@jakobi.dev>
Co-authored-by: Anton Kesy <anton@kesy.de>
2026-01-12 03:50:57 +00:00
zeertzjq
94144d4678 fix(lua): vim._with() doesn't save boolean options properly (#37354)
Problem:  vim._with() doesn't save boolean options with false values
          properly.
Solution: Use vim.F.if_nil().
2026-01-11 20:04:32 +08:00
zeertzjq
bfb70c03ff test(buffer_updates_spec): move on_detach tests to its block (#37297) 2026-01-08 09:59:27 +08:00
Robert Muir
efa6d91132 fix(diagnostic): display 1-based related information line/col numbers (#37093)
Problem
LSP Related Information line and column numbers are 0-based. Displaying
them this way can confuse the user, since vim line/col numbers are
typically displayed 1-based.

Solution
Display the line and column numbers as 1-based.
2026-01-04 15:07:00 -08:00
Kira Kawai
3ac76977bc fix(diagnostic): check for extmark in get_logical_pos #37127
Problem: The function get_logical_pos did not account for the possibility that a diagnostic might not have an associated extmark, leading to potential errors or incorrect behavior.

Solution: Add a check for diagnostic._extmark_id and return the logical positions directly if it does not exist.
2026-01-02 01:49:28 -05:00
glepnir
9833f0da5f fix(diagnostic): unstable sorting by severity #37154
Problem: random order for same-severity diagnostics, severity_sort reversed.

Solution: add stable comparison with _extmark_id tiebreaker.
2025-12-30 04:28:32 -05:00
Justin M. Keyes
1d70c96e5b build: move shared.lua to _core/ 2025-12-30 01:44:52 -05:00
Bryan Turns
bef68ba266 docs(lua): iInconsistent vim.keymap param name #37026
Problem: vim.keymap.del has 'modes' as it's first argument while vim.keymap.set
has 'mode' as it's first argument despite both 'mode' and 'modes' taking in the
same type input of String or String[].

Solution: Updated vim.keymap.set docs to refer to it's first argument
as 'modes'.
2025-12-20 19:26:44 -05:00
skewb1k
b87bdef2a8 fix(lua): relax vim.wait() timeout validation #36900
Problem:
After bc0635a9fc `vim.wait()` rejects floats
and NaN values.

Solution:
Restore the prior behavior, while still supporting `math.huge`. Update
tests to cover float case.
2025-12-10 09:44:05 -05:00
skewb1k
bc0635a9fc fix(lua): vim.wait(math.huge) fails #36885
Problem:
`nlua_wait()` uses `luaL_checkinteger()` which doesn't support
`math.huge` since it's double type. On PUC Lua this fails with
'number has no integer representation' error and on LuaJIT this
overflows int.

Solution:
Use `luaL_checknumber()` and handle `math.huge`.
2025-12-09 13:59:06 -05:00
benarcher2691
7f2d5d6883 fix(msgpack): use fixstr encoding for strings of length 20-31 #36737
Problem:
MessagePack fixstr format supports string lengths 0-31, but mpack_str()
only used fixstr for lengths < 20. Strings of 20-31 bytes were
incorrectly encoded as str8 (2-byte header) instead of fixstr (1-byte
header).

Solution:
Change the condition from `len < 20` to `len < 32` to match the
MessagePack specification.

This fix affects message timing which exposed a pre-existing race
condition in the channels_spec PTY test. The test now uses a helper
function to accumulate partial PTY reads, making it more robust.

Fixes #32784
2025-12-01 13:16:44 -05:00
Maria Solano
7e09fedf43 feat(diagnostic): config.status #36693
Problem:
`diagnostic.status()` is configured via `config.signs`, but users may
want diagnostics only in statusline, not in the gutter (signs).

Solution:
Add `config.status`.
2025-11-25 21:00:00 -08:00
Riley Bruins
4107442103 feat(diagnostic): highlights in diagnostic.status() #36685
Applies the appropriate `DiagnosticSign*` highlight to each group,
resetting the highlights at the end of the expression.
2025-11-25 10:14:46 -08:00
Justin M. Keyes
83d22e0979 refactor: deduplicate test 2025-11-22 17:04:32 -05:00
Riccardo Mazzarini
7da4d6abe2 fix(api): on_bytes gets stale data on :substitute #36487
Problem: `extmark_splice()` was being called before `ml_replace()`,
which caused the on_bytes callback to be invoked with the old buffer
text instead of the new text.

Solution: store metadata for each match in a growing array, call
`ml_replace()` once to update the buffer, then call `extmark_splice()`
once per match.

Closes https://github.com/neovim/neovim/issues/36370.
2025-11-20 21:40:08 -08:00
Michele Sorcinelli
69b286c3bf fix(vim.net): filetype detection, mark unmodified #36297
Problem:
When running ":edit <url>", filetype detection is not triggered.

Solution:
Run the autocmds in the filetypedetect group after loading the content.

Problem:
After fetching remote content from a URL and adding it to the buffer,
the buffer is marked as modified. This is inconsistent with the original
netrw behavior, and it causes problems with `:e` to refresh or `:q` as
it prompts for saving the file even if the user hasn't touched the
content at all.

Solution:
Mark the buffer as unmodified right after adding the remote content to
the buffer.
2025-11-19 22:04:59 -08:00
zeertzjq
a04c73cc17 fix(input): discard following keys when discarding <Cmd>/K_LUA (#36498)
Technically the current behavior does match documentation. However, the
keys following <Cmd>/K_LUA aren't normally received by vim.on_key()
callbacks either, so it does makes sense to discard them along with the
preceding key.

One may also argue that vim.on_key() callbacks should instead receive
the following keys together with the <Cmd>/K_LUA, but doing that may
cause some performance problems, and even in that case the keys should
still be discarded together.
2025-11-20 12:33:02 +08:00
Grzegorz Rozdzialik
2767eac320 feat(diagnostics): stack DiagnosticUnnecessary,DiagnosticDeprecated highlights #36590
Problem: unnecessary and deprecated diagnostics use their own highlight
groups (`DiagnosticUnnecessary` and `DiagnosticDeprecated`) which
override the typical severity-based highlight groups (like
`DiagnosticUnderlineWarn`).

This can be misleading, since diagnostics about unused variables which
are warnings or errors, are shown like comments, since then only the
`DiagnosticUnnecessary` highlight group is used. Users do not see the
more eye-catching red/yellow highlight.

Solution: Instead of overriding the highlight group to
`DiagnosticUnnecessary` or `DiagnosticDeprecated`, set them in addition
to the normal severity-based highlights.
2025-11-17 09:37:59 -08:00
Justin M. Keyes
1f9d9cb2e5 fix(vim.fs): abspath(".") returns "/…/." #36583 2025-11-16 22:36:03 -08:00
Cameron Ring
f11f8546e7 fix(vim.fs): root() should always return absolute path #36466 2025-11-16 21:41:26 -08:00
Jonny Kong
e2cb675705 fix(filetype): move fallback logic to vim.filetype.match() #30141
Problem:
Previously, the fallback logic to ".conf" was located outside of
`vim.filetype.match()` and directly within the AutoCmd definition. As a
result, `vim.filetype.match()` would return nil instead of ".conf" for
fallback cases (#30100).

Solution:
Added a boolean return value to `vim.filetype.match()` that indicates
whether the match was the result of fallback. If true, the filetype will
be set using `setf FALLBACK <ft>` instead of `setf <ft>`.
2025-10-28 18:45:50 -07:00
xvzc
095b9f98f3 fix(filetype): handle invalid bufnr in _getlines(), _getline() #36272
**Problem:**
`vim.filetype.match({ filename = 'a.sh' })` returns `nil` because
an invalid buffer ID is passed to `vim.api.nvim_buf_get_lines()`.
For filetypes like `csh`, `txt`, or any other extensions that call
`_getlines()` or `_getline()` to detect their filetypes, the same
issue occurs.

When only the `filename` argument is passed, an error is raised
inside a `pcall()` that wraps the filetype detection function,
causing it to return no value without showing any error message.

**Solution:**
Validate the `bufnr` value in `_getlines()` and `_getline()`.
2025-10-23 17:34:12 -07:00
Matthieu Coudron
e42050f4ae feat(vimscript): log function name in "fast" message #32616 2025-10-21 07:46:03 -07:00
Yochem van Rosmalen
62d3a2110d fix(help): wrong tag url in third-party help docs #36115
fix(help): only set url for nvim-owned tags

Problem:
1. gx on |nonexistingtag| opens
https://neovim.io/doc/user/helptag.html?nonexistingtag.
2. b:undo_ftplugin doesn't remove url extmarks.

Solution:
1. Check if the tag is defined in a help file in $VIMRUNTIME.
2. Solution: clear namespace for buffer in b:undo_ftplugin.
2025-10-12 15:08:18 -07:00
zeertzjq
c881bc537e vim-patch:9.1.1817: popup: there are some position logic bugs (#36075)
Problem:  popup: there are some position logic bugs
Solution: Refactor position logic and fix a few bugs
          (Girish Palya).

This change does the following:

- Simplified and rewrote horizontal positioning logic (was overly
  complex).
- Split horizontal and vertical positioning into separate functions.
- Fixed missing truncation marker (e.g. `>`) when items were truncated
  and `pummaxwidth` was not set.
- Fixed occasional extra space being added to menu items.
- Update tests

closes: vim/vim#18441

e3ed5584ed

Cherry-pick pum_display_{rtl,ltr}_text() changes from patch 9.1.1835.

Co-authored-by: Girish Palya <girishji@gmail.com>
2025-10-08 13:47:50 +08:00
zeertzjq
eb7c12d3e3 test: remove a few more redundant clear() calls (#35903) 2025-09-24 14:25:54 +08:00
zeertzjq
b256e0476b test(lua/secure_spec): clean up properly (#35902)
- Remove "state" directory after each test, so that a failure in one
  test won't interfere with later tests.
- Still make sure the trust file is empty at the end of each test.
2025-09-24 12:30:57 +08:00
zeertzjq
a62fb57e58 test: don't call clear() in both before_each() and after_each() (#35901) 2025-09-24 11:41:43 +08:00
Yochem van Rosmalen
47b0a718c3 feat(help): gx opens help tag in web browser #35778
Problem:
`gx` does not work on tags in help buffers to open the documentation of that tag in the browser.

Solution:
Get the `optionlink`, `taglink` and `tag` TS nodes and set extmark "url" property.
`gx` then discovers the extmark "url" and opens it.
2025-09-15 15:38:49 -07:00
bfredl
0458a1e694 build(ci): bump zig to 0.15.1 and add more platforms
- Bump zig version to 0.15.1 and workaround zig fetch hang (ziglang/zig#24916)
- add mac os zig build (currently without luajit, linker failure)
- Add windows zig build, currently with very limited testing
2025-09-15 12:10:23 +02:00
skewb1k
a897cc17a5 feat(json): vim.json.encode() sort_keys #35574
Problem: There is no way to ensure a stable key order when encoding a JSON string,
which can be useful for comparisons and producing cleaner diffs.

Solution: Introduce a `sort_keys` option for `vim.json.encode()`,which
is disabled by default. When enabled, object keys are sorted in
alphabetical order.
2025-09-13 21:17:07 -07:00
skewb1k
448f15ca39 feat(json): pretty-format (indent) with vim.json.encode() #35424
Problem:
There is no straightforward way to pretty-print objects as JSON.
The existing `vim.inspect` outputs LON.

Solution:
Introduce an `indent` option for `vim.json.encode()` which enables
human-readable output with configurable indentation.

Adapts PR to upstream: openresty/lua-cjson#114
2025-09-07 14:38:27 -07:00
Justin M. Keyes
9c3099f0cf docs: lsp, misc
- Problem: It's not clear for new plugin developers that `:help` uses
  a help-tags file for searching the docs, generated by `:helptags`.
  - Solution: Hint to the |:helptags| docs for regenerating the tags
    file for their freshly written documentation.

Co-authored-by: Yochem van Rosmalen <git@yochem.nl>
2025-09-03 23:03:51 -04:00
luukvbaal
de950f8272 fix(window): avoid referencing cmdline_win after it is closed #35617
Solution:  A window marked for ext_cmdline usage is still referenced
           after it is already closed and freed.
Solution:  Unset cmdline_win when the window is closed.
2025-09-03 16:28:23 -07:00