Skip to content

Escape backslashes in fish completion descriptions#2378

Open
greymoth-jp wants to merge 1 commit into
urfave:mainfrom
greymoth-jp:fish-escape-backslash
Open

Escape backslashes in fish completion descriptions#2378
greymoth-jp wants to merge 1 commit into
urfave:mainfrom
greymoth-jp:fish-escape-backslash

Conversation

@greymoth-jp

Copy link
Copy Markdown

What type of PR is this?

bug

What this PR does / why we need it:

ToFishCompletion writes flag and command descriptions into fish -d '...' tokens and escapes them with escapeSingleQuotes. That helper only replaced ' with \' and left backslashes untouched.

Inside a fish single-quoted string the only escape sequences are \\ and \' (https://fishshell.com/docs/current/language.html). An unescaped backslash in a usage string is therefore mis-parsed:

  • A trailing backslash turns the closing quote into an escaped quote (\'), so the description is never terminated and the rest of the script is swallowed. A usage of C:\tmp\ was emitted as -d 'C:\tmp\'.
  • A doubled backslash such as a UNC path \\server collapsed down to a single one.

This escapes the backslash as \\ in addition to the existing single-quote handling.

  • fish.go: escapeSingleQuotes now doubles backslashes as well as escaping single quotes, using a strings.Replacer.
  • fish_test.go: adds TestFishCompletionBackslashEscaping, covering a flag and a subcommand whose usage contains backslashes.

Usage strings without backslashes are unaffected, so existing output (including testdata/expected-fish-full.fish) is unchanged.

Which issue(s) this PR fixes:

NONE

Testing

go test ./... passes. The new test fails before the change, where the descriptions are emitted with single, unescaped backslashes, and passes after it.

Release Notes

Fix fish completion so backslashes in flag and command usage descriptions are escaped correctly.

Inside a fish single-quoted string a literal backslash must be written as a
doubled backslash, just as a literal single quote is written as backslash plus
quote. escapeSingleQuotes only handled the quote, so a usage string containing
a backslash corrupted the generated -d '...' description, and a trailing
backslash left the single-quoted string unterminated.

See https://fishshell.com/docs/current/language.html
@greymoth-jp greymoth-jp requested a review from a team as a code owner June 30, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant