| Commit message (Collapse) | Author | Age |
| ... | |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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#34101
fixes vim/vim#17531
closes: vim/vim#17900
https://github.com/vim/vim/commit/7e0df5eee9eab872261fd5eb0068cec967a2ba77
Co-authored-by: Girish Palya <girishji@gmail.com>
|
| |
|
|
|
|
|
|
|
|
| |
Problem: Cannot specify scope for chdir()
Solution: Add optional scope argument (kuuote)
closes: vim/vim#17888
https://github.com/vim/vim/commit/8a65a49d509d5a9dd5759a4287969896e8941c10
Co-authored-by: kuuote <znmxodq1@gmail.com>
|
| |
|
|
|
|
|
|
| |
Maybe this was unnecessary, but saw this:
https://github.com/vim/vim/issues/17854
https://github.com/vim/vim/commit/d82c918e2f3e6af65c36fb14457968053dcc03a3
Co-authored-by: Girish Palya <girishji@gmail.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
The '?' needs to be escaped, because the autocommand is using
file-patterns (glob like) and not a regex). See :h file-pattern
closes: vim/vim#17890
https://github.com/vim/vim/commit/f7deb815b0b3f326a4b3b5b983da87e46df4f477
Co-authored-by: Girish Palya <girishji@gmail.com>
|
| |
|
|
|
|
|
|
|
|
| |
closes: vim/vim#17857
https://github.com/vim/vim/commit/85cd509885a05c3a6bb029fb378b1295f107f8f6
Omit 'completepopup' and v:colornames.
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
|
| |
|
|
| |
fix #34981
|
| |
|
|
|
|
|
|
| |
Problem:
No way to deduplicate values in a list in-place
Solution:
Add `vim.list.unique()`
|
| |
|
|
|
|
|
| |
Problem:
serverlist() only lists servers that were started by the current Nvim.
Solution:
Look for other Nvim servers in stdpath("run").
|
| |
|
|
|
|
|
|
| |
closes: vim/vim#17824
https://github.com/vim/vim/commit/5711d768181c3b08869ac41ee947a56a26763450
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem: cannot easily trigger wildcard expansion
Solution: Introduce wildtrigger() function
(Girish Palya)
This PR introduces a new `wildtrigger()` function.
See `:h wildtrigger()`
`wildtrigger()` behaves like pressing the `wildchar,` but provides a
more refined and controlled completion experience:
- Suppresses beeps when no matches are found.
- Avoids displaying irrelevant completions (like full command lists)
when the prefix is insufficient or doesn't match.
- Skips completion if the typeahead buffer has pending input or if a
wildmenu is already active.
- Does not print "..." before completion.
This is an improvement on the `feedkeys()` based autocompletion script
given in vim/vim#16759.
closes: vim/vim#17806
https://github.com/vim/vim/commit/b486ed8266d3b8cd1ffab7d7f302fbd6d5a55c70
While at it, also make Ctrl-Z trigger search completion.
Co-authored-by: Girish Palya <girishji@gmail.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
Problem: :retab cannot be limited to indentation only
Solution: add the optional -indentonly parameter
(Hirohito Higashi)
closes: vim/vim#17730
https://github.com/vim/vim/commit/836e54f5de8479a39f6d1dd4a13202af0e447311
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
sorted (#34891)
Problem: tests: string options in gen_opt_test.vim aren't fully sorted.
Solution: Sort the string options alphabetically. Also make description
of 'maxsearchcount' start with lower-case for consistency with
other options, update documentation for searchcount().
closes: vim/vim#17720
https://github.com/vim/vim/commit/7306e8fcdb6fd17276b6aafb23a522cefecb5857
|
| | |
|
| |
|
|
|
|
|
|
|
|
| |
Problem: getcompletiontype() crashes when no completion is available
(after v9.1.1509).
Solution: Don't call set_expand_context() (zeertzjq)
fixes: vim/vim#17681
closes: vim/vim#17684
https://github.com/vim/vim/commit/e2c0f81dd014b03a40af6b2c42463b7a0d92f5d6
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem: Patch 9.1.1505 was not good
Solution: Revert "patch 9.1.1505: not possible to return completion type
for :ex command" and instead add the getcompletiontype()
function (Hirohito Higashi).
related: vim/vim#17606
closes: vim/vim#17662
https://github.com/vim/vim/commit/96b3ef23896ce70b2fdf3425ba2c013ce2840db6
Cherry-pick Test_multibyte_expression() from Vim, as it passes.
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Problem: not possible to return command-line completion type for :ex
command
Solution: make getcmdcompltype() accept an optional and return the
command-line completion for that arg (Shougo Matsushita).
closes: vim/vim#17606
https://github.com/vim/vim/commit/5d2354fc07b642f8835bef27e6dd46ee705726b5
Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Problem: no easy way to deduplicate text
Solution: add the :uniq ex command
(Hirohito Higashi)
closes: vim/vim#17538
https://github.com/vim/vim/commit/74f0a77bb9a170a25b03cacf640aa4e1b1d222b2
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
fix(exrc): lua exrc files know their location
Problem:
'exrc' files are inherently bound to their location / workspace and
therefore require to "know" their location on the filesystem. However,
currently using `debug.getinfo(1, 'S')` returns `"<nvim>"`.
Solution:
Include the filepath as chunkname in `loadstring()` and `nlua_exec()`.
|
| |
|
|
|
|
|
|
|
|
| |
Problem:
Not easy to get user-input in prompt-buffer before the user submits the
input. Under the current system user/plugin needs to read the buffer
contents, figure out where the prompt is, then extract the text.
Solution:
- Add prompt_getinput().
- Extract prompt text extraction logic to a separate function
|
| | |
|
| |
|
|
|
|
|
| |
Co-authored-by: Jan Weinkauff <jan@weinkauff.cloud>
Co-authored-by: MeanderingProgrammer <meanderingprogrammer@gmail.com>
Co-authored-by: Yochem van Rosmalen <git@yochem.nl>
Co-authored-by: phanium <91544758+phanen@users.noreply.github.com>
|
| |
|
|
|
|
|
| |
vim-patch:partial:8f7256a: runtime(doc): fix some style issues and remove obsolete docs
https://github.com/vim/vim/commit/8f7256a5ee5b827722de4e7524da1c2adb68bbae
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
|
| |
|
|
| |
Type fixes caught by emmylua
|
| |
|
|
|
|
|
|
|
| |
```lua
---@type string
local _a = vim.fn.getreg('a', 1)
---@type string[]
local _b = vim.fn.getreg('a', 1, 1)
```
|
| |
|
|
|
|
|
|
|
| |
selections (#34289)
closes: vim/vim#17410
https://github.com/vim/vim/commit/bfeefc474a3ed25852491a93e1e5610774f4de8c
Co-authored-by: Christian Brabandt <cb@256bit.org>
|
| |
|
|
|
|
|
|
|
|
|
| |
Problem: Non-visible/focusable windows are assigned a window number,
whereas commands that use this window number skip over them.
Solution: Skip over non-visible/focusable windows when computing
the window number, unless it is made the current window
through the API in which case an identifiable window number
is still useful. This also ensures it matches the window
number of the window entered by `<winnr>wincmd w` since
403fcacf.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
complete_info() (#34219)
Problem: missing info about register completion in complete_info()
(after v9.1.1408)
Solution: update documentation and mention that register is used as
source, add a test (glepnir)
closes: vim/vim#17389
https://github.com/vim/vim/commit/49864aecd0d23676e202b30bc8705c78ae52d680
Co-authored-by: glepnir <glephunter@gmail.com>
|
| |
|
|
|
|
|
|
|
| |
Problem: "99 searchcount ought to be enough for anyone."
Solution: Increase `SEARCH_STAT_DEF_MAX_COUNT` to 999, which I'm sure
will suffice for the next twenty years.
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
|
| |
|
|
|
|
| |
https://github.com/vim/vim/commit/9973b39a17095e6d77b25aafb73a317cebcf586e
Co-authored-by: Christian Brabandt <cb@256bit.org>
|
| |
|
|
|
|
|
|
|
|
| |
fixes: vim/vim#17273
credit: Github user @msoyka2024
https://github.com/vim/vim/commit/17ad852a62b6e2cf25207292ebca7a748e529d59
Co-authored-by: Christian Brabandt <cb@256bit.org>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem:
`any[]` means nothing, and the return value is not the same as what's
documented in the comment (eg, Lua returns `{ "row", { { "leaf", 1000 },
{ "leaf", 1001 } } }`, not `{ "row", { "leaf", 1000, "leaf", 1001 } }`)
Solution:
Create two classes (vim.fn.winlayout.leaf and vim.fn.winlayout.branch)
and one alias that links the two together.
Also: Due to LuaLS limitations, there is an empty class,
vim.fn.winlayout.empty
Signed-Off-By: VoxelPrismatic <voxelprismatic@pm.me>
|
| | |
|
| |
|
|
|
|
|
|
|
|
| |
clarify complete_match() documentation to better explain its backward
search behavior, argument handling, and return value format and add an
example of isexpand
closes: https://github.com/vim/vim/pull/17212
https://github.com/vim/vim/commit/ffc89e47d014178bcd0a681ff2c8e18470cc972b
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem: Cannot define completion triggers and act upon it
Solution: add the new option 'isexpand' and add the complete_match()
function to return the completion matches according to the
'isexpand' setting (glepnir)
Currently, completion trigger position is determined solely by the
'iskeyword' pattern (\k\+$), which causes issues when users need
different completion behaviors - such as triggering after '/' for
comments or '.' for methods. Modifying 'iskeyword' to include these
characters has undesirable side effects on other Vim functionality that
relies on keyword definitions.
Introduce a new buffer-local option 'isexpand' that allows specifying
different completion triggers and add the complete_match() function that
finds the appropriate start column for completion based on these
triggers, scanning backwards from cursor position.
This separation of concerns allows customized completion behavior
without affecting iskeyword-dependent features. The option's
buffer-local nature enables per-filetype completion triggers.
closes: vim/vim#16716
https://github.com/vim/vim/commit/bcd5995b40a1c26e735bc326feb2e3ac4b05426b
Co-authored-by: glepnir <glephunter@gmail.com>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Problem: cannot complete :filetype arguments (Phạm Bình An)
Solution: add :filetype ex command completion, add "filetypecmd"
completion type for getcompletion()
fixes: vim/vim#17165
closes: vim/vim#17167
https://github.com/vim/vim/commit/a3422aa3170d49a7c3d1e6cd4242b86e42ef3945
Co-authored-by: Christian Brabandt <cb@256bit.org>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Problem: Leaking memory with cmdcomplete()
(zeertzjq, after v9.1.1329)
Solution: free the memory (Girish Palya)
closes: vim/vim#17190
https://github.com/vim/vim/commit/5c3d1e3258872381831f419765f2969f45caaa11
Co-authored-by: Girish Palya <girishji@gmail.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem: cannot get information about command line completion
Solution: add CmdlineLeavePre autocommand and cmdcomplete_info() Vim
script function (Girish Palya)
This commit introduces two features to improve introspection and control
over command-line completion in Vim:
- Add CmdlineLeavePre autocmd event:
A new event triggered just before leaving the command line and before
CmdlineLeave. It allows capturing completion-related state that is
otherwise cleared by the time CmdlineLeave fires.
- Add cmdcomplete_info() Vim script function:
Returns a Dictionary with details about the current command-line
completion state.
These are similar in spirit to InsertLeavePre and complete_info(),
but focused on command-line mode.
**Use case:**
In [[PR vim/vim#16759](https://github.com/vim/vim/pull/16759)], two examples
demonstrate command-line completion: one for live grep, and another for
fuzzy file finding. However, both examples share two key limitations:
1. **Broken history recall (`<Up>`)**
When selecting a completion item via `<Tab>` or `<C-n>`, the original
pattern used for searching (e.g., a regex or fuzzy string) is
overwritten in the command-line history. This makes it impossible to
recall the original query later.
This is especially problematic for interactive grep workflows, where
it’s useful to recall a previous search and simply select a different
match from the menu.
2. **Lack of default selection on `<CR>`**
Often, it’s helpful to allow `<CR>` (Enter) to accept the first match
in the completion list, even when no item is explicitly selected. This
behavior is particularly useful in fuzzy file finding.
----
Below are the updated examples incorporating these improvements:
**Live grep, fuzzy find file, fuzzy find buffer:**
```vim
command! -nargs=+ -complete=customlist,GrepComplete Grep VisitFile()
def GrepComplete(arglead: string, cmdline: string, cursorpos: number):
list<any>
return arglead->len() > 1 ? systemlist($'grep -REIHns "{arglead}"' ..
' --exclude-dir=.git --exclude=".*" --exclude="tags" --exclude="*.swp"') : []
enddef
def VisitFile()
if (selected_match != null_string)
var qfitem = getqflist({lines: [selected_match]}).items[0]
if qfitem->has_key('bufnr') && qfitem.lnum > 0
var pos = qfitem.vcol > 0 ? 'setcharpos' : 'setpos'
exec $':b +call\ {pos}(".",\ [0,\ {qfitem.lnum},\ {qfitem.col},\ 0]) {qfitem.bufnr}'
setbufvar(qfitem.bufnr, '&buflisted', 1)
endif
endif
enddef
nnoremap <leader>g :Grep<space>
nnoremap <leader>G :Grep <c-r>=expand("<cword>")<cr>
command! -nargs=* -complete=customlist,FuzzyFind Find
execute(selected_match != '' ? $'edit {selected_match}' : '')
var allfiles: list<string>
autocmd CmdlineEnter : allfiles = null_list
def FuzzyFind(arglead: string, _: string, _: number): list<string>
if allfiles == null_list
allfiles = systemlist($'find {get(g:, "fzfind_root", ".")} \! \(
-path "*/.git" -prune -o -name "*.swp" \) -type f -follow')
endif
return arglead == '' ? allfiles : allfiles->matchfuzzy(arglead)
enddef
nnoremap <leader><space> :<c-r>=execute('let
fzfind_root="."')\|''<cr>Find<space><c-@>
nnoremap <leader>fv :<c-r>=execute('let
fzfind_root="$HOME/.vim"')\|''<cr>Find<space><c-@>
nnoremap <leader>fV :<c-r>=execute('let
fzfind_root="$VIMRUNTIME"')\|''<cr>Find<space><c-@>
command! -nargs=* -complete=customlist,FuzzyBuffer Buffer execute('b '
.. selected_match->matchstr('\d\+'))
def FuzzyBuffer(arglead: string, _: string, _: number): list<string>
var bufs = execute('buffers', 'silent!')->split("\n")
var altbuf = bufs->indexof((_, v) => v =~ '^\s*\d\+\s\+#')
if altbuf != -1
[bufs[0], bufs[altbuf]] = [bufs[altbuf], bufs[0]]
endif
return arglead == '' ? bufs : bufs->matchfuzzy(arglead)
enddef
nnoremap <leader><bs> :Buffer <c-@>
var selected_match = null_string
autocmd CmdlineLeavePre : SelectItem()
def SelectItem()
selected_match = ''
if getcmdline() =~ '^\s*\%(Grep\|Find\|Buffer\)\s'
var info = cmdcomplete_info()
if info != {} && info.pum_visible && !info.matches->empty()
selected_match = info.selected != -1 ? info.matches[info.selected] : info.matches[0]
setcmdline(info.cmdline_orig). # Preserve search pattern in history
endif
endif
enddef
```
**Auto-completion snippet:**
```vim
set wim=noselect:lastused,full wop=pum wcm=<C-@> wmnu
autocmd CmdlineChanged : CmdComplete()
def CmdComplete()
var [cmdline, curpos] = [getcmdline(), getcmdpos()]
if getchar(1, {number: true}) == 0 # Typehead is empty (no more pasted input)
&& !pumvisible() && curpos == cmdline->len() + 1
&& cmdline =~ '\%(\w\|[*/:.-]\)$' && cmdline !~ '^\d\+$' # Reduce noise
feedkeys("\<C-@>", "ti")
SkipCmdlineChanged() # Suppress redundant completion attempts
# Remove <C-@> that get inserted when no items are available
timer_start(0, (_) => getcmdline()->substitute('\%x00', '', 'g')->setcmdline())
endif
enddef
cnoremap <expr> <up> SkipCmdlineChanged("\<up>")
cnoremap <expr> <down> SkipCmdlineChanged("\<down>")
autocmd CmdlineEnter : set bo+=error
autocmd CmdlineLeave : set bo-=error
def SkipCmdlineChanged(key = ''): string
set ei+=CmdlineChanged
timer_start(0, (_) => execute('set ei-=CmdlineChanged'))
return key != '' ? ((pumvisible() ? "\<c-e>" : '') .. key) : ''
enddef
```
These customizable snippets can serve as *lightweight* and *native*
alternatives to picker plugins like **FZF** or **Telescope** for common,
everyday workflows. Also, live grep snippet can replace **cscope**
without the overhead of building its database.
closes: vim/vim#17115
https://github.com/vim/vim/commit/92f68e26ec36f2c263db5bea4f39d8503e0b741c
Co-authored-by: Girish Palya <girishji@gmail.com>
|
| |
|
|
|
|
|
|
|
|
| |
Problem: tests: test_format fails (after 9.1.1314).
Solution: Increase the string size. Add missing test_format.res in
NEW_TESTS_RES (zeertzjq).
closes: vim/vim#17144
https://github.com/vim/vim/commit/e9a27ef37395a0130f99e21b288b7765f0e38236
|
| | |
|
| |
|
|
| |
Match maparg's return type.
|
| |
|
|
|
|
|
| |
These occurrences also accept string, which is used like in getline.
Also make the lnum field of vim.fn.sign_placelist.list.item optional, as it can
be omitted like vim.fn.sign_place.dict's.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem: Strange error with type for matchfuzzy() "camelcase".
Solution: Show the error "Invalid value for argument camelcase" instead
of "Invalid argument: camelcase" (zeertzjq).
Note that using tv_get_string() will lead to confusion, as when the
value cannot be converted to a string tv_get_string() will also give an
error about that, but "camelcase" takes a boolean, not a string. Also
don't use tv_get_string() for the "limit" argument above.
closes: vim/vim#16926
https://github.com/vim/vim/commit/c4815c157b27923001e44bfd241fb540bf1fb518
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem: When searching for "Cur", CamelCase matches like "lCursor" score
higher than exact prefix matches like Cursor, which is
counter-intuitive (Maxim Kim).
Solution: Add a 'camelcase' option to matchfuzzy() that lets users disable
CamelCase bonuses when needed, making prefix matches rank higher.
(glepnir)
fixes: vim/vim#16504
closes: vim/vim#16797
https://github.com/vim/vim/commit/28e40a7b55ce471656cccc2260c11a29d5da447e
Co-authored-by: glepnir & |