Problem: on_detach may be called after buf_freeall and other important things,
plus its textlock restrictions are insufficient. This can cause issues such as
leaks, internal errors and crashes.
Solution: disable buffer updates in buf_freeall, before autocommands (like the
order after #35355 and when do_ecmd reloads a buffer). Don't do so in
free_buffer_stuff; it's not safe to run user code there, and buf_freeall already
runs before then; just free them to avoid leaks if buf_freeall autocommands
registered more for some reason.
Fixes#28084Fixes#33967Fixes#35116
Problem:
Buffer-updates on_detach callback is invoked before buf_freeall(), which
deletes autocmds of the buffer (via apply_autocmds(EVENT_BUFWIPEOUT,
...)). Due to this, buffer-local autocmds executed in on_detach (e.g.,
LspDetach) are not actually invoked.
Solution:
Call buf_updates_unload() before buf_freeall().
Problem: Unicode has deprecated some code-points
Solution: Update the digraph tables to align with the Unicode v16
release (David Friant)
This commit updates the digraphs Left-Pointing Angle Bracket '</'
and Right-Pointing Angle Bracket '/>' to account for the fact that
the old Unicode codepoints for them (2329 and 232A, respectively)
have been deprecated. As per the Miscellaneous Technical code chart
(https://www.unicode.org/charts/PDF/U2300.pdf), the old digraphs
have been reassigned to the CJK Left Angle Bracket and Right Angle
Bracket (3008 and 3009) with their declaration moved to the
appropriate block.
This commit also introduces the new digraphs '<[' and ']>' to
represent the Mathematical Left Angle Bracket and Mathematical
Right Angle Bracket (27E8 and 27E9) to replace the deprecated code
points in the Technical block.
Tests have been added and, I believe, the documentation has been
updated accordingly.
closes: vim/vim#17990c08b94b072
Co-authored-by: David Friant <friant@HPEnvyx360.friant.dev>
Some terminals support the CSI 8 t sequence to resize their own window
area. Neovim will emit this sequence when the TUI is resized
programatically, but it should not be emitted when the TUI is resized
because the host terminal was resized, as that results in an infinite
resize loop.
These are not needed after #35129 but making uncrustify still play nice
with them was a bit tricky.
Unfortunately `uncrustify --update-config-with-doc` breaks strings
with backslashes. This issue has been reported upstream,
and in the meanwhile auto-update on every single run has been disabled.
Problem: fuzzy.c has a few issues
Solution: Use Vims memory management, update style
(glepnir)
Problem:
- Missing cleanup of lmatchpos lists causing memory leaks
- Missing error handling for list operations
- Use of malloc() instead of Vim's alloc() functions
- Inconsistent C-style comments
- Missing null pointer checks for memory allocation
- Incorrect use of vim_free() for list objects
Solution:
- Add proper cleanup of lmatchpos in done section using list_free()
- Set lmatchpos to NULL after successful transfer to avoid confusion
- Add error handling for list_append_tv() failures
- Replace malloc() with alloc() and add null pointer checks
- Convert C-style comments to C++ style for consistency
- Fix vim_free() calls to use list_free() for list objects
closes: vim/vim#1798417a6d696bd
Co-authored-by: glepnir <glephunter@gmail.com>
Problem: fuzzy-matching can be improved
Solution: Implement a better fuzzy matching algorithm
(Girish Palya)
Replace fuzzy matching algorithm with improved fzy-based implementation
The
[current](https://www.forrestthewoods.com/blog/reverse_engineering_sublime_texts_fuzzy_match/)
fuzzy matching algorithm has several accuracy issues:
* It struggles with CamelCase
* It fails to prioritize matches at the beginning of strings, often
ranking middle matches higher.
After evaluating alternatives (see my comments
[here](https://github.com/vim/vim/issues/17531#issuecomment-3112046897)
and
[here](https://github.com/vim/vim/issues/17531#issuecomment-3121593900)),
I chose to adopt the [fzy](https://github.com/jhawthorn/fzy) algorithm,
which:
* Resolves the aforementioned issues.
* Performs better.
Implementation details
This version is based on the original fzy
[algorithm](https://github.com/jhawthorn/fzy/blob/master/src/match.c),
with one key enhancement: **multibyte character support**.
* The original implementation supports only ASCII.
* This patch replaces ascii lookup tables with function calls, making it
compatible with multibyte character sets.
* Core logic (`match_row()` and `match_positions()`) remains faithful to
the original, but now operates on codepoints rather than single-byte
characters.
Performance
Tested against a dataset of **90,000 Linux kernel filenames**. Results
(in milliseconds) show a **\~2x performance improvement** over the
current fuzzy matching algorithm.
```
Search String Current Algo FZY Algo
-------------------------------------------------
init 131.759 66.916
main 83.688 40.861
sig 98.348 39.699
index 109.222 30.738
ab 72.222 44.357
cd 83.036 54.739
a 58.94 62.242
b 43.612 43.442
c 64.39 67.442
k 40.585 36.371
z 34.708 22.781
w 38.033 30.109
cpa 82.596 38.116
arz 84.251 23.964
zzzz 35.823 22.75
dimag 110.686 29.646
xa 43.188 29.199
nha 73.953 31.001
nedax 94.775 29.568
dbue 79.846 25.902
fp 46.826 31.641
tr 90.951 55.883
kw 38.875 23.194
rp 101.575 55.775
kkkkkkkkkkkkkkkkkkkkkkkkkkkkk 48.519 30.921
```
```vim
vim9script
var haystack = readfile('/Users/gp/linux.files')
var needles = ['init', 'main', 'sig', 'index', 'ab', 'cd', 'a', 'b',
'c', 'k',
'z', 'w', 'cpa', 'arz', 'zzzz', 'dimag', 'xa', 'nha', 'nedax',
'dbue',
'fp', 'tr', 'kw', 'rp', 'kkkkkkkkkkkkkkkkkkkkkkkkkkkkk']
for needle in needles
var start = reltime()
var tmp = matchfuzzy(haystack, needle)
echom $'{needle}' (start->reltime()->reltimefloat() * 1000)
endfor
```
Additional changes
* Removed the "camelcase" option from both matchfuzzy() and
matchfuzzypos(), as it's now obsolete with the improved algorithm.
related: neovim/neovim#34101fixesvim/vim#17531closes: vim/vim#179007e0df5eee9
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: C-indent does not handle compound literals
(@44100hertz, @Jorenar)
Solution: Detect and handle compound literal and structure
initialization (Anttoni Erkkilä)
match '=' or "return" optionally followed by &, (typecast), {
Fixes also initialization which begins with multiple opening braces.
fixes: vim/vim#2090fixes: vim/vim#12491closes: vim/vim#178655ba6e41d37
Co-authored-by: Anttoni Erkkilä <anttoni.erkkila@protonmail.com>
Problem: Autocompletion slow with include- and tag-completion
Solution: Refactor ins_compl_interrupted() to also check for timeout,
further refactor code to skip outputting message when
performing autocompletion (Girish Palya).
Running `vim *` in `vim/src` was slower than expected when
'autocomplete' was enabled. Include-file and tag-file completion
sources were not subject to the timeout check, causing unnecessary
delays.
So apply the timeout check to these sources as well, improving
autocompletion responsiveness, refactor find_pattern_in_path() to take
an additional "silent" argument, to suppress any messages.
closes: vim/vim#1796659e1d7f353
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: parse_cmdline() sets eap->cmdlinep to address of local parameter,
causing invalid memory access when expand_filename() tries to modify it.
This leads to crashes when typing '%' in user commands with preview=true
and complete=file.
Solution: Change parse_cmdline() signature to accept char **cmdline,
allowing cmdlinep to point to caller's variable for safe reallocation.
problem: most shada entries use weird `PossiblyFreedShadaEntry` type
solution: delet it
Shada entries can either be allocated by shada.c when reading,
or be constructed to represent the state of the current instance,
with direct references to live instance data to avoid extra allocations.
shada.c needs to carefully only free memory allocated by the first case,
and not free memory owned by other subsystems.
In some part of the code, this is inferred by the context but in others
we are mixing entries from different sources and need to indicate
the provenance by a `can_free_entry` flag. However constantly
frontloading this distinction in the name of the type and with
extra nesting levels, cause extra cognitive overhead when trying
to understand the code in any other aspects than the specific detail
of avoiding leaks/double frees.
As we always know if the memory is owned or not for any entry, we
can just put `can_free_entry` directly on the ShadaEntry struct.
That only one state is possible in a given context, is indicated
by this neat little syntactical construct called a constant field
initializer.
Problem:
During preview, the `input` still prompts the user to enter something
that won't be used later, which could be a bit confusing.
e.g., `:s/a/\=input("")`.
Solution:
Make the input() return early during 'inccommand' preview.
Problem:
gen_help_html.lua script misinterprets parts of ASCII diagrams as help tags
(e.g., `|_________|` in `usr_28.txt`). This incorrectly triggered
special alignment-fixing logic that is meant for columnar text.
Signed-off-by: Shashwat Agrawal <shashwatagrawal473@gmail.com>
Problem: Byte2line() does not work correctly with text properties. (Billie
Cleek)
Solution: Take the bytes of the text properties into account.
(closesvim/vim#5334)
9df53b62de
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: Listener callback called at the wrong moment
Solution: Invoke listeners before calling ml_delete_int(). (closesvim/vim#4657)
acf7544cf6
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: Listener callback called for the wrong buffer.
Solution: Invoke listeners before calling ml_append_int().
250e3112c6
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: completion: incorrect selected index returned from
complete_info()
Solution: Return the index into "items" and restore the previous
behaviour (Robert Muir).
complete_info() returned an incorrect selected index after
0ac1eb3555445f4c458c06cef7c411de1c8d1020 (Patch v9.1.1311). Effectively
it became an index into "matches" instead of "items". Return the index
into "items" by default to restore the previous behavior, unless
"matches" was requested.
closes: vim/vim#179528e2a229189
Co-authored-by: Robert Muir <rmuir@apache.org>
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Problem: Ctrl-G/Ctrl-T does not ignore the end search delimiter
(irisjae)
Solution: Check if the pattern ends with a search delimiter and ignore
it, unless it is part of the pattern.
fixes: vim/vim#17895closes: vim/vim#17933c03990d30f
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: possible undefined behaviour in mb_decompose(), when using the
same pointer as argument several times
Solution: use separate assignments to avoid reading and writing the same
object at the same time (Áron Hárnási)
closes: vim/vim#17953c43a0614d4
Co-authored-by: Áron Hárnási <aron.harnasi@gmail.com>
Problem: completion: cannot use autoloaded funcs in 'complete' F{func}
(Maxim Kim)
Solution: Make it work (Girish Palya)
fixes: vim/vim#17869closes: vim/vim#178851bfe86a7d3
Cherry-pick Test_omni_autoload() from patch 8.2.3223.
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: The :keep{alt,jumps,marks,patterns} commmands are sometimes
misidentified as :k.
Solution: Make sure one_letter_cmd() only returns true for :k and not
other :keep* commands (Doug Kearns).
This currently manifests as missing completion for :keep* commands and
incorrect results from fullcommand().
E.g., fullcommand("keepmarks") returns "k" rather than "keepmarks".
The correct command, however, is executed as command modifiers are
handled specially in do_one_cmd() rather than using find_ex_command().
Fix exists(':k') so that it returns 2 for a full match.
closes: vim/vim#15742ea84202372
Cherry-pick Test_ex_command_completion() from patch 9.1.0624.
Co-authored-by: Doug Kearns <dougkearns@gmail.com>
Problem: completion: hang (after 9.1.1471) or E684 (after 9.1.1410)
when 'tagfunc' calls complete().
Solution: Check if complete() has been called immediately after getting
matches instead of in the next loop iteration (zeertzjq).
related: vim/vim#1668
related: neovim/neovim#34416
related: neovim/neovim#35163closes: vim/vim#17929982cda6976
Problem: completion: incsearch highlight might be lost after search
completion (Hirohito Higashi)
Solution: Restore incsearch highlight after dismissing pum with Ctrl-E
(Girish Palya)
related: vim/vim#17870closes: vim/vim#1789104c9e78cd3
This change actually isn't needed as Nvim doesn't call update_screen()
to redraw pum, but it doesn't hurt either.
Co-authored-by: Girish Palya <girishji@gmail.com>
When Nvim is started in one terminal emulator,
suspended, and later resumed in a different terminal emulator (as can
happen when using e.g. a multiplexer), the new terminal emulator will
not have all of the same modes enabled that the original terminal
emulator had. This is a problem in particular for in-band resize events
because we were disabling the SIGWINCH signal handler when we determined
that the terminal supported this mode.
However, if the new terminal does not support this mode then the
SIGWINCH handler remains disabled, and Neovim no longer properly
resizes. Instead of disabling the SIGWINCH handler, we track the state
of the resize events mode internally. If the mode is enabled then we
return early from the SIGWINCH handler before performing any ioctls or
other system calls. But if the mode is not enabled we proceed as normal.
Problem: :bnext doesn't go to unlisted help buffers when cycling
through help buffers (after 9.1.0557).
Solution: Don't check if a help buffer is listed (zeertzjq).
From <https://github.com/vim/vim/issues/4478#issuecomment-498831057>:
> I think we should fix that, since once you get to a non-help buffer
> all unlisted buffers are skipped, thus you won't encounter another
> help buffer.
This implies that cycling through help buffers should work even if help
buffers are unlisted. Otherwise this part of :bnext isn't really useful,
as :h makes help buffers unlisted by default.
related: vim/vim#4478
related: vim/vim#15198closes: vim/vim#179139662f33480
Problem: diff: using diff anchors with hidden buffers fails silently
Solution: Give specific error message for diff anchors when using hidden
buffers (Yee Cheng Chin).
Diff anchors currently will fail to parse if a buffer used for diff'ing
is hidden. Previously it would just fail as the code assumes it would
not happen normally, but this is actually possible to do if `closeoff`
and `hideoff` are not set in diffopt. Git's default diff tool "vimdiff3"
also takes advantage of this.
This fix this properly would require the `{address}` parser to be
smarter about whether a particular address relies on window position or
not (e.g. the `'.` address requires an active window, but `'a` or `1234`
do not). Since hidden diff buffers seem relatively niche, just provide a
better error message / documentation for now. This could be improved
later if there's a demand for it.
related: vim/vim#17615closes: vim/vim#17904cad3b2421d
Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>