Skip to content

fix(core): Harden grep fallback and parser detection#31

Merged
mhiro2 merged 2 commits intomainfrom
fix/grep-fallback-and-symbol-parser
Apr 26, 2026
Merged

fix(core): Harden grep fallback and parser detection#31
mhiro2 merged 2 commits intomainfrom
fix/grep-fallback-and-symbol-parser

Conversation

@mhiro2
Copy link
Copy Markdown
Owner

@mhiro2 mhiro2 commented Apr 26, 2026

Summary

  • Keep the editor responsive during the grep fallback by dispatching ripgrep asynchronously and
    scheduling the quickfix update on the main loop.
  • Stop vimgrep-based fallback from descending into VCS metadata, dependency caches, and build
    outputs, and notify the user before the synchronous scan starts.
  • Make PinWordSymbol honor its documented cword fallback when the buffer has no Treesitter
    parser registered.

Changes

  • 7b1e516 : fix(symbol): guard parser detection so PinWordSymbol falls back to cword
    • Wrap vim.treesitter.get_parser in pcall so filetypes without a registered parser no
      longer raise out of has_parser, restoring the documented cword fallback path for
      PinWordSymbol.
    • Add regression tests covering the parser-missing case at both the has_parser and
      PinWordSymbol command levels.
  • c4e2fac : fix(grep): harden fallback to keep the UI responsive on large projects
    • Run the ripgrep fallback through the callback form of vim.system and apply quickfix
      updates via vim.schedule, so large repositories no longer freeze the UI while results are
      gathered.
    • Notify the user before the synchronous vimgrep fallback runs and extend wildignore only
      for the duration of the call to skip common VCS, dependency, cache, and build directories.
    • Update and add tests to cover the new async dispatch shape, the scan-start notification,
      and the wildignore set/restore behavior.

mhiro2 added 2 commits April 26, 2026 19:22
Wrap vim.treesitter.get_parser in pcall: filetypes without a registered
parser raise from get_parser, which otherwise prevents has_parser from
returning false and breaks the documented cword fallback for
PinWordSymbol.
Run the ripgrep fallback through the asynchronous form of vim.system so
the editor stays responsive while results are gathered, and schedule the
quickfix update on the main loop. When ripgrep is unavailable, notify
the user that a synchronous scan is starting and extend wildignore for
the duration of the vimgrep call so common VCS, dependency, cache, and
build directories are skipped.
@mhiro2 mhiro2 self-assigned this Apr 26, 2026
@mhiro2 mhiro2 added the bug Something isn't working label Apr 26, 2026
@github-actions
Copy link
Copy Markdown

Benchmark Results

nvim --headless -u NONE -c "lua dofile('bench/run.lua')" -c "qa!"

== bench.bench_reapply ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
reapply_all  slots=1 wins=1                         50          2.8          0.7         20.6
reapply_all  slots=1 wins=5                         50          6.2          3.4         21.0
reapply_all  slots=1 wins=10                        50         13.9          6.2         32.3
reapply_all  slots=1 wins=20                        50         13.7         12.2         42.0
reapply_all  slots=5 wins=1                         50          1.5          0.7         24.7
reapply_all  slots=5 wins=5                         50          6.2          4.1         10.6
reapply_all  slots=5 wins=10                        50         17.0          7.6         47.6
reapply_all  slots=5 wins=20                        50         17.9         14.2         43.6
reapply_all  slots=9 wins=1                         50          2.1          0.9         30.1
reapply_all  slots=9 wins=5                         50         12.2          5.0         42.5
reapply_all  slots=9 wins=10                        50          9.5          8.5         25.7
reapply_all  slots=9 wins=20                        50         26.4         16.4         80.8
---------------------------------------------------------------------------------------------

== bench.bench_apply ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
apply_slot_globally  wins=1                        100          5.4          3.9         28.2
apply_slot_globally  wins=5                        100         19.7         18.8         37.5
apply_slot_globally  wins=10                       100         45.5         37.3        110.6
apply_slot_globally  wins=20                       100         84.3         75.5        166.6
apply_slot_for_window  existing=0                  200          4.4          3.7         30.3
apply_slot_for_window  existing=5                  200          6.8          4.2         46.0
apply_slot_for_window  existing=9                  200          5.2          4.6         29.4
---------------------------------------------------------------------------------------------

== bench.bench_clear ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
clear_all_globally  slots=1 wins=1                  30         68.1         47.6        141.2
clear_all_globally  slots=1 wins=5                  30        185.7        135.5        383.8
clear_all_globally  slots=1 wins=10                 30        291.9        240.1        471.8
clear_all_globally  slots=5 wins=1                  30        118.2         78.0        213.5
clear_all_globally  slots=5 wins=5                  30        275.9        235.2        484.4
clear_all_globally  slots=5 wins=10                 30        521.2        447.2        803.3
clear_all_globally  slots=9 wins=1                  30        129.4         99.2        277.2
clear_all_globally  slots=9 wins=5                  30        391.4        341.3        670.1
clear_all_globally  slots=9 wins=10                 30        715.3        645.4       1013.5
---------------------------------------------------------------------------------------------

== bench.bench_set_clear ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
set+clear cycle  wins=1                             50         26.7         13.5        209.3
set+clear cycle  wins=5                             50         38.9         36.0         59.6
set+clear cycle  wins=10                            50         75.2         67.2        122.5
---------------------------------------------------------------------------------------------

== bench.bench_jump ==---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
jump.next  slots=1                                 100         22.6          9.2         63.2
jump.next  slots=5                                 100       5104.6       4995.6       5669.4
jump.next  slots=9                                 100      15219.2      15031.4      16538.9
---------------------------------------------------------------------------------------------

== bench.bench_cword ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
apply_cword_for_window                             200          2.7          2.1         50.1
---------------------------------------------------------------------------------------------

== bench.bench_symbol ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
symbol: get_symbol (on identifier)                 200          8.5          4.4         83.8
symbol: get_symbol (on keyword)                    200         13.1          5.5         51.4
symbol: set+clear cycle (source=symbol)             50         23.7         17.1         83.2
symbol: set+clear cycle (source=cword)              50         15.6         13.1         45.9
---------------------------------------------------------------------------------------------

== SUMMARY ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
reapply_all  slots=1 wins=1                         50          2.8          0.7         20.6
reapply_all  slots=1 wins=5                         50          6.2          3.4         21.0
reapply_all  slots=1 wins=10                        50         13.9          6.2         32.3
reapply_all  slots=1 wins=20                        50         13.7         12.2         42.0
reapply_all  slots=5 wins=1                         50          1.5          0.7         24.7
reapply_all  slots=5 wins=5                         50          6.2          4.1         10.6
reapply_all  slots=5 wins=10                        50         17.0          7.6         47.6
reapply_all  slots=5 wins=20                        50         17.9         14.2         43.6
reapply_all  slots=9 wins=1                         50          2.1          0.9         30.1
reapply_all  slots=9 wins=5                         50         12.2          5.0         42.5
reapply_all  slots=9 wins=10                        50          9.5          8.5         25.7
reapply_all  slots=9 wins=20                        50         26.4         16.4         80.8
apply_slot_globally  wins=1                        100          5.4          3.9         28.2
apply_slot_globally  wins=5                        100         19.7         18.8         37.5
apply_slot_globally  wins=10                       100         45.5         37.3        110.6
apply_slot_globally  wins=20                       100         84.3         75.5        166.6
apply_slot_for_window  existing=0                  200          4.4          3.7         30.3
apply_slot_for_window  existing=5                  200          6.8          4.2         46.0
apply_slot_for_window  existing=9                  200          5.2          4.6         29.4
clear_all_globally  slots=1 wins=1                  30         68.1         47.6        141.2
clear_all_globally  slots=1 wins=5                  30        185.7        135.5        383.8
clear_all_globally  slots=1 wins=10                 30        291.9        240.1        471.8
clear_all_globally  slots=5 wins=1                  30        118.2         78.0        213.5
clear_all_globally  slots=5 wins=5                  30        275.9        235.2        484.4
clear_all_globally  slots=5 wins=10                 30        521.2        447.2        803.3
clear_all_globally  slots=9 wins=1                  30        129.4         99.2        277.2
clear_all_globally  slots=9 wins=5                  30        391.4        341.3        670.1
clear_all_globally  slots=9 wins=10                 30        715.3        645.4       1013.5
set+clear cycle  wins=1                             50         26.7         13.5        209.3
set+clear cycle  wins=5                             50         38.9         36.0         59.6
set+clear cycle  wins=10                            50         75.2         67.2        122.5
jump.next  slots=1                                 100         22.6          9.2         63.2
jump.next  slots=5                                 100       5104.6       4995.6       5669.4
jump.next  slots=9                                 100      15219.2      15031.4      16538.9
apply_cword_for_window                             200          2.7          2.1         50.1
symbol: get_symbol (on identifier)                 200          8.5          4.4         83.8
symbol: get_symbol (on keyword)                    200         13.1          5.5         51.4
symbol: set+clear cycle (source=symbol)             50         23.7         17.1         83.2
symbol: set+clear cycle (source=cword)              50         15.6         13.1         45.9
---------------------------------------------------------------------------------------------

@mhiro2 mhiro2 merged commit 34edf18 into main Apr 26, 2026
4 checks passed
@mhiro2 mhiro2 deleted the fix/grep-fallback-and-symbol-parser branch April 26, 2026 10:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant