260729.3 · 57631684d8dcb7bbf2ec9656f26ed1a8c5bcc021
Escape trailing semicolon in tmux command argument
tmux ends a command at an argument whose last character is ';', so a --border-label ending in one was stored truncated. escapeTmuxSeparator only covered a value that was exactly ';'.
fzf --popup --border-label 'foo;' -> @fzf-border-label was 'foo'
reading declarations
@@ -46,11 +46,11 @@ func tmuxFloatingPaneInfo() (int, int, bool) { return width, height, true } -// A lone ';' argument is a command separator to tmux, aborting the whole-// command at parse time+// tmux ends a command at an argument ending in ';', so a trailing one is+// escaped. Elsewhere it is not special func escapeTmuxSeparator(str string) string {- if str == ";" {- return `\;`+ if strings.HasSuffix(str, ";") {+ return str[:len(str)-1] + `\;` } return str }
@@ -18,6 +18,7 @@ func TestEscapeTmuxFormat(t *testing.T) { {" C# notes #S ", " C## notes ##S "}, {";", `\;`}, {"; rm", "; rm"},+ {"C#;", `C##\;`}, } { if actual := escapeTmuxFormat(tc.given); actual != tc.expected { t.Errorf("expected %q, got %q", tc.expected, actual)@@ -35,10 +36,15 @@ func TestEscapeTmuxSeparator(t *testing.T) { {"#", "#"}, {"#{pane_id}", "#{pane_id}"}, {"100%", "100%"},+ // tmux drops a trailing ';' and everything after it, so only that+ // one is escaped {";", `\;`},+ {"abc;", `abc\;`},+ {";;", `;\;`},+ {`foo\;`, `foo\\;`}, {"; rm", "; rm"}, {" ; ", " ; "},- {";;", ";;"},+ {"a;b", "a;b"}, } { if actual := escapeTmuxSeparator(tc.given); actual != tc.expected { t.Errorf("expected %q, got %q", tc.expected, actual)