Skip to content

fix(runtime): Harden cword updates, pin identity matching, and grep fallback behavior#27

Merged
mhiro2 merged 4 commits intomainfrom
fix/cword-pin-identity-grep-flash
Mar 18, 2026
Merged

fix(runtime): Harden cword updates, pin identity matching, and grep fallback behavior#27
mhiro2 merged 4 commits intomainfrom
fix/cword-pin-identity-grep-flash

Conversation

@mhiro2
Copy link
Copy Markdown
Owner

@mhiro2 mhiro2 commented Mar 18, 2026

Summary

  • make cword debounce updates independent per window so split navigation does not drop pending highlights
  • tighten pin identity matching so auto toggle and unpin only act on exact matches and avoid ambiguous
    removals
  • prefer rg --vimgrep for quickfix fallback grep, with vimgrep kept as the fallback path when ripgrep is
    unavailable
  • allow flash.timeout_ms = 0, align empty-state picker notices, and update the related tests and docs

Changes

  • 0817bae : fix(cword): use per-window debounce timers
    • Replaced the shared cword debounce timer with window-local timers so cursor movement in one split no
      longer cancels pending updates in another.
    • Added regression coverage for concurrent cword updates across multiple windows.
  • f412256 : fix(state): tighten pin identity matching
    • Changed auto-toggle matching to require an exact raw-and-pattern match so pins with different match
      semantics can coexist.
    • Updated UnpinWord to prefer exact matches and warn instead of deleting an arbitrary slot when the
      current word maps to multiple pins.
    • Added state, command, and auto-allocation tests for the stricter identity rules.
  • 1e83005 : fix(grep): prefer rg for quickfix fallback
    • Switched quickfix fallback grep to use rg --vimgrep when available to avoid the broad vimgrep **/*
      scan in large or mixed repositories.
    • Kept the legacy vimgrep path as a fallback for environments without ripgrep and covered both branches
      with tests.
  • df85644 : fix(ui): allow zero flash timeout and align empty notices
    • Allowed flash.timeout_ms = 0 so flash highlights can clear on the next event loop tick without failing
      config validation.
    • Standardized empty-state picker notifications to INFO level for a more consistent user-facing experience.
    • Updated help and README text to reflect the revised flash and grep fallback behavior.

@mhiro2 mhiro2 self-assigned this Mar 18, 2026
@mhiro2 mhiro2 added the bug Something isn't working label Mar 18, 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          3.2          0.7         25.2
reapply_all  slots=1 wins=5                         50          6.2          3.3         21.2
reapply_all  slots=1 wins=10                        50         12.5          5.9         47.2
reapply_all  slots=1 wins=20                        50         13.6         11.6         28.6
reapply_all  slots=5 wins=1                         50          1.3          0.7          7.9
reapply_all  slots=5 wins=5                         50          6.2          3.9         14.4
reapply_all  slots=5 wins=10                        50          9.0          7.0         39.5
reapply_all  slots=5 wins=20                        50         16.3         13.7         35.5
reapply_all  slots=9 wins=1                         50          2.8          0.8         10.0
reapply_all  slots=9 wins=5                         50          3.9          3.8          4.2
reapply_all  slots=9 wins=10                        50          8.0          7.7          8.5
reapply_all  slots=9 wins=20                        50         22.9         15.6         78.1
---------------------------------------------------------------------------------------------

== bench.bench_apply ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
apply_slot_globally  wins=1                        100          5.1          3.9         25.5
apply_slot_globally  wins=5                        100         21.2         18.9         42.6
apply_slot_globally  wins=10                       100         42.5         37.1         95.6
apply_slot_globally  wins=20                       100         88.5         76.6        167.6
apply_slot_for_window  existing=0                  200          4.0          3.7         24.5
apply_slot_for_window  existing=5                  200          4.4          4.1         26.8
apply_slot_for_window  existing=9                  200          5.0          4.7         29.8
---------------------------------------------------------------------------------------------

== bench.bench_clear ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
clear_all_globally  slots=1 wins=1                  30         93.3         56.3        168.2
clear_all_globally  slots=1 wins=5                  30        197.6        157.7        354.5
clear_all_globally  slots=1 wins=10                 30        303.3        261.1        536.7
clear_all_globally  slots=5 wins=1                  30         99.6         81.6        188.6
clear_all_globally  slots=5 wins=5                  30        297.4        259.5        503.6
clear_all_globally  slots=5 wins=10                 30        521.3        458.2        800.9
clear_all_globally  slots=9 wins=1                  30        134.5        109.3        251.2
clear_all_globally  slots=9 wins=5                  30        428.0        363.4        633.8
clear_all_globally  slots=9 wins=10                 30        739.1        660.8       1048.2
---------------------------------------------------------------------------------------------

== bench.bench_set_clear ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
set+clear cycle  wins=1                             50         28.2         13.7        101.6
set+clear cycle  wins=5                             50         50.5         36.9         93.6
set+clear cycle  wins=10                            50        119.6         66.7        204.9
---------------------------------------------------------------------------------------------

== bench.bench_jump ==---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
jump.next  slots=1                                 100         43.1         19.6        131.9
jump.next  slots=5                                 100       5403.8       5243.5       9938.6
jump.next  slots=9                                 100      15996.3      15664.9      23274.3
---------------------------------------------------------------------------------------------

== bench.bench_cword ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
apply_cword_for_window                             200          2.6          2.0         35.3
---------------------------------------------------------------------------------------------

== bench.bench_symbol ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
symbol: get_symbol (on identifier)                 200          9.2          4.1         67.5
symbol: get_symbol (on keyword)                    200         14.4          5.5         80.8
symbol: set+clear cycle (source=symbol)             50         27.3         20.5        144.5
symbol: set+clear cycle (source=cword)              50         16.0         13.1         35.2
---------------------------------------------------------------------------------------------

== SUMMARY ==
---------------------------------------------------------------------------------------------
Benchmark                                        Iters    Mean (us)     Min (us)     Max (us)
---------------------------------------------------------------------------------------------
reapply_all  slots=1 wins=1                         50          3.2          0.7         25.2
reapply_all  slots=1 wins=5                         50          6.2          3.3         21.2
reapply_all  slots=1 wins=10                        50         12.5          5.9         47.2
reapply_all  slots=1 wins=20                        50         13.6         11.6         28.6
reapply_all  slots=5 wins=1                         50          1.3          0.7          7.9
reapply_all  slots=5 wins=5                         50          6.2          3.9         14.4
reapply_all  slots=5 wins=10                        50          9.0          7.0         39.5
reapply_all  slots=5 wins=20                        50         16.3         13.7         35.5
reapply_all  slots=9 wins=1                         50          2.8          0.8         10.0
reapply_all  slots=9 wins=5                         50          3.9          3.8          4.2
reapply_all  slots=9 wins=10                        50          8.0          7.7          8.5
reapply_all  slots=9 wins=20                        50         22.9         15.6         78.1
apply_slot_globally  wins=1                        100          5.1          3.9         25.5
apply_slot_globally  wins=5                        100         21.2         18.9         42.6
apply_slot_globally  wins=10                       100         42.5         37.1         95.6
apply_slot_globally  wins=20                       100         88.5         76.6        167.6
apply_slot_for_window  existing=0                  200          4.0          3.7         24.5
apply_slot_for_window  existing=5                  200          4.4          4.1         26.8
apply_slot_for_window  existing=9                  200          5.0          4.7         29.8
clear_all_globally  slots=1 wins=1                  30         93.3         56.3        168.2
clear_all_globally  slots=1 wins=5                  30        197.6        157.7        354.5
clear_all_globally  slots=1 wins=10                 30        303.3        261.1        536.7
clear_all_globally  slots=5 wins=1                  30         99.6         81.6        188.6
clear_all_globally  slots=5 wins=5                  30        297.4        259.5        503.6
clear_all_globally  slots=5 wins=10                 30        521.3        458.2        800.9
clear_all_globally  slots=9 wins=1                  30        134.5        109.3        251.2
clear_all_globally  slots=9 wins=5                  30        428.0        363.4        633.8
clear_all_globally  slots=9 wins=10                 30        739.1        660.8       1048.2
set+clear cycle  wins=1                             50         28.2         13.7        101.6
set+clear cycle  wins=5                             50         50.5         36.9         93.6
set+clear cycle  wins=10                            50        119.6         66.7        204.9
jump.next  slots=1                                 100         43.1         19.6        131.9
jump.next  slots=5                                 100       5403.8       5243.5       9938.6
jump.next  slots=9                                 100      15996.3      15664.9      23274.3
apply_cword_for_window                             200          2.6          2.0         35.3
symbol: get_symbol (on identifier)                 200          9.2          4.1         67.5
symbol: get_symbol (on keyword)                    200         14.4          5.5         80.8
symbol: set+clear cycle (source=symbol)             50         27.3         20.5        144.5
symbol: set+clear cycle (source=cword)              50         16.0         13.1         35.2
---------------------------------------------------------------------------------------------

@mhiro2 mhiro2 merged commit f347de5 into main Mar 18, 2026
4 checks passed
@mhiro2 mhiro2 deleted the fix/cword-pin-identity-grep-flash branch March 18, 2026 21:57
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