Binding the raw @@ chord made a lone @ an ambiguous prefix. With fish_sequence_key_delay_ms unset (as it always was), fish held every typed @ indefinitely waiting to see if a second @ was coming, before it would even render — breaking ssh user@host and similar. Confirmed via git log -S "fish_sequence_key_delay_ms" that this was present since the @@ binding was first added, not a later regression.
Fixes it at the root by binding the single @ key (never ambiguous — no lookahead buffering) and having the bound function look behind at the current token instead: plain @ always self-inserts instantly, and a second consecutive bare @ triggers the fzf picker in place, replacing the token with the selection. No forced delimiter, so you can keep typing (e.g. /subdir) immediately after a pick.
@@ still only triggers as its own token — cat @@ triggers it, cat@@ does not — same isolation guarantee as before.
Vi's normal/visual modes are explicitly left unbound for @, matching their existing (no-op) behavior; only Emacs and Vi-insert get the binding. Verified this doesn't leak via fish's shared default bind_mode namespace between Emacs and Vi-normal.
Updated docs/manual/03-key-bindings.md (the docs SSOT) to describe the new behavior.
Test plan
exec fish (or open a new terminal) to reload
Type a lone @ (e.g. ssh root@ ) and confirm it appears with no perceptible delay
Type @@ and confirm the fzf picker opens instantly
Pick an item and confirm it replaces @@ with no leftover artifacts, then keep typing (e.g. /subdir) and confirm it appends normally
Cancel the picker (Esc) and confirm @@ is left as literal text
If using Vi key bindings: confirm @ still does nothing in normal/visual mode, and only triggers the picker in insert mode
## Summary
- Binding the raw `@@` chord made a lone `@` an ambiguous prefix. With `fish_sequence_key_delay_ms` unset (as it always was), fish held every typed `@` indefinitely waiting to see if a second `@` was coming, before it would even render — breaking `ssh user@host` and similar. Confirmed via `git log -S "fish_sequence_key_delay_ms"` that this was present since the `@@` binding was first added, not a later regression.
- Fixes it at the root by binding the single `@` key (never ambiguous — no lookahead buffering) and having the bound function look *behind* at the current token instead: plain `@` always self-inserts instantly, and a second consecutive bare `@` triggers the fzf picker in place, replacing the token with the selection. No forced delimiter, so you can keep typing (e.g. `/subdir`) immediately after a pick.
- `@@` still only triggers as its own token — `cat @@` triggers it, `cat@@` does not — same isolation guarantee as before.
- Vi's normal/visual modes are explicitly left unbound for `@`, matching their existing (no-op) behavior; only Emacs and Vi-insert get the binding. Verified this doesn't leak via fish's shared `default` bind_mode namespace between Emacs and Vi-normal.
- Updated `docs/manual/03-key-bindings.md` (the docs SSOT) to describe the new behavior.
## Test plan
- [x] `exec fish` (or open a new terminal) to reload
- [x] Type a lone `@` (e.g. `ssh root@` ) and confirm it appears with no perceptible delay
- [x] Type `@@` and confirm the fzf picker opens instantly
- [x] Pick an item and confirm it replaces `@@` with no leftover artifacts, then keep typing (e.g. `/subdir`) and confirm it appends normally
- [x] Cancel the picker (Esc) and confirm `@@` is left as literal text
- [x] If using Vi key bindings: confirm `@` still does nothing in normal/visual mode, and only triggers the picker in insert mode
Binding the raw @@ chord made a lone @ an ambiguous prefix, so fish
(with fish_sequence_key_delay_ms unset) held every typed @ indefinitely
until a disambiguating keystroke arrived, breaking things like
`ssh user@host`. Binding the single @ key instead and checking whether
the current token is already a bare @ removes the ambiguity entirely:
plain @ always self-inserts instantly, and a second consecutive @
triggers the picker in place, with no forced delimiter before you can
keep typing. Vi's normal/visual modes are left unbound, matching their
existing (no-op) @ behavior.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
@@chord made a lone@an ambiguous prefix. Withfish_sequence_key_delay_msunset (as it always was), fish held every typed@indefinitely waiting to see if a second@was coming, before it would even render — breakingssh user@hostand similar. Confirmed viagit log -S "fish_sequence_key_delay_ms"that this was present since the@@binding was first added, not a later regression.@key (never ambiguous — no lookahead buffering) and having the bound function look behind at the current token instead: plain@always self-inserts instantly, and a second consecutive bare@triggers the fzf picker in place, replacing the token with the selection. No forced delimiter, so you can keep typing (e.g./subdir) immediately after a pick.@@still only triggers as its own token —cat @@triggers it,cat@@does not — same isolation guarantee as before.@, matching their existing (no-op) behavior; only Emacs and Vi-insert get the binding. Verified this doesn't leak via fish's shareddefaultbind_mode namespace between Emacs and Vi-normal.docs/manual/03-key-bindings.md(the docs SSOT) to describe the new behavior.Test plan
exec fish(or open a new terminal) to reload@(e.g.ssh root@) and confirm it appears with no perceptible delay@@and confirm the fzf picker opens instantly@@with no leftover artifacts, then keep typing (e.g./subdir) and confirm it appends normally@@is left as literal text@still does nothing in normal/visual mode, and only triggers the picker in insert mode