From 8d84e2e222963f3f306ab5b16c2ed13547d7e1d6 Mon Sep 17 00:00:00 2001 From: Chmouel Boudjnah Date: Thu, 4 Jul 2019 16:16:22 +0200 Subject: [PATCH 1/2] Make sure we quote brackets when generating zsh completion Signed-off-by: Chmouel Boudjnah --- zsh_completions.go | 4 +++- zsh_completions_test.go | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/zsh_completions.go b/zsh_completions.go index 12755482f..b58a5d68f 100644 --- a/zsh_completions.go +++ b/zsh_completions.go @@ -332,5 +332,7 @@ func zshCompFlagCouldBeSpecifiedMoreThenOnce(f *pflag.Flag) bool { } func zshCompQuoteFlagDescription(s string) string { - return strings.Replace(s, "'", `'\''`, -1) + return strings.NewReplacer("'", `'\''`, + "[", `\[`, + "]", `\]`).Replace(s) } diff --git a/zsh_completions_test.go b/zsh_completions_test.go index e53fa886e..8079f6cf7 100644 --- a/zsh_completions_test.go +++ b/zsh_completions_test.go @@ -157,6 +157,17 @@ func TestGenZshCompletion(t *testing.T) { `--private\[Don'\\''t show public info]`, }, }, + { + name: "flag description with brackets ([]) shouldn't break the completion file", + root: func() *Command { + r := genTestCommand("root", true) + r.Flags().Bool("level", false, "[ALERT]") + return r + }(), + expectedExpressions: []string{ + `--level[\[ALERT\]]`, + }, + }, { name: "argument completion for file with and without patterns", root: func() *Command { From ee8ca02120838f0b59a4facad0efd1ebe7ea3111 Mon Sep 17 00:00:00 2001 From: Chmouel Boudjnah Date: Tue, 12 Nov 2019 14:32:04 +0100 Subject: [PATCH 2/2] Properly escape help text Closes #989 Authored-by: Cornelius Weig Signed-off-by: Chmouel Boudjnah --- zsh_completions.go | 7 +++++-- zsh_completions_test.go | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/zsh_completions.go b/zsh_completions.go index b58a5d68f..e2476b62f 100644 --- a/zsh_completions.go +++ b/zsh_completions.go @@ -25,6 +25,7 @@ var ( "extractFlags": zshCompExtractFlag, "genFlagEntryForZshArguments": zshCompGenFlagEntryForArguments, "extractArgsCompletions": zshCompExtractArgumentCompletionHintsForRendering, + "escapeText": zshCompQuoteFlagDescription, } zshCompletionText = ` {{/* should accept Command (that contains subcommands) as parameter */}} @@ -41,7 +42,7 @@ function {{$cmdPath}} { case $state in cmnds) commands=({{range .Commands}}{{if not .Hidden}} - "{{.Name}}:{{.Short}}"{{end}}{{end}} + "{{.Name}}:{{.Short | escapeText}}"{{end}}{{end}} ) _describe "command" commands ;; @@ -334,5 +335,7 @@ func zshCompFlagCouldBeSpecifiedMoreThenOnce(f *pflag.Flag) bool { func zshCompQuoteFlagDescription(s string) string { return strings.NewReplacer("'", `'\''`, "[", `\[`, - "]", `\]`).Replace(s) + "]", `\]`, + "$(", `\$(`, + ).Replace(s) } diff --git a/zsh_completions_test.go b/zsh_completions_test.go index 8079f6cf7..a9405fe10 100644 --- a/zsh_completions_test.go +++ b/zsh_completions_test.go @@ -240,6 +240,25 @@ func TestGenZshCompletion(t *testing.T) { `--ptest\[ptest]:filename:_files -g "-\(/\)"`, }, }, + { + name: "escape text in subcommand description", + root: func() *Command { + r := &Command{ + Use: "rootcmd", + Long: "Long rootcmd description", + } + d := &Command{ + Use: "subcmd1", + Short: "$(echo foo)", + Run: emptyRun, + } + r.AddCommand(d) + return r + }(), + expectedExpressions: []string{ + `\$\(echo foo\)`, + }, + }, } for _, tc := range tcs {