package main import ( "fmt" "os/exec" "strings" ) // tmuxCmd runs a tmux command and returns its stdout. func tmuxCmd(args ...string) (string, error) { out, err := exec.Command("tmux", args...).CombinedOutput() if err != nil { return "", fmt.Errorf("tmux %s: %v: %s", strings.Join(args, " "), err, strings.TrimSpace(string(out))) } return string(out), nil } func tmuxHasSession(name string) bool { err := exec.Command("tmux", "has-session", "-t", "="+name).Run() return err == nil } func tmuxListSessions() []string { out, err := tmuxCmd("list-sessions", "-F", "#{session_name}") if err != nil { return nil // no tmux server running = no sessions } var names []string for _, l := range strings.Split(strings.TrimSpace(out), "\n") { if l != "" { names = append(names, l) } } return names } func tmuxNewSession(name, cwd string, width, height int, cmdline string) error { args := []string{"new-session", "-d", "-s", name, "-x", fmt.Sprint(width), "-y", fmt.Sprint(height)} if cwd != "" { args = append(args, "-c", cwd) } if cmdline != "" { args = append(args, cmdline) } _, err := tmuxCmd(args...) return err } func tmuxKillSession(name string) error { _, err := tmuxCmd("kill-session", "-t", "="+name) return err } // tmuxCapture returns the visible pane content. ansi keeps escape // sequences (for terminal-faithful rendering in clients). func tmuxCapture(name string, ansi bool, history int) (string, error) { args := []string{"capture-pane", "-p", "-t", "=" + name + ":"} if ansi { args = append(args, "-e") } if history > 0 { args = append(args, "-S", fmt.Sprintf("-%d", history)) } return tmuxCmd(args...) } // tmuxSendKeys sends key names (Enter, Up, Down, BTab, C-c, ...). func tmuxSendKeys(name string, keys ...string) error { args := append([]string{"send-keys", "-t", "=" + name + ":"}, keys...) _, err := tmuxCmd(args...) return err } // tmuxPasteText inserts literal text (multi-line safe) via a paste // buffer, without submitting it. func tmuxPasteText(name, text string) error { cmd := exec.Command("tmux", "load-buffer", "-b", "helmd", "-") cmd.Stdin = strings.NewReader(text) if out, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("tmux load-buffer: %v: %s", err, strings.TrimSpace(string(out))) } _, err := tmuxCmd("paste-buffer", "-d", "-b", "helmd", "-t", "="+name+":") return err } func tmuxSessionAlive(name string) bool { out, err := tmuxCmd("list-panes", "-t", "="+name+":", "-F", "#{pane_dead}") if err != nil { return false } return strings.TrimSpace(out) == "0" }