From 2f7d6e64d3fb065e79d2568d25ca018a053cebb6 Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 16 Aug 2024 22:46:03 +0200 Subject: [PATCH] allow custom tmux args, fix #79 (#125) --- config.go | 34 +++++++++++++++++++++++----- config_test.go | 9 ++++++++ main.go | 12 ++++++---- smug_test.go | 6 ++--- tmux.go | 60 +++++++++++++++++++++++++++++++++++++------------- 5 files changed, 93 insertions(+), 28 deletions(-) diff --git a/config.go b/config.go index 2f49014..cee1a10 100644 --- a/config.go +++ b/config.go @@ -2,10 +2,12 @@ package main import ( "fmt" - "io/ioutil" + "log" "os" "os/exec" + "os/user" "path" + "path/filepath" "strings" "gopkg.in/yaml.v2" @@ -36,8 +38,9 @@ type Window struct { } type Config struct { - SendKeysTimeout int `yaml:"sendkeys_timeout"` - Session string `yaml:"session"` + SendKeysTimeout int `yaml:"sendkeys_timeout"` + Session string `yaml:"session"` + TmuxOptions `yaml:"tmux_options"` Env map[string]string `yaml:"env"` Root string `yaml:"root"` BeforeStart []string `yaml:"before_start"` @@ -64,8 +67,26 @@ func EditConfig(path string) error { return cmd.Run() } -func GetConfig(path string, settings map[string]string) (*Config, error) { - f, err := ioutil.ReadFile(path) +func setTmuxOptions(tmuxOpts *TmuxOptions, c Config) { + tmuxOpts.SocketName = c.SocketName + tmuxOpts.SocketPath = c.SocketPath + + if c.ConfigFile != "" { + usr, err := user.Current() + if err != nil { + log.Fatalf("cannot expand user home dir: %s", err) + } + path := c.ConfigFile + if strings.HasPrefix(path,"~") { + path = filepath.Join(usr.HomeDir, path[1:]) + } + + tmuxOpts.ConfigFile = path + } +} + +func GetConfig(path string, settings map[string]string, tmuxOpts *TmuxOptions) (*Config, error) { + f, err := os.ReadFile(path) if err != nil { return nil, err } @@ -78,6 +99,7 @@ func GetConfig(path string, settings map[string]string) (*Config, error) { } addDefaultEnvs(&c, path) + setTmuxOptions(tmuxOpts, c) return &c, err @@ -110,7 +132,7 @@ func ParseConfig(data string, settings map[string]string) (Config, error) { func ListConfigs(dir string) ([]string, error) { var result []string - files, err := ioutil.ReadDir(dir) + files, err := os.ReadDir(dir) if err != nil { return result, err diff --git a/config_test.go b/config_test.go index 956e639..3083dd9 100644 --- a/config_test.go +++ b/config_test.go @@ -10,6 +10,10 @@ func TestParseConfig(t *testing.T) { yaml := ` session: ${session} sendkeys_timeout: 200 +tmux_options: + socket_name: foo + socket_path: /path/to/socket + config_file: /path/to/tmux_config windows: - layout: tiled commands: @@ -31,6 +35,11 @@ windows: Session: "test", SendKeysTimeout: 200, Env: make(map[string]string), + TmuxOptions: TmuxOptions{ + SocketName: "foo", + SocketPath: "/path/to/socket", + ConfigFile: "/path/to/tmux_config", + }, Windows: []Window{ { Layout: "tiled", diff --git a/main.go b/main.go index 9f44e65..3944e7e 100644 --- a/main.go +++ b/main.go @@ -84,7 +84,7 @@ func main() { } commander := DefaultCommander{logger} - tmux := Tmux{commander} + tmux := Tmux{commander, &TmuxOptions{}} smug := Smug{tmux, commander} context := CreateContext() @@ -93,10 +93,13 @@ func main() { configPath = options.Config } else if options.Project != "" { config, err := FindConfig(userConfigDir, options.Project) - if err != nil { + if err != nil && options.Command != CommandNew { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) } + if options.Command == CommandNew { + config = fmt.Sprintf("%s.yml", options.Project) + } configPath = filepath.Join(userConfigDir, config) } else { path, err := os.Getwd() @@ -114,7 +117,8 @@ func main() { } else { fmt.Println("Starting new windows...") } - config, err := GetConfig(configPath, options.Settings) + + config, err := GetConfig(configPath, options.Settings, smug.tmux.TmuxOptions) if err != nil { fmt.Fprint(os.Stderr, err.Error()) os.Exit(1) @@ -132,7 +136,7 @@ func main() { } else { fmt.Println("Killing windows...") } - config, err := GetConfig(configPath, options.Settings) + config, err := GetConfig(configPath, options.Settings, smug.tmux.TmuxOptions) if err != nil { fmt.Fprint(os.Stderr, err.Error()) os.Exit(1) diff --git a/smug_test.go b/smug_test.go index 7fc00c6..6e753af 100644 --- a/smug_test.go +++ b/smug_test.go @@ -292,7 +292,7 @@ func TestStartStopSession(t *testing.T) { t.Run("start session: "+testDescription, func(t *testing.T) { commander := &MockCommander{[]string{}, params.commanderOutputs} - tmux := Tmux{commander} + tmux := Tmux{commander, &TmuxOptions{}} smug := Smug{tmux, commander} err := smug.Start(params.config, params.options, params.context) @@ -307,7 +307,7 @@ func TestStartStopSession(t *testing.T) { t.Run("stop session: "+testDescription, func(t *testing.T) { commander := &MockCommander{[]string{}, params.commanderOutputs} - tmux := Tmux{commander} + tmux := Tmux{commander, &TmuxOptions{}} smug := Smug{tmux, commander} err := smug.Stop(params.config, params.options, params.context) @@ -346,7 +346,7 @@ func TestPrintCurrentSession(t *testing.T) { "id1;win1;layout;root", "root\n/tmp", }} - tmux := Tmux{commander} + tmux := Tmux{commander, &TmuxOptions{}} smug := Smug{tmux, commander} diff --git a/tmux.go b/tmux.go index 82b48e3..bb7b7e0 100644 --- a/tmux.go +++ b/tmux.go @@ -16,8 +16,21 @@ const ( Tiled = "tiled" ) +type TmuxOptions struct { + + // Default socket name + SocketName string `yaml:"socket_name"` + + // Default socket path, overrides SocketName + SocketPath string `yaml:"socket_path"` + + // tmux config file + ConfigFile string `yaml:"config_file"` +} + type Tmux struct { commander Commander + *TmuxOptions } type TmuxWindow struct { @@ -31,36 +44,53 @@ type TmuxPane struct { Root string } +func (tmux Tmux) cmd(args ...string) *exec.Cmd { + tmuxCmd := []string{"tmux"} + if tmux.SocketPath != "" { + tmuxCmd = append(tmuxCmd, "-S", tmux.SocketPath) + } else if tmux.SocketName != "" { + tmuxCmd = append(tmuxCmd, "-L", tmux.SocketName) + } + + if tmux.ConfigFile != "" { + tmuxCmd = append(tmuxCmd, "-f", tmux.ConfigFile) + } + + tmuxCmd = append(tmuxCmd, args...) + + return exec.Command(tmuxCmd[0], tmuxCmd[1:]...) +} + func (tmux Tmux) NewSession(name string, root string, windowName string) (string, error) { - cmd := exec.Command("tmux", "new", "-Pd", "-s", name, "-n", windowName, "-c", root) + cmd := tmux.cmd("new", "-Pd", "-s", name, "-n", windowName, "-c", root) return tmux.commander.Exec(cmd) } func (tmux Tmux) SessionExists(name string) bool { - cmd := exec.Command("tmux", "has-session", "-t", name) + cmd := tmux.cmd("has-session", "-t", name) res, err := tmux.commander.Exec(cmd) return res == "" && err == nil } func (tmux Tmux) KillWindow(target string) error { - cmd := exec.Command("tmux", "kill-window", "-t", target) + cmd := tmux.cmd("kill-window", "-t", target) _, err := tmux.commander.Exec(cmd) return err } func (tmux Tmux) NewWindow(target string, name string, root string) (string, error) { - cmd := exec.Command("tmux", "neww", "-Pd", "-t", target, "-c", root, "-F", "#{window_id}", "-n", name) + cmd := tmux.cmd("neww", "-Pd", "-t", target, "-c", root, "-F", "#{window_id}", "-n", name) return tmux.commander.Exec(cmd) } func (tmux Tmux) SendKeys(target string, command string) error { - cmd := exec.Command("tmux", "send-keys", "-t", target, command, "Enter") + cmd := tmux.cmd("send-keys", "-t", target, command, "Enter") return tmux.commander.ExecSilently(cmd) } func (tmux Tmux) Attach(target string, stdin *os.File, stdout *os.File, stderr *os.File) error { - cmd := exec.Command("tmux", "attach", "-d", "-t", target) + cmd := tmux.cmd("attach", "-d", "-t", target) cmd.Stdin = stdin cmd.Stdout = stdout @@ -70,7 +100,7 @@ func (tmux Tmux) Attach(target string, stdin *os.File, stdout *os.File, stderr * } func (tmux Tmux) RenumberWindows(target string) error { - cmd := exec.Command("tmux", "move-window", "-r", "-s", target, "-t", target) + cmd := tmux.cmd("move-window", "-r", "-s", target, "-t", target) _, err := tmux.commander.Exec(cmd) return err } @@ -87,7 +117,7 @@ func (tmux Tmux) SplitWindow(target string, splitType string, root string) (stri args = append(args, []string{"-t", target, "-c", root, "-F", "#{pane_id}"}...) - cmd := exec.Command("tmux", args...) + cmd := tmux.cmd(args...) pane, err := tmux.commander.Exec(cmd) if err != nil { @@ -98,28 +128,28 @@ func (tmux Tmux) SplitWindow(target string, splitType string, root string) (stri } func (tmux Tmux) SelectLayout(target string, layoutType string) (string, error) { - cmd := exec.Command("tmux", "select-layout", "-t", target, layoutType) + cmd := tmux.cmd("select-layout", "-t", target, layoutType) return tmux.commander.Exec(cmd) } func (tmux Tmux) SetEnv(target string, key string, value string) (string, error) { - cmd := exec.Command("tmux", "setenv", "-t", target, key, value) + cmd := tmux.cmd("setenv", "-t", target, key, value) return tmux.commander.Exec(cmd) } func (tmux Tmux) StopSession(target string) (string, error) { - cmd := exec.Command("tmux", "kill-session", "-t", target) + cmd := tmux.cmd("kill-session", "-t", target) return tmux.commander.Exec(cmd) } func (tmux Tmux) SwitchClient(target string) error { - cmd := exec.Command("tmux", "switch-client", "-t", target) + cmd := tmux.cmd("switch-client", "-t", target) return tmux.commander.ExecSilently(cmd) } func (tmux Tmux) SessionName() (string, error) { - cmd := exec.Command("tmux", "display-message", "-p", "#S") + cmd := tmux.cmd("display-message", "-p", "#S") sessionName, err := tmux.commander.Exec(cmd) if err != nil { @@ -132,7 +162,7 @@ func (tmux Tmux) SessionName() (string, error) { func (tmux Tmux) ListWindows(target string) ([]TmuxWindow, error) { var windows []TmuxWindow - cmd := exec.Command("tmux", "list-windows", "-F", "#{window_id};#{window_name};#{window_layout};#{pane_current_path}", "-t", target) + cmd := tmux.cmd("list-windows", "-F", "#{window_id};#{window_name};#{window_layout};#{pane_current_path}", "-t", target) out, err := tmux.commander.Exec(cmd) if err != nil { return windows, err @@ -158,7 +188,7 @@ func (tmux Tmux) ListWindows(target string) ([]TmuxWindow, error) { func (tmux Tmux) ListPanes(target string) ([]TmuxPane, error) { var panes []TmuxPane - cmd := exec.Command("tmux", "list-panes", "-F", "#{pane_current_path}", "-t", target) + cmd := tmux.cmd("list-panes", "-F", "#{pane_current_path}", "-t", target) out, err := tmux.commander.Exec(cmd) if err != nil {