Problem: When the value of an exported variable sources an autoload
script, the script fails to load with E1043.
Solution: Reset is_export while sourcing a script, and remove the reset
added in patch 9.1.1040 (Hirohito Higashi)
closes: #21610
Assisted-by: Claude
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: The NFA engine repeatedly traverses growing patch lists while
compiling optional atoms and decodes the current character
again for keyword and printable character classes.
Solution: Prepend singleton patch lists and reuse the already decoded
character (Julien Voisin)
Compiling optional atoms currently appends singleton entries to the end of
the unresolved patch list. For long optional-character expressions such
as \%[...], each append traverses an increasingly large list, resulting in
quadratic compilation time.
The order of entries in the unresolved patch list does not affect matching
priority, since priority is represented by the out and out1 branches of
NFA_SPLIT states. Prepending singleton entries therefore avoids the list
traversal without changing matching behavior.
In a wall-clock benchmark that forced the NFA engine and compiled a
4,000-character \%[...] expression 100 times, compilation time decreased
from 0.56 seconds to 0.01 seconds. After the change, compiling expressions
containing 1,000, 2,000, and 4,000 characters 1,000 times took 0.02, 0.04,
and 0.09 seconds respectively, demonstrating approximately linear scaling.
Reproducing the benchmarks is simply a matter of running the following script:
```
/usr/bin/time -f 'n=4000 %e s' \
src/vim -Nu NONE -N -n -es \
--cmd 'set regexpengine=2' \
-c 'let p = "\\%[" .. repeat("x", 4000) .. "]"' \
-c 'for i in range(99) | call match("", p .. i) | endfor' \
-c 'qa!'
```
The matching loop also decodes the current input character before
processing active states. Reuse that value for \k, \K, \p, and \P instead
of decoding the same character again, like it's done everywhere else.
closes: #21603
Signed-off-by: Julien Voisin <julien.voisin@dustri.org>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Use-after-free when garbage collection runs in a function that
has a deferred function call, the arguments of the deferred
call are freed.
Solution: Mark the arguments of the deferred function calls when
collecting garbage (Yegappan Lakshmanan).
The arguments of a deferred call are stored in the funccall, but
set_ref_in_funccal() did not mark them. When the arguments were not
referenced elsewhere, a List, Dict or Tuple argument was freed and the
deferred function was called with freed memory.
fixes: #21599closes: #21600
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Invalid memory access when allocating memory fails while
converting a tuple to a string.
Solution: Check the return value of ga_grow() in tuple_join_inner()
and free the item string (Yegappan Lakshmanan).
The result of ga_grow() was ignored and the next item was written to
the unallocated array. Use ga_grow_id() so that the allocation failure
can be tested.
closes: #21598
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Memory leak when allocating memory fails while concatenating
tuples, slicing a tuple or creating a tuple from a literal.
Solution: Free the item that could not be added to the tuple
(Yegappan Lakshmanan).
tuple_append_tv() only takes over the item when it succeeds. On failure
tuple_concat(), tuple_slice() and eval_tuple() did not free the item.
closes: #21596
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: A terminal-mode mapping for a CTRL key, e.g. ":tnoremap <C-E>",
is not used when both the terminal and the job in a terminal
window use the kitty keyboard protocol or modifyOtherKeys, the
key is passed to the job instead.
Solution: For a job using a key protocol only avoid merging the modifier
into the key, so that the key matches the mapping, and make the
letter lowercase when sending it to the job (Milly).
While the job uses a key protocol, term_vgetc() incremented
"no_reduce_keys", which made may_adjust_key_for_ctrl() keep CTRL-e
lowercase, while mappings are stored as CTRL-E. The simplified mapping
(0x05) is skipped because the terminal uses a key protocol, and
check_simplify_modifier() is not used, thus no mapping matched.
Add "no_simplify_keys", used for the terminal instead of
"no_reduce_keys", which only prevents check_simplify_modifier(). Rename
check_no_reduce_keys() to check_no_simplify_keys(). term_convert_key()
now makes the letter lowercase when CTRL is used, always for the kitty
keyboard protocol and only without Shift for modifyOtherKeys, to match
what xterm sends.
closes: #21593
Assisted-by: Claude
Signed-off-by: Milly <milly.ca@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: A tuple with fewer items than the items before the
variadic type is accepted for a variadic tuple type, e.g. (1,)
for tuple<number, string, ...list<number>>.
Solution: Check that a non-variadic tuple has at least the items before
the variadic type (Yegappan Lakshmanan).
The help says that tuple<number, ...list<string>> is a tuple with an item
of type Number followed by zero or more items of type String, but the
leading items were not required.
fixes: #21591closes: #21592
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: The item type is lost when indexing a tuple literal with
one item in a compiled function, a type error is only found at
runtime.
Solution: Set the declared type instead of overwriting the item type
(Yegappan Lakshmanan).
fixes: #21589closes: #21590
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Strip all references to 32-bit (i686) MinGW/MSYS2 builds: the
32-bit installer download, mingw-w64-i686-toolchain package,
32-bit MSYS2 paths and batch files, 32-bit pacboy suffixes, and
32-bit Lua/Ruby/GvimExt paths in sections 2, 3, 9, 11, and 17.
64-bit and ARM64 instructions are unaffected.
closes: #21639
Signed-off-by: Philip H. <47042125+pheiduck@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
MSYS2 no longer ships 32-bit (i686) mingw-w64 packages, including
mingw-w64-i686-make, so `pacboy -S make:p gcc:p` fails once MSYSTEM
resolves to MINGW32:
error: target not found: mingw-w64-i686-make
Upstream has been dropping i686 mingw-w64 packages since the
2023-12-13 "starting to drop some 32-bit packages" announcement, and
the community-maintained 32-bit fallback repo stopped updating in
November 2025, so there's no maintained path to keep this working.
Move the two mingw+x86 matrix entries to x64. 32-bit coverage is
still provided by the existing MSVC x86 entries; only the
MinGW-on-x86 combination is removed.
related: #21639
Signed-off-by: Philip H. <47042125+pheiduck@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: In a compiled function, when unpacking a tuple in a :for
loop, the variable after ";" gets a list with the remaining
items instead of a tuple.
Solution: Create a tuple with the remaining items (Yegappan Lakshmanan).
The help says that the variable after ";" gets a tuple, this was already
the case when not in a compiled function.
fixes: #21587closes: #21588
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Using a tuple with :echomsg, :echoerr, :echowindow or
:echoconsole gives an error, while a List can be used.
Solution: Use string() for a tuple in tv_stringify() (Yegappan Lakshmanan).
The help for :echomsg says that string() is used for an expression that
does not evaluate to a Number or String.
fixes: #21585closes: #21586
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Crash when the "paste" callback of a clipboard provider returns
a null tuple or a null list.
Solution: Check for a NULL tuple and a NULL list before using the
returned value (Yegappan Lakshmanan).
fixes: #21583closes: #21584
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: As stated in :help i_CTRL-X_CTRL-F, 'path' is not yet used for
filename completion.
Solution: Add EW_PATH flag in expand_wildcards of
get_next_filename_completion() (Fabian Wermelinger).
* Add new "pathopt" in 'completeopt' to enable 'path' consultation during
filename completion (not enabled by default).
* Add a new Test_ins_complete_files_in_path case for test_ins_complete.
* Update corresponding runtime/doc files.
closes: #21445
Signed-off-by: Fabian Wermelinger <fabian@git.0xfab.ch>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: crash when concatenating tuples in a compiled function
when the number of items in one of the tuples is not known.
Solution: Use the tuple<any> type for the result when the number of items
in either tuple is unknown. Do not read past the end of the
item types when setting the type of a tuple
(Yegappan Lakshmanan).
When one of the operands has the type tuple<any> (e.g. a variable that
was initialized with an empty tuple), the type of the concatenated tuple
left out the item types of that operand. The resulting type had fewer
items than the tuple value, and setting this type on the value read past
the end of the item types and used an invalid pointer.
fixes: #21581closes: #21582
Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: Garbage collection of tuples is not tested.
Solution: Add tests for garbage collection of tuples in global,
script-local, buffer, window, tab page and Vim9 script
variables, function variables and arguments, closures, the
arguments of a partial, timer and popup callbacks, objects and
class variables, quickfix lists, deeply nested tuples and
cycles through a tuple (Yegappan Lakshmanan).
closes: #21579
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim syntax highlighting can sometimes be a bit slow, and it
might be unclear as to why.
Solution: Document a couple of tips to speed up syntax highlighting.
related: #21513
closes: #21572
Signed-off-by: jvoisin <julien.voisin@dustri.org>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: Some tuple functionality is not tested
Solution: Add more tuple tests (Yegappan Lakshmanan)
Add tests for comparing tuples with items of different types, tuples as
List items, functions that don't support a tuple, printf() with a tuple,
removing a tuple item and using a compound operator on it, a tuple as a
Dict key, exists() with a tuple item, :break and :continue in a :for
loop over a tuple, a tuple as a default argument and in a closure,
shared references and locking with deepcopy(), tuple type aliases, typed
unpacking, interfaces and enums, lambdas and varargs, 'ignorecase',
:const and :final, errors in a tuple item, String indexes,
import/export, Lists of tuples, operators that cannot be used with a
tuple, a tuple as a condition, a Funcref tuple item, nested tuple type
mismatches, repeatedly concatenating and slicing a tuple and tuples from
an autoload script
closes: #21578
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: Several Vim9 instructions generated for tuples are not
covered by disassemble tests.
Solution: Add more tests (Yegappan Lakshmanan)
Add disassemble tests for using a null tuple, unpacking a tuple, looping
over a tuple, all the compare operators, concatenating with a variadic
tuple and with an "any" value, type checks for function arguments,
return values, type casts and tuple items, tuples in a List, a Dict and
an object variable, a generic function, using a tuple as a boolean, the
different index and slice forms, converting a tuple to a string,
variadic tuple types, a script-local tuple variable and builtin
functions
closes: #21577
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When 'smoothscroll' is enabled, wrapped lines with virtual
text above do not scroll smoothly.
Solution: Do not count skipped virtual text above multiple times and
do not count its width again when skipping to the first
displayed character (Yamagi).
related: #21336
closes: #21556
Assisted-by: Claude
Signed-off-by: Yamagi <yamagi@yamagi.org>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: After a forced blockwise exclusive motion that makes a
one-column block, such as "d<C-V>`x" with the mark at the
cursor, "d" and "c" do nothing.
Solution: Do not use the inclusive flag to find an empty region for a
block, because "oap->end" is already the last column of the
block (Nagato Yuzuru).
fixes: #21547
related: #21540
related: neovim/neovim#24613
closes: #21548
Assisted-by: Claude
Signed-off-by: Nagato Yuzuru <nagato@yuzuru.me>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Error E1016 is used for 2 different things
(Ivan Pešić)
Solution: Use E1000 for the environment variable error.
fixes: #21522closes: #21538
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: vim_strchr(p, *p) == NULL is dead code, it always returns
p.
Solution: Use vim_strchr(p + 1, *p) instead (Sami Farin)
A single, lone unclosed backtick or apostrophe (e.g., `it's_a_file.txt`)
will **never** be skipped by continue. Instead, it immediately causes
has_special_wildchar() to return TRUE, forcing
gen_expand_wildcards() to bypass internal globbing and delegate
directly to the external shell via mch_expand_wildcards().
closes: #21523
related: 26262f8777
Assisted-by: Google Gemini 3.8
Signed-off-by: Sami Farin <hvtaifwkbgefbaei@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Commands with a pattern address containing the delimiter in a
collection fail (after v7.4.530).
Solution: Skip the delimiter when it appears in a pattern collection
(Doug Kearns).
closes: #21554
Signed-off-by: Doug Kearns <dougkearns@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: GTK4: the accelerator text in menu items is not dimmed
Solution: Add the "dim-label" CSS class to the accelerator label
(Sylvain Cresto).
closes: #21552
Signed-off-by: Sylvain Cresto <scresto@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: After a forced blockwise exclusive motion, such as "y<C-V>l"
or "g@<C-V>l", '] is one character before the last character
of the block.
Solution: Do not exclude the end position for a block, because
"oap->end" is already the last column of the block
(Nagato Yuzuru).
fixes: #21511closes: #21540
Assisted-by: Claude
Signed-off-by: Nagato Yuzuru <nagato@yuzuru.me>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: vimglob() fails for patterns starting with a -
(Sami Farin)
Solution: Use printf instead of echo for the vimglob() function
fixes: #21524closes: #21537
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: tests: test_terminal2.vim is flaky
Solution: Instead of reading the terminal output directly, redirect to a
file (Philip H.)
closes: #21549
Signed-off-by: Philip H. <47042125+pheiduck@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Sourcing a file expands its full name twice, which is slow on
MS-Windows when SourceCmd autocommands are defined.
Solution: Use the name already made full by fix_fname() for the
SourceCmd check (Yasuhiro Matsumoto).
do_source_ext() makes the file name a full path with fix_fname(), but
has_autocmd() expanded it again. On MS-Windows this calls
GetLongPathNameW() once more, which takes about 0.3 ms for a deep path, and
netrw and vimball always define SourceCmd autocommands. With my
configuration sourcing an empty file takes about 310 us instead of 520 us,
and startup goes from 380 ms to 339 ms (median of 11 runs).
closes: #21526
Assisted-by: Claude Opus 5.5
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: On MS-Windows, "O" in a local listing does not copy the file,
Test_netrw_obtain_local() fails with E484. "cmd /c copy" does
not handle the composed source and target paths.
Solution: Use filecopy() for each file, as s:NetrwMarkFileCopy() does.
closes: #21534
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Yoko Davis <56965728+revesis@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Pressing "O" in a local listing reports "cannot determine
method" instead of copying the file to the current directory
as documented in |netrw-O|.
Solution: Use the islocal argument of netrw#Obtain() instead of
b:netrw_islocal, and copy the files from b:netrw_curdir.
b:netrw_islocal is only set when a file is marked while other files are
already marked, so without marks netrw#Obtain() took the remote branch.
The names in the listing are relative to b:netrw_curdir, which is not
vim's current directory when netrw obtains a file, so the local copy
command could not find them.
related: #21534
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Yoko Davis <56965728+revesis@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: netrw#Obtain() passes the hostname to netrw#msg#Notify() as a
third argument, so instead of "Rejecting invalid hostname"
the user gets E118: Too many arguments for function.
Solution: Format the message with printf() first, as the other
"Rejecting invalid hostname" messages in netrw already do.
related: #21534
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Yoko Davis <56965728+revesis@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: GTK4: tab pages looks dated, missing close button
Solution: Use flat rounded tabs that share the width of the tab line,
with a close button on each tab (Sylvain Cresto).
closes: #21525
Assisted-by: Claude Opus
Signed-off-by: Sylvain Cresto <scresto@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: ga_concat() only works for INT_MAX length items, trying to
grow past this size causes an overflow (Venukamatchi).
Solution: Error out when the final size would be larger than INT_MAX.
closes: #21520
Assisted-by: Claude
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: when a function called with :silent! fails to load
a variable, the value is missing from the stack causing a
crash (waroad).
Solution: Push a zero value.
closes: #21519
Assisted-by: Claude
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: when a class is freed, e.g. when sourcing its script
again, a global function with the same name as one of its
methods is removed from the function table and cannot be used
anymore.
Solution: Only remove a function from the function table when it is the
function in the table (Yegappan Lakshmanan).
fixes: #21571closes: #21510
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: memory leak when the return type of a lambda is invalid
after argument types that were allocated, e.g.
"(x: list<list<number>>): nosuch => x".
Solution: Free the types and the variable arguments name of the lambda
(Yegappan Lakshmanan).
fixes: #21570closes: #21509
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: when a class implements interfaces and extends a class
that implements interfaces, checking whether an interface of
the parent class is already present reads past the garray
structure instead of using its items.
Solution: Use the items of the garray (Yegappan Lakshmanan).
fixes: #21569closes: #21508
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Similar to "sh.vim", there are a handful of other filetypes
whose names (assigned to "b:current_syntax") are different
from the base names of their syntax plugins, e.g. "python2"
and "elsa". Two scripts, "testdir/tools/maketestdeps" and
"testdir/runtest.vim", currently assume that the base name
of a syntax plugin can be derived from the name of a syntax
test. Prescribe using the base name of the syntax plugin,
instead of its filetype, for a test filename prefix so that
existing files are listed in Make targets ("maketestdeps")
and name correspondence is kept between the syntax plugin
and optional test settings for it ("runtest.vim"). Add a CI
check for name verification.
closes: #21414
Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: a type variable of a generic function can have the name
of the function itself, e.g. "def Foo<Foo>()".
Solution: Give an error for a type variable with the name of the
function, like for other script items (Yegappan Lakshmanan).
fixes: #21560closes: #21505
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: when a generic function with variable arguments is used
with type arguments, the type variable in the variable arguments
type is not replaced in the function type, e.g. it is
"func(...list<any>)" instead of "func(...list<number>)".
Solution: Also replace the type variable in the function type
(Yegappan Lakshmanan).
fixes: #21568closes: #21507
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: a type variable name matches a longer type variable name
that starts with it, e.g. "def Fn<TT, T>()" gives a duplicate
type variable error and in "def Fn<TT>(x: T)" the type "T" is
"TT".
Solution: Also check the end of the name (Yegappan Lakshmanan).
fixes: #21567closes: #21506
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: memory leak when a generic function or method is used in
a def function with an invalid type argument after a valid
one.
Solution: Free the parsed type arguments (Yegappan Lakshmanan).
fixes: #21551closes: #21504
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: buffer overflow when a generic function with very long
type arguments is used with ":call" or call().
Solution: Allocate the name with the type arguments instead of using
IObuff (Yegappan Lakshmanan).
fixes: #21544closes: #21503
Assisted-by: Claude
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>