a tool
fish completion escape simulator
Paste a string as it appears in your fish completion source. See what fish unescapes it to at the completion call site, one pass at a time.
One unescape pass at source time. The bin name is consumed by fish at completion-registration time.
What fish sees
Walk through each pass of unescape_string.
What this tool simulates
Fish runs unescape_string on argument values at each call-site evaluation. A literal backslash in your source survives only if it can outlast every pass between source and use.
| Context | Passes | Why |
|---|---|---|
complete --command BIN | 1 | Argument unescaped once at source time. BIN is stored as plain string. |
complete --arguments "..." | 2 | Source-time unescape, then completion-engine re-evaluates the stored string at completion-call time. |
| raw source line | 1 | Same as any normal fish word: one pass at parse time. |
This is the asymmetry that bites completion-generator authors. shlex and similar single-pass quoters work for --command but lose a backslash level on --arguments.
Quoting and escape rules
Unquoted. A backslash escapes the next single character. \\b becomes b, \\n becomes a real newline, \\\\ becomes \\.
Single quotes. Almost everything literal. Only \\\\ (a literal backslash) and \\' (a literal single quote) are recognized escapes. 'C:\\path' stays exactly C:\\path.
Double quotes. \\\\, \\", and \\$ are escapes. Other backslashes pass through literally on modern fish, but legacy versions may differ.
Common escape sequences (unquoted, double-quoted)
| Source | Becomes |
|---|---|
\\a | bell |
\\b | backspace |
\\e | escape |
\\f | form feed |
\\n | newline |
\\r | carriage return |
\\t | tab |
\\v | vertical tab |
\\xHH | byte at hex value |
\\uXXXX | code point at hex value |
\\\\ | literal backslash |
Pitfall the simulator highlights
If your complete --arguments "..." string contains \\\\ (a literal backslash), pass one consumes it down to \\, and pass two consumes that down to nothing (or to whatever the next character escapes to). To survive two passes intact, a literal backslash needs \\\\\\\\ in source. That is four backslashes in your fish file for one backslash at the completion site.
The reverse failure mode: an unquoted literal path C:\\Users\\jane in --arguments source survives pass one (rewritten by some quoter) and gets mangled on pass two because pass two treats the remaining backslashes as escape leaders for U, j, etc.
References
- Fish documentation, Shell language: quotes and escape sequences.
- fish-shell issue #12712 on
--commandsource-time unescaping. - clap_complete PR #6368 on double-shlex for fish env completers.
The simulator approximates modern fish behavior. Versions differ. If a result looks wrong, check against your installed fish and file an issue on the source repo.