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'
This commit is contained in:
Junegunn Choi
2026-07-29 20:59:53 +09:00
parent 50e6c026ec
commit 57631684d8
2 changed files with 11 additions and 5 deletions
+4 -4
View File
@@ -46,11 +46,11 @@ func tmuxFloatingPaneInfo() (int, int, bool) {
return width, height, true return width, height, true
} }
// A lone ';' argument is a command separator to tmux, aborting the whole // tmux ends a command at an argument ending in ';', so a trailing one is
// command at parse time // escaped. Elsewhere it is not special
func escapeTmuxSeparator(str string) string { func escapeTmuxSeparator(str string) string {
if str == ";" { if strings.HasSuffix(str, ";") {
return `\;` return str[:len(str)-1] + `\;`
} }
return str return str
} }
+7 -1
View File
@@ -18,6 +18,7 @@ func TestEscapeTmuxFormat(t *testing.T) {
{" C# notes #S ", " C## notes ##S "}, {" C# notes #S ", " C## notes ##S "},
{";", `\;`}, {";", `\;`},
{"; rm", "; rm"}, {"; rm", "; rm"},
{"C#;", `C##\;`},
} { } {
if actual := escapeTmuxFormat(tc.given); actual != tc.expected { if actual := escapeTmuxFormat(tc.given); actual != tc.expected {
t.Errorf("expected %q, got %q", tc.expected, actual) t.Errorf("expected %q, got %q", tc.expected, actual)
@@ -35,10 +36,15 @@ func TestEscapeTmuxSeparator(t *testing.T) {
{"#", "#"}, {"#", "#"},
{"#{pane_id}", "#{pane_id}"}, {"#{pane_id}", "#{pane_id}"},
{"100%", "100%"}, {"100%", "100%"},
// tmux drops a trailing ';' and everything after it, so only that
// one is escaped
{";", `\;`}, {";", `\;`},
{"abc;", `abc\;`},
{";;", `;\;`},
{`foo\;`, `foo\\;`},
{"; rm", "; rm"}, {"; rm", "; rm"},
{" ; ", " ; "}, {" ; ", " ; "},
{";;", ";;"}, {"a;b", "a;b"},
} { } {
if actual := escapeTmuxSeparator(tc.given); actual != tc.expected { if actual := escapeTmuxSeparator(tc.given); actual != tc.expected {
t.Errorf("expected %q, got %q", tc.expected, actual) t.Errorf("expected %q, got %q", tc.expected, actual)