Commit Graph

9773 Commits

Author SHA1 Message Date
Cameron Ring
f11f8546e7 fix(vim.fs): root() should always return absolute path #36466 2025-11-16 21:41:26 -08:00
Justin M. Keyes
c8b6852363 docs: misc #36580
Co-authored-by: nguyenkd27 <nguyenkd27@gmail.com>
Co-authored-by: dundargoc <gocdundar@gmail.com>
Co-authored-by: Yochem van Rosmalen <git@yochem.nl>
Co-authored-by: Tuure Piitulainen <tuure.piitulainen@gmail.com>
Co-authored-by: Maria Solano <majosolano99@gmail.com>
Co-authored-by: tao <2471314@gmail.com>
2025-11-16 20:36:07 -08:00
tao
654303079b feat(lsp): skip invalid header lines #36402
Problem:
Some servers write log to stdout and there's no way to avoid it.
See https://github.com/neovim/neovim/pull/35743#pullrequestreview-3379705828

Solution:
We can extract `content-length` field byte by byte and skip invalid
lines via a simple state machine (name/colon/value/invalid), with minimal
performance impact.

I chose byte parsing here instead of pattern. Although it's a bit more complex,
it provides more stable performance and allows for more accurate error info when
needed.

Here is a bench result and script:

    parse header1 by pattern: 59.52377ms 45
    parse header1 by byte: 7.531128ms 45

    parse header2 by pattern: 26.06936ms 45
    parse header2 by byte: 5.235724ms 45

    parse header3 by pattern: 9.348495ms 45
    parse header3 by byte: 3.452389ms 45

    parse header4 by pattern: 9.73156ms 45
    parse header4 by byte: 3.638386ms 45

Script:

```lua
local strbuffer = require('string.buffer')

--- @param header string
local function get_content_length(header)
  for line in header:gmatch('(.-)\r?\n') do
    if line == '' then
      break
    end
    local key, value = line:match('^%s*(%S+)%s*:%s*(%d+)%s*$')
    if key and key:lower() == 'content-length' then
      return assert(tonumber(value))
    end
  end
  error('Content-Length not found in header: ' .. header)
end

--- @param header string
local function get_content_length_by_byte(header)
  local state = 'name'
  local i, len = 1, #header
  local j, name = 1, 'content-length'
  local buf = strbuffer.new()
  local digit = true
  while i <= len do
    local c = header:byte(i)
    if state == 'name' then
      if c >= 65 and c <= 90 then -- lower case
        c = c + 32
      end
      if (c == 32 or c == 9) and j == 1 then
        -- skip OWS for compatibility only
      elseif c == name:byte(j) then
        j = j + 1
      elseif c == 58 and j == 15 then
        state = 'colon'
      else
        state = 'invalid'
      end
    elseif state == 'colon' then
      if c ~= 32 and c ~= 9 then -- skip OWS normally
        state = 'value'
        i = i - 1
      end
    elseif state == 'value' then
      if c == 13 and header:byte(i + 1) == 10 then -- must end with \r\n
        local value = buf:get()
        return assert(digit and tonumber(value), 'value of Content-Length is not number: ' .. value)
      else
        buf:put(string.char(c))
      end
      if c < 48 and c ~= 32 and c ~= 9 or c > 57 then
        digit = false
      end
    elseif state == 'invalid' then
      if c == 10 then -- reset for next line
        state, j = 'name', 1
      end
    end
    i = i + 1
  end
  error('Content-Length not found in header: ' .. header)
end

--- @param fn fun(header: string): number
local function bench(label, header, fn, count)
  local start = vim.uv.hrtime()
  local value --- @type number
  for _ = 1, count do
    value = fn(header)
  end
  local elapsed = (vim.uv.hrtime() - start) / 1e6
  print(label .. ':', elapsed .. 'ms', value)
end

-- header starting with log lines
local header1 =
  'WARN: no common words file defined for Khmer - this language might not be correctly auto-detected\nWARN: no common words file defined for Japanese - this language might not be correctly auto-detected\nContent-Length: 45  \r\n\r\n'
-- header starting with content-type
local header2 = 'Content-Type: application/json-rpc; charset=utf-8\r\nContent-Length: 45  \r\n'
-- regular header
local header3 = '  Content-Length: 45\r\n'
-- regular header ending with content-type
local header4 = '  Content-Length: 45 \r\nContent-Type: application/json-rpc; charset=utf-8\r\n'

local count = 10000

collectgarbage('collect')
bench('parse header1 by pattern', header1, get_content_length, count)
collectgarbage('collect')
bench('parse header1 by byte', header1, get_content_length_by_byte, count)

collectgarbage('collect')
bench('parse header2 by pattern', header2, get_content_length, count)
collectgarbage('collect')
bench('parse header2 by byte', header2, get_content_length_by_byte, count)

collectgarbage('collect')
bench('parse header3 by pattern', header3, get_content_length, count)
collectgarbage('collect')
bench('parse header3 by byte', header3, get_content_length_by_byte, count)

collectgarbage('collect')
bench('parse header4 by pattern', header4, get_content_length, count)
collectgarbage('collect')
bench('parse header4 by byte', header4, get_content_length_by_byte, count)
```

Also, I removed an outdated test
accd392f4d/test/functional/plugin/lsp_spec.lua (L1950)
and tweaked the boilerplate in two other tests for reusability while keeping the final assertions the same.
accd392f4d/test/functional/plugin/lsp_spec.lua (L5704)
accd392f4d/test/functional/plugin/lsp_spec.lua (L5721)
2025-11-16 17:23:52 -08:00
Evgeni Chasnovski
474e9e9408 fix(pack): show more informative error message if no git executable
Problem: Relaxing minimal Git version did not fully preserve previous
  behavior in case there no `git` executable. Instead it showed the same
  error as if after `vim.system({ 'does_not_exist' })`.

Solution: Show a more direct "No `git` executable" error message.
2025-11-16 22:26:19 +02:00
Evgeni Chasnovski
18e6ba90e2 docs(pack): add example workflow of how to revert after a bad update
Problem: No example workflow of how to revert after a bad update.

Solution: Add example workflow of how to revert after a bad update.

  In future this might be improved by utilizing other `vim.pack`
  features or via a dedicated function (like `vim.pack.restore()` that
  restores all installed plugins to a state from the lockfile).
2025-11-16 22:19:10 +02:00
Evgeni Chasnovski
2e533e364e feat(pack): update add() to handle source change for installed plugin
Problem: Changing `src` of an existing plugin cleanly requires manual
  `vim.pack.del()` prior to executing `vim.pack.add()` with a new `src`.

Solution: Autodetect `src` change for an existing plugin (by comparing
  against lockfile data). If different - properly delete immediately and
  treat this as new plugin installation.

  Alternative solution might be to update `origin` remote in the
  installed plugin after calling `vim.pack.update()`. Although, doable,
  this 1) requires more code; and 2) works only for Git plugins (which
  might be not the only type of plugins in the future). Automatic
  "delete and clean install" feels more robust.
2025-11-16 22:19:10 +02:00
Evgeni Chasnovski
a39171f532 fix(pack)!: make default opts.load in add() to work inside 'plugin/'
Problem: Plain `vim.pack.add()` calls (with default `opts.load`) does
  not fully work if called inside 'plugin/' runtime directory. In
  particular, 'plugin/' files of newly added plugins are not sourced.
  This is because `opts.load` is `false` during the whole startup, which
  means `:packadd!` is used (modify 'runtimepath' but not force source
  newly added 'plugin/' files).

  This use case is common due to users organizing their config as
  separate files in '~/.config/nvim/plugin/'.

Solution: Use newly added `v:vim_did_init` to decide default `opts.load`
  value instead of `v:vim_did_enter`.
2025-11-16 22:19:10 +02:00
Evgeni Chasnovski
e4e6605943 fix(pack): relax minimal Git version to be 2.0 #36573
Problem: Current requirement is Git>=2.36 as `--also-filter-submodules`
  flag for `git clone` was introduced there. This is problematic since
  default Git version on Ubuntu 22.04 is 2.34.

Solution: Relax minimal Git version to be (at least) 2.0 by selectively
  applying necessary flags based on the current Git version.
  As 2.0.0 was released in 2014-05-28 (almost the same age as Neovim
  project itself), it is reasonable to drop any mention and checks on
  minimal version altogether.
2025-11-16 10:27:19 -08:00
Justin M. Keyes
f01c212e37 docs: rework main help page 2025-11-16 00:55:28 -05:00
Justin M. Keyes
3f16037e45 docs: getpos, getregion, lsp 2025-11-15 22:47:38 -05:00
zeertzjq
30634f63e2 vim-patch:fb8ebf1: runtime(compiler): Remove version check in rustc compiler (#36568)
closes: vim/vim#18347

fb8ebf1ee0

Co-authored-by: Konfekt <Konfekt@users.noreply.github.com>
2025-11-15 23:46:08 +00:00
Chip Senkbeil
c123b7245c refactor(path)!: support RFC3986 in path_with_url() #36564
Problem:
Nvim does not recognize URI scheme with numeric characters. While rare, there
are URIs that contain numbers (e.g. [ed2k://](https://en.wikipedia.org/wiki/Ed2k_URI_scheme))
and characters like `+` (e.g. `svn+ssh`). I use it in
[distant.nvim](https://github.com/chipsenkbeil/distant.nvim) to support
multiple, distinct connections using `distant+1234://` as the scheme.
Otherwise, if you open a file with the same name & path on two different
machines from the same Nvim instance, their buffer names will conflict
when just using `distant://`.

Solution:
Adds full support for detecting URI scheme per
[RFC3986](https://www.rfc-editor.org/rfc/rfc3986#section-3.1)
2025-11-15 13:40:01 -08:00
zeertzjq
b3c099b1dd vim-patch:d0dd561: runtime(compiler): add biome linter (#36562)
closes: vim/vim#18685

d0dd5614db

Co-authored-by: Konfekt <Konfekt@users.noreply.github.com>
2025-11-15 11:21:19 +00:00
zeertzjq
d1c5c11ee0 vim-patch:f46616f: runtime(vim): Update base syntax and generator, match :cd commands
Match :cd commands explicitly.

fixes: vim/vim#17964
closes: vim/vim#18736

Reported by Maxim Kim.

f46616f0c4

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-15 18:28:00 +08:00
zeertzjq
2fdf097fa5 vim-patch:4f19d27: runtime(vim): Update base syntax, match :prompt command args
closes: vim/vim#18732

4f19d2768a

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-15 18:26:56 +08:00
zeertzjq
2c9b102a9f vim-patch:fe24972: runtime(vim): Update base syntax, refine object constructor matching
Match "object" and "<" ... ">" separately with dedicated syntax groups
to allow for highlighting distinct from that generally used for types.

closes: vim/vim#18721

fe24972139

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-15 18:26:14 +08:00
zeertzjq
d017f3c9a0 vim-patch:9.1.1914: runtime(netrw): wipes unnamed buffers (#36551)
Problem:  runtime(netrw): LocalBrowseCheck() wipes unnamed buffers when
          g:netrw_fastbrowse=0 (Carlos Falgueras García)
Solution: Check that bufname() is not empty

fixes: vim/vim#18740
closes: vim/vim#18741

384685fade

Co-authored-by: Christian Brabandt <cb@256bit.org>
2025-11-13 23:59:35 +00:00
zeertzjq
1a5f0ba201 vim-patch:eb732ed: runtime(doc): Wrap overlength lines in uganda.txt (#36550)
Wrap overlength lines and normalise URL indentation.

closes: vim/vim#18737

eb732ed26d

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-13 23:28:34 +00:00
Justin M. Keyes
72110da567 Merge #36468 from echasnovski/pack-consistency
`vim.pack` consistency improvements: full hashes, state->revision, buffer URI name
2025-11-13 02:00:05 -05:00
Toby She
4dd9137215 fix(lsp): reuse_win prioritizes windows/tabs currently displayed #36486
Problem: reuse_win will always jump to the first window containing the
target buffer rather even if the buffer is displayed in the current
window/tab

Solution: check to see if the buffer is already displayed in the
current window or any window of the current buffer
2025-11-12 20:43:25 -08:00
Andrey Starodubtsev
4143bcbd37 fix(tutor): escape tutor filename #36539
Since NeoVim is installed in `Program Files` directory by default, path
to tutor filename must be quoted before passing to `:drop`.
2025-11-12 19:27:24 -08:00
zeertzjq
756043760b vim-patch:9.1.1909: filetype: .mom files recognized as nroff files (#36543)
Problem:  filetype: .mom files recognized as nroff files
Solution: Detect *.mom files as groff filetype instead
          (Callum Andrew)

Reference:
- mom macros are written specifically for groff:
  https://www.schaffter.ca/mom/

closes: vim/vim#18718

23e12c0b7e

Co-authored-by: Callum Andrew <dev@candrew.net>
2025-11-13 00:22:11 +00:00
zeertzjq
fbcdbd458f vim-patch:e9d296e: runtime(erlang): recognize -if/-elif as erlangPreCondit in syntax script (#36542)
The -if(Condition)/-elif(Condition) are compiler macros that evaluate
the following lines only if Condition evaluates to true.  This patch
enables syntax highlighting for these macros.

https://www.erlang.org/doc/system/macros.html#conditional-compilation

closes: vim/vim#18729

e9d296e52a

Co-authored-by: Vadim Yanitskiy <fixeria@osmocom.org>
2025-11-12 23:45:50 +00:00
zeertzjq
1571fde23e vim-patch:9ab6a22: runtime(doc): Improve :help :ls description formatting (#36541)
Quote the special buffer names for consistency (see :help bufname()) and
so that they're not incorrectly highlighted as optional command
arguments.

closes: vim/vim#18730

9ab6a22c90

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-12 23:04:06 +00:00
Yochem van Rosmalen
94ae48ff29 docs(undotree): rename help tag #36497
Problem: confusing that there is the tag `undo-tree` (the Vim
implementation) and `undotree` (the Lua plugin for visualization).

Solution: rename tag to undotree-plugin. Mention the plugin in the docs of
|undotree|.
2025-11-12 09:00:27 -08:00
Andrey Starodubtsev
b15b22fc73 fix(trust): :trust command on Windows #36509
`:trust` command calculated SHA-256 on file content reading it as a
text. While it doesn't matter on Unices, on Windows hash was calculated
incorectly. SHA-256 for buffer content was calculated fine though.

After this fix hashes in `%LOCALAPPDATA%/nvim-data/trust` are the same
as in output of `sha256sum -t`.
2025-11-11 21:57:09 -08:00
Maria Solano
653871da1b fix(lsp): check nvim.lsp.enable before doautoall #36518 2025-11-11 21:04:31 -08:00
Maria Solano
1bc85d29c1 fix(lsp): check for non-nil buffer state on reset (#36519) 2025-11-11 17:47:33 -08:00
zeertzjq
3606b74d24 vim-patch:f85951f: runtime(css): improve cssBoxProp matches (#36528)
closes: vim/vim#18717

f85951fee0

Co-authored-by: Neil Lambert <nlambert@pm.me>
2025-11-12 08:23:35 +08:00
zeertzjq
8cf7a0c4de vim-patch:b74ec15: runtime(sqlcomplete): only set 'omnifunc' if dbext plugin was loaded (#36527)
fixes: vim/vim#18716

b74ec159dd

Co-authored-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: gcanat <72149218+gcanat@users.noreply.github.com>
2025-11-12 00:21:31 +00:00
zeertzjq
97cb0d5571 vim-patch:9.1.1906: filetype: not all Ruby files are recognized (#36526)
Problem:  filetype: not all Ruby files are recognized
Solution: Detect *.rbi and Brewfile as ruby filetype
          (botantony).

- `rbi` is a file extension used by Sorbet, typechecker for Ruby:
   https://sorbet.org/docs/rbi

- `Brewfile` is a bundler file for Homebrew package manager:
   https://docs.brew.sh/Brew-Bundle-and-Brewfile

closes: vim/vim#18697

efc3be77bb

Co-authored-by: botantony <antonsm21@gmail.com>
2025-11-12 07:38:55 +08:00
Maria Solano
2822c38f2e fix(lsp): correct iteration through attached buffers (#36517) 2025-11-10 19:54:01 -08:00
Olivia Kinnear
7c9b865bdd feat(lsp): deprecate vim.lsp.stop_client (#36459)
* feat(lsp): deprecate `vim.lsp.stop_client`

* fix(tests): fix nil variable in diagnostic_spec.lua
2025-11-10 18:27:13 -08:00
zeertzjq
637c9c4f5f vim-patch:d3bef6c: runtime(sml): Fix number regex in syntax script (#36513)
closes: vim/vim#18690

d3bef6cf3f

Co-authored-by: tocariimaa <tocariimaa@pissmail.com>
2025-11-11 09:28:18 +08:00
zeertzjq
1eb12b896e vim-patch:e1e3474: runtime(vim): Update base syntax, fix :augroup error matching (#36512)
Only terminate the :augroup END argument at whitespace, comments and
trailing bars.

closes: vim/vim#18711

e1e347475e

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-11 09:22:00 +08:00
zeertzjq
70d1397766 vim-patch:acf928a: runtime(doc): Improve windows.txt formatting (#36511)
- Wrap some overlength lines
- Highlight the example at :help WinScrolled-event

closes: vim/vim#18713

acf928a33b

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-11 00:32:06 +00:00
Maria Solano
70ea589d79 fix(lsp): deprecate vim.lsp.get_buffers_by_client_id (#36449) 2025-11-10 06:58:56 -08:00
Yochem van Rosmalen
9bdb011a50 refactor(spellfile): config() interface, docs #36481
Problem:
- Exposing the raw config as table is a pattern not seen anywhere else
  in the Nvim codebase.
- Old spellfile.vim docs still available, no new documentation

Solution:
- Exposing a `config()` function that both acts as "getter" and "setter"
  is a much more common idiom (e.g. vim.lsp, vim.diagnostic).
- Add new documentation and link old docs to |spellfile.lua| instead of
  |spellfile.vim|.
2025-11-09 21:51:39 -08:00
zeertzjq
2b49a0e773 vim-patch:5427465: runtime(doc): Clean up file header whitespace
- :retab! line 1 and line 4 (main page heading).
- Use four columns whitespace before "by [Author]" in the user manual
  heading to match the reference manual formatting.
- double space headings.

closes: vim/vim#18648

542746521f

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-10 11:13:56 +08:00
zeertzjq
95f5bbd4a8 vim-patch:c8eeda9: runtime(doc): Improve header formatting
- Normalise header formatting and highlight all bylines.
- Remove broken email address from if_sniff.txt.

closes: vim/vim#18601

c8eeda9b15

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-10 11:13:52 +08:00
Riley Bruins
c2c5a0297e fix(lsp): don't overlay insertion-style inline completions (#36477)
* feat(lua): `Range:is_empty()` to check vim.range emptiness

* fix(lsp): don't overlay insertion-style inline completions

**Problem:** Some servers commonly respond with an empty inline
completion range which acts as a position where text should be inserted.
However, the inline completion module assumes that all responses with a
range are deletions + insertions that thus require an `overlay` display
style. This causes an incorrect preview, because the virtual text should
have the `inline` display style (to reflect that this is purely an
insertion).

**Solution:** Only use `overlay` for non-empty replacement ranges.
2025-11-09 17:49:25 -08:00
zeertzjq
c6dad6e9df vim-patch:a795aab: runtime(spec): Add support for more tags and distributions (#36502)
- specMacroIdentifier: support macros starting with '?'; the most common
  example is `%{?dist}`
- specPreAmble: added some missing tags from:
  https://rpm.org/docs/4.19.x/manual/spec.html
- Added support for: `fedora`, `rhel`, `rocky`, `rhl`, `centos`, `el\d`
  and `fc\d`, see https://docs.fedoraproject.org/en-US/packaging-guidelines/DistTag

closes: vim/vim#18703

a795aab885

Co-authored-by: Jesse Portnoy <jesse.portnoy@perforce.com>
2025-11-10 08:44:50 +08:00
zeertzjq
4466c950cb vim-patch:8869800: runtime(vim): Update base syntax, match :*do command arg
Match the Ex command arg to all :*do commands.

closes: vim/vim#18700

8869800f70

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-10 08:00:35 +08:00
zeertzjq
24ecd0c48d vim-patch:59f0ea5: runtime(vim): Update base syntax, match Vim9 object type constructor
fixes: vim/vim#18677.
closes: vim/vim#18691

Reported by Aliaksei Budavei.

59f0ea5b3e

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-10 08:00:12 +08:00
zeertzjq
82910ddbfb vim-patch:433d2ab: runtime(vim): Update base syntax, match Vim9 lambda arg to :defer
Support added in commit 21ef3c6e5972bbe8ab61195f98ccb85048b78985.

See: vim/vim#18643
closes: vim/vim#18645

433d2ab206

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-10 08:00:12 +08:00
Riley Bruins
a0678a5849 fix(lsp): ignore inline completions after leaving insert mode (#36476)
**Problem:** When quickly entering and leaving insert mode, sometimes
inline completion requests are returned and handled in normal mode. This
causes an extmark to be set, which will not get cleared until the next
time entering & leaving insert mode.

**Solution:** Return early in the inline completion handler if we have
left insert mode.
2025-11-09 14:28:02 -08:00
zeertzjq
19a3687f69 vim-patch:185cec2: runtime(doc): Rewrite some overlength lines
closes: vim/vim#18695

185cec2b09

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-09 08:01:04 +08:00
zeertzjq
39a2cbbd58 vim-patch:a3063f2: runtime(doc): Wrap some overlength lines in the user manual
closes: vim/vim#18696

a3063f2f90

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-09 07:55:15 +08:00
zeertzjq
7ef7f82c5c vim-patch:c28b73d: runtime(doc): Improve :help synconcealed() description
closes: vim/vim#18698

c28b73d349

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2025-11-09 07:49:48 +08:00
luukvbaal
8d6963a6a0 fix(ui): cmdline_show is not fired after clearing the screen (#36451)
Problem:  Resize events during startup may clear an active external
          cmdline, which is then not redrawn.
          UI2 VimResized autocommand does not work.
          UI2 message appearance may be altered by inherited window
          options. The message separator uses the wrong fillchar.

Solution: Unset cmdline_was_last_redrawn when clearing the screen, such
          that cmdline_show is re-emitted.
          Ensure set_pos function is called without arguments.
          Ensure such options are unset. Use 'fillchars'->msgsep.
2025-11-08 11:38:56 +01:00