fix(shell): parse fish aliases and abbreviations - #154
Merged
versenilvis merged 5 commits intoAug 30, 2026
Conversation
Alias scanning hardcoded the POSIX grammar, so a shell with different block and assignment syntax could not reuse the source-following and cache-stamping logic around it.
ScanPosixAliases read config.fish with bash/zsh rules, so fish returned almost nothing: `alias name value` has no equals sign to split on, and `end` never closed a block that `fi` was counting. It also read only config.fish, missing conf.d/, autoloaded functions/, and the files a config reaches through `set`/`for` rather than a literal path. abbr was not read at all.
Abbreviations are how fish users shorten a command, and unlike an alias one expands in place, so listing the name next to what the shell will put on the line matches what happens next. They carry their own source and icon rather than passing as aliases.
versenilvis
approved these changes
Aug 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #153
FishAdapter.ScanAliasessentconfig.fishthroughScanPosixAliases, which reads bash/zsh syntax, so on a normal fish config you get almost nothing back and what you do get can be wrong.abbrwasn't read at allThe four problems from the issue, plus one that only showed up against a real config:
alias name valuehas no=to split on so those lines were dropped, and when the value carried its own=the line survived but split in the wrong place. Both forms parse now, with-s/--saveand--handled (1dd9d53)if/else/fi. fish closes everything withend, and that includesfor/while/switch/begin/function, so counting onlyiflets an innerendpop the enclosing one and the fallback arm starts overwriting the preferred one. It's a stack now, first arm still wins,switch/caseincluded (1dd9d53)config.fishwas read. Nowfunctions/*.fish,conf.d/*.fishandconfig.fish, in that precedence order, since an autoloaded function only loads while its name is still undefined.$__fish_config_diris resolved once per process, same trick asZDOTDIR(1dd9d53)abbrparses in the forms people write:-a/--add, implicit add,--,--position,--set-cursor,-g.--regexand--functionare skipped since neither the name nor the expansion is in the text, and a name the shell computes gets dropped instead of recorded as a literal. They reach the menu with their own source and icon, which fits the split from Add semantic, configurable icons for suggestion types #60 (6cec6ff)sourceneededsetandforresolved too. My own config names its parts in a list and sources them from a loop, so without that the parser never reaches a single alias file (1dd9d53)The walker was split out first (d8fa4a1) so the posix path and the fish one share the source following and cache stamping instead of duplicating both
Note
aliases and abbrs come out of one walk and share one cache entry. Two scans with different entry points would evict each other and re-read the whole tree on every keystroke
abbrs aren't wired into
core.expand-alias: fish expands them itself on space, and a--set-cursorabbr would get its marker typed literallyintegration/shell/fish_test.gocovers the alias and abbr forms, arm preference with nested blocks, statement separators,alias --savefunction files, the autoloaded dirs, loop-sourced files, and cache invalidation when a file lands inconf.d/. Against my real config it finds 27/27 aliases and 39/39 plain abbrs; the other 50 are the--command-scoped ones built by that loop with(string split ...)names, which no static parser can resolve.just test,just lintandgo vet ./...are clean