Commit Graph

34472 Commits

Author SHA1 Message Date
Oleh Volynets
ea70d2ad85 fix(ui2): unset Search highlighting (#36633)
Problem:
Trying to match the search highlight groups to the Normal highlight for
the window can fail when the message highlighting contains a fg/bg that
the Normal highlight doesn't (like an error message in cmd will have
ErrorMsg highlight instead of MsgArea - which is Normal in cmd.)

Solution:
Link the search highlight groups to an empty group in 'winhighlight'
thus disabling them instead of overriding them with Normal/MsgArea/etc.
2025-11-20 17:19:31 +00:00
Lewis Russell
e9b6474ae7 fix(statusline): scope truncation bookkeeping
Limit the default truncation item to the current recursion range so
nested `nvim_eval_statusline()` calls don't reuse stale `stl_items`
pointers. Add a functional regression that evaluates a Lua statusline
helper which forces truncation to ensure the nested scenario stays
stable.

AI-Assist: OpenAI ChatGPT

Fixes #36616
2025-11-20 09:53:11 +00: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
Justin M. Keyes
e0308dc147 fix(install): only install "tee" on Windows #36629
Problem:
AUR does not want a web-scale implementation of "tee".

Solution:
- Only install "tee" on Windows.
- The build will still produce `./build/bin/tee` on all platforms, to
  have more coverage and avoid special-cases in tests.
2025-11-19 21:00:56 -08:00
altermo
caa9419355 refactor!: optwin.lua #36505
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2025-11-19 20:43:15 -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
zeertzjq
3b6df3ae55 refactor: avoid unnecessary redraw for non-curwin cursor line (#36607) 2025-11-20 10:45:08 +08:00
luukvbaal
ba6fc90b6f fix(ui2): hide search highlights in msg window #36626
fix(ui2): hide search highlights in msg window.

Problem:  Search highlighting is shown in the msg (and dialog) window.
Solution: Hide search highlighting in all but the pager window.
2025-11-19 17:02:32 -08:00
AaronSteen
ceb7eb5230 build(windows): restore tee.exe on Windows #36363
Problem:
Neovim no longer ships with a tee binary on Windows, which breaks
functionality for the :grep and :make commands.

    nvim --clean
    :grep foo or :make
    "tee is not recognized as an internal or external command"

Solution:
Include a simple, no-dependency tee.c source file in the src/ directory.
Update CMakeLists.txt to build a tee executable alongside neovim during
the build process, and ensure the tee.exe program appears alongside the
neovim executable in the bin/ directory so that it is accessible for
:grep and :make.

tee.c was obtained from the vim codebase:
https://github.com/vim/vim/blob/master/src/tee/tee.c

And we modified it to fix performance issues.

Testing:

    nvim --clean
    :grep foo or :make, after setting a file to the makeprg option.
    Verify that :grep results and error output from a compiler appear in the message pane.

ref https://github.com/neovim/neovim/issues/32431
fix https://github.com/neovim/neovim/issues/32504

Other tee options:
- [tee-win32](https://github.com/dEajL3kA/tee-win32): MIT. However,
  I couldn't get it to build on my machine even after updating its
  makefile to call my install of MSVC. It's also super optimized and
  uses some processor intrinsics for multithreading.
- [gnu coreutils tee](https://gnuwin32.sourceforge.net/packages/coreutils.htm):
  (Windows coreutils contains a tee.c. Last updated 2005. Did not build
  immediately on my machine; we'd have to determine which definitions
  from elsewhere in coreutils tee.c needs and incorporate them somehow.
- [WinTee](https://github.com/mpderbec/WinTee): Has no license. Last
  updated 11 years ago. Relies on Visual Studio to build.

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2025-11-19 16:48:14 -08:00
Justin M. Keyes
4f97239661 build: USE_BUNDLED_UNIBILIUM=0 fails #36623
build: guard unibilium.h with HAVE_UNIBILIUM

Problem:

    make distclean
    make CMAKE_BUILD_TYPE=Release CMAKE_EXTRA_FLAGS="-DENABLE_UNIBILIUM=0" BUNDLED_CMAKE_FLAG="-DUSE_BUNDLED_UNIBILIUM=0"
    sudo make install

    In file included from …/nvim/tui/input.h:10:
    …/nvim/tui/termkey/termkey_defs.h:5:10: fatal error: 'unibilium.h' file not found
        5 | #include <unibilium.h>
          |          ^~~~~~~~~~~~~
    1 error generated.
    make[3]: *** [src/nvim/CMakeFiles/nvim_bin.dir/tui/input.c.o] Error 1
    make[2]: *** [src/nvim/CMakeFiles/nvim_bin.dir/all] Error 2
    make[1]: *** [all] Error 2
    make: *** [nvim] Error 2

Solution:
Check HAVE_UNIBILIUM.
2025-11-19 22:35:32 +00:00
Justin M. Keyes
7c2d4df2d3 revert: "fix(tutor): remove hyperlinks, simplify non-interactive examples" #36622
This reverts commit 5e039c8e97.
2025-11-19 13:47:48 -08:00
przepompownia
3eefe37871 docs(dev_tools): fix how to properly run not yet installed build
Problem: running ./build/bin/nvim without make install
- doesn't respect local changes in ./runtime,
- includes the path where Nvim would be installed,
- ignores changes in precompiled Lua modules (like .../vim/_editor.lua)

Solution:
- use VIMRUNTIME=./runtime,
- use --luamod-dev
2025-11-19 13:07:32 +00:00
Jeff Martin
ff792f8e69 fix(lsp): enable insertReplaceSupport for use in adjust_start_col #36569
Problem:
With the typescript LSes typescript-language-server and vtsls,
omnicompletion on partial tokens for certain types, such as array
methods, and functions that are attached as attributes to other
functions, either results in no entries populated in the completion menu
(typescript-language-server), or an unfiltered completion menu with all
array methods included, even if they don't share the same prefix as the
partial token being completed (vtsls).

Solution:
Enable insertReplaceSupport and uses the insert portion of the lsp
completion response in adjust_start_col if it's included in the
response.

Completion results are still filtered client side.
2025-11-18 23:03:40 -08:00
glepnir
b65aadc03e docs(diagnostic): diagnostic.Opts.Float extend open_floating_preview.Opts #30058
Problem: the opts table also is param of util.open_floating_preview,
vim.diagnostic.Opts.Float missing some fields of open_floating_preview.

Solution: diagnostic.Opts.Float extend util.open_floating_preview.Opts

Fix #29267
2025-11-18 21:52:30 -08:00
glepnir
c22b03c771 feat(lsp): user-specified sorting of lsp.completion multi-server results #36401
Problem: No way to customize completion order across multiple servers.

Solution: Add `cmp` function to `vim.lsp.completion.enable()` options
for custom sorting logic.
2025-11-18 21:38:53 -08:00
SquallATF
2c04ae9fcc fix(windows): wrong RT_MANIFEST ID in nvim.rc #36406
Problem:
Starting Nvim on MinGW fails:
https://github.com/msys2/MINGW-packages/issues/25140

    Unknown system error -1:"C:\msys64\ucrt64\bin\nvim.exe"Failed to start Nvim server!

Solution:
On Windows, the main application manifest should use resource ID 1 (RT_MANIFEST).
Update `nvim.rc` to use `1 RT_MANIFEST nvim.manifest` instead of `2`,
ensuring the manifest is correctly embedded and recognized by the system.

ID = 1 is for executable files (.exe)
ID = 2 is for DLLs (/DLL)
From MSVC docs: "Use a value of 2 for a DLL to enable it to specify private dependencies."
https://learn.microsoft.com/en-us/cpp/build/reference/manifest-create-side-by-side-assembly-manifest
2025-11-18 21:19:06 -08:00
glepnir
4998b8d7b5 feat(api): nvim_win_set_config accepts unchanged "noautocmd" #36463
Problem: Cannot reuse same config with noautocmd for both window
creation and updates, even when value is unchanged.

Solution: Only reject noautocmd changes for existing windows.
2025-11-18 20:23:50 -08:00
Paweł Tomulik
c567340171 build: support Cygwin + bundled luajit #36417
Fixes compilation/link/installation on Cygwin with bundled dependencies
(cmake.deps). Only builds with LuaJIT are fixed. Linking against PUC LUA still
does not work.

Note: Luajit technically does not support Cygwin:
55a42da36e
2025-11-18 19:25:23 -08:00
Justin M. Keyes
4244a96774 test: fix failing lsp/utils_spec #36609
Problem:
098da1fc2c was merged without rebasing on 4b8980949c, which
changed how this test behaves.

Solution:
Update the test.
2025-11-18 19:06:44 -08:00
zeertzjq
677446c70f fix(cmdline): make sure pum is removed on leave (#36608) 2025-11-19 09:40:20 +08:00
zeertzjq
f2619160ae vim-patch:c2cc63e: runtime(compiler): expand errorformats in maven compiler (#36605)
matches malformed POM error messages and tries to catch other tools
as well.

closes: vim/vim#18768

c2cc63ec7d

Co-authored-by: Konfekt <Konfekt@users.noreply.github.com>
2025-11-19 09:14:49 +08:00
zeertzjq
ec70a248b8 vim-patch:040a47a: runtime(netrw): Use proper UNC notation for temp files (#36606)
closes: vim/vim#18764

040a47a470

Co-authored-by: Miguel Barro <miguel.barro@live.com>
2025-11-19 09:14:36 +08:00
Koichi Shiraishi
93526754a9 build(test): unknown 'ipc_info_object_type_t' type on macOS #36523
Problem:
On macOS Tahoe, `make unittest` started failing with the following error.

````
test/unit/testutil.lua:784: test/unit/testutil.lua:768: (string) '
test/unit/testutil.lua:295: declaration specifier expected near 'ipc_info_object_type_t' at line 2297'
exit code: 256

stack traceback: 
test/unit/testutil.lua:784: in function 'itp_parent' 
test/unit/testutil.lua:822: in function <test/unit/testutil.lua:812>
````

Solution:
Update filter_complex_blocks.
2025-11-18 15:30:20 -08:00
Daniel Danner
d00f680c0d fix(clipboard): use tmux only in a tmux session #36407
This reverts 2495e7e. That past change meant that we would modify the
buffer contents of a tmux session if it exists, even if the current Nvim
process wasn't running inside of it. Depending on the tmux
configuration, this could even affect the clipboard of an actually
attached tmux client, since tmux itself uses OSC 52 to forward buffer
writes to attached clients.

While autodetection is usually a trade-off and can rarely make everybody
happy, this behavior goes counter the principle of least surprise. If
really desired, it can be brought back by explicit configuration.
2025-11-18 12:38:30 -08:00
Yochem van Rosmalen
a468bc573d ci: check URL reachability #35593
Problem:
scripts/check_urls.vim manually matches urls in the help pages and then
synchronously checks them via curl/wget/powershell. This is extremely
slow (~5 minutes for Nvims runtime on my machine) and prone to errors in
how the urls are matched.

Solution:
- Use Tree-sitter to find the urls in the help pages and `vim.net.request` to
  check the responses.
- Add a `lintdocurls` build task and check it in CI (every Friday).
  - Reopens a dedicated issue if it finds unreachable URLs.
- Drop the old check_urls.vim script.
2025-11-18 12:35:22 -08:00
Riley Bruins
098da1fc2c perf(treesitter): parse multiple ranges in languagetree, eliminate flickering #36503
**Problem:** Whenever `LanguageTree:parse()` is called, injection trees
from previously parsed ranges are dropped.

**Solution:** Allow the function to accept a list of ranges, so it can
return injection trees for all the given ranges.

Co-authored-by: Jaehwang Jung <tomtomjhj@gmail.com>
2025-11-18 10:09:49 -08:00
Vendetta
2483d5ad8a fix(clint.py): replace deprecated codecs.open #36593
Remove codecs import and use open(..., encoding='utf-8', errors='replace', newline=None) in clint.py to avoid Python 3.14 DeprecationWarning; preserve existing CR handling.
2025-11-18 09:35:42 -08:00
skewb1k
4b8980949c fix(lsp): set concealcursor='' in LSP floating windows #36596
Problem:
Users often jump and navigate through LSP windows to yank text.
Concealed markdown can make navigation through hyperlinks and code
blocks more difficult.

Solution:
Change 'concealcursor' from 'n' to '' to preserve clean display
while improving navigation and selection of the LSP response.

Closes #36537
2025-11-17 17:49:14 -08:00
luukvbaal
c4ac36bfd9 fix(ui2): only redraw when necessary #36457
Problem:  Until now the UI callback called nvim__redraw() liberally.
          It should only be needed when Nvim does not update the screen
          in its own event loop.
Solution: Identify which UI events require immediate redrawing.
2025-11-17 10:34:02 -08:00
Justin M. Keyes
5df1112e5f Merge #36338 vim.pack: lockfile synchronization 2025-11-17 09:55:11 -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
Evgeni Chasnovski
f492f62c3d fix(pack): rename confirmation buffer to again use nvim-pack:// scheme
Problem: `nvim://` scheme feels more like a generalized interface that
  may be requested externally, and it acts like CLI args (roughly).
  This is how `vscode://` works.

  Anything that behaves like an "app" or a "protocol" deserves its own
  scheme. For such Nvim-owned things they will be called `nvim-xx://`.

Solution: Use `nvim-pack://confirm#<bufnr>` template for confirmation
  buffer name instead of `nvim://pack-confirm#<bufnr>`.
2025-11-17 12:47:29 +02:00
Evgeni Chasnovski
b151aa761f feat(pack)!: synchronize lockfile with installed plugins when reading it
Problem: Lockfile can become out of sync with what is actually installed
  on disk when user performs (somewhat reasonable) manual actions like:
    - Delete lockfile and expect it to regenerate.
    - Delete plugin directory without `vim.pack.del()`.
    - Manually edit lock data in a bad way.

Solution: Synchronize lockfile data with installed plugins on every
  lockfile read. In particular:

    1. Install immediately all missing plugins with valid lock data.
       This helps with "manually delete plugin directory" case by
       prompting user to figure out how to properly delete a plugin.

    2. Repair lock data for properly installed plugins.
       This helps with "manually deleted lockfile", "manually edited
       lockfile in an unexpected way", "installation terminated due to
       timeout" cases.

    3. Remove unrepairable corrupted lock data and their plugins. This
       includes bad lock data for missing plugins and any lock data
       for corrupted plugins (right now this only means that plugin
       path is not a directory, but can be built upon).

  Step 1 also improves usability in case there are lazy loaded plugins
  that are rarely loaded (like on `FileType` event, for example):
    - Previously starting with config+lockfile on a new machine only
      installs rare `vim.pack.add()` plugin after it is called (while
      an entry in lockfile would still be present). This could be
      problematic if there is no Internet connection, for example.
    - Now all plugins from the lockfile are installed before actually
      executing the first `vim.pack.add()` call in 'init.lua'. And later
      they are only loaded on a rare `vim.pack.add()` call.

  ---

  Synchronizing lockfile on its every read makes it work more robustly
  if other `vim.pack` functions are called without any `vim.pack.add()`.

  ---

  Performance for a regular startup (good lockfile, everything is
  installed) is not affected and usually even increased. The bottleneck
  in this area is figuring out which plugins need to be installed.

  Previously the check was done by `vim.uv.fs_stat()` for every plugin
  in `vim.pack.add()`. Now it is replaced with a single `vim.fs.dir()`
  traversal during lockfile sync while later using lockfile data to
  figure out if plugin needs to be installed.

  The single `vim.fs.dir` approach scales better than `vim.uv.fs_stat`,
  but might be less performant if there are many plugins that will be
  not loaded via `vim.pack.add()` during startup.

  Rough estimate of how long the same steps (read lockfile and normalize
  plugin array) take with a single `vim.pack.add()` filled with 43
  plugins benchmarking:
  - Before commit: ~700 ms
  - After commit:  ~550 ms
2025-11-17 12:47:29 +02:00
Evgeni Chasnovski
60bfc741ed refactor(pack): rearrange lockfile code to be able to use other locals 2025-11-17 12:47:29 +02:00
Evgeni Chasnovski
c3ac329c7a fix(pack)!: ensure plugin is fully absent if not fully installed
Problem: Currently it is possible to have plugin in a "partial install"
  state when `git clone` was successfull but `git checkout` was not.
  This was done to not checkout default branch by default in these
  situations (for security reasons).

  The problem is that it adds complexity when both dealing with lockfile
  (plugin's `rev` might be `nil`) and in how `src` and `version` are
  treated (wrong `src` - no plugin on disk; wrong `version` - "partial"
  plugin on disk).

Solution: Treat plugin as "installed" if both `git clone` and
  `git checkout` are successful, while ensuring that not installed
  plugins are not on disk and in lockfile.

  This also means that if in 'init.lua' there is a `vim.pack.add()` with
  bad `version`, for first install there will be an informative error
  about it BUT next session will also try to install it. The solution is
  the same - adjust `version` beforehand.
2025-11-17 12:47:29 +02:00
Evgeni Chasnovski
9e2599df05 fix(pack)!: adjust install confirm (no error on "No", show names)
Problem: Installation confirmation has several usability issues:
    - Choosing "No" results in a `vim.pack.add()` error. This was by
      design to ensure that all later code that *might* reference
      presumably installed plugin will not get executed. However, this
      is often too restrictive since there might be no such code (like
      if plugin's effects are automated in its 'plugin/' directory).
      Instead the potential code using not installed plugin will throw
      an error.

      No error on "No" will also be useful for planned lockfile repair.

    - List of soon-to-be-installed plugins doesn't mention plugin names.
      This might be confusing if plugins are installed under different
      name.

Solution: Silently drop installation step if user chose "No" and show
  plugin names in confirmation text (together with their pretty aligned
  sources).
2025-11-17 12:46:22 +02:00
Christian Clason
5d258854a7 build(deps): bump luajit to e17ee8332 2025-11-17 10:59:01 +01: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
Jan Edmund Lazo
1be37c245f ci(vim-patches): add N/A tokens to version.c commit #36524 2025-11-16 20:48:43 -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
6e2b514813 fix(system): handle SIGINT in --headless mode #36557
Problem:
When running with `--headless --listen ./hello`, pressing Ctrl-C
doesn’t log anything and doesn’t clean up the socket file.

Solution:
handle SIGINT like SIGTERM.
2025-11-16 18:44:30 -08:00
zeertzjq
ef0c522077 vim-patch:9.1.1918: completion: crash with fuzzy completion (#36578)
Problem:  completion: crash with fuzzy completion
          (Christian Brabandt)
Solution: When completion candidates are gathered from a different
          window, and when completing `<c-p>`, linked list should be
          sorted only after all items are collected (Girish Palya).

fixes: vim/vim#18752
closes: vim/vim#18756

6437997d83

Co-authored-by: Girish Palya <girishji@gmail.com>
2025-11-17 09:33:04 +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
Justin M. Keyes
f0294418d6 Merge #36435 vim.pack: improve default opts.load, handle src change 2025-11-16 13:21:47 -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
alf171
d464dffd2f fix: make :restart respect 'confirm' option #36531
When 'confirm' is set and there are unsaved buffers,
:restart now prompts before quitting, matching the behavior of :quit.
2025-11-16 11:08:38 -08:00