Files
go-tmux/tmux.go

82 lines
1.6 KiB
Go

package tmux
import (
"bufio"
"bytes"
"regexp"
)
var optMatcher = regexp.MustCompile(`^\s*([@\w-][\w-]+)\s+(.*)$`)
var quote = []byte(`"`)
// Tmux enables easily running tmux commands.
type Tmux struct {
BinPath string
SocketName string
SocketPath string
Runner Runner
}
// New returns a Tmux objects with a Runner capable of executing shell commands.
func New() *Tmux {
return &Tmux{Runner: &ExecRunner{}}
}
// Exec runs the given tmux command.
func (s *Tmux) Exec(args ...string) ([]byte, error) {
args = append(s.Args(), args...)
return s.Runner.Run(s.Binary(), args...)
}
func (s *Tmux) Binary() string {
if s.BinPath != "" {
return s.BinPath
} else {
return "tmux"
}
}
func (s *Tmux) Args() []string {
args := []string{}
if s.SocketPath != "" {
args = append(args, "-S", s.SocketPath)
} else if s.SocketName != "" {
args = append(args, "-L", s.SocketName)
}
return args
}
func (s *Tmux) GetOptions(scope OptionsScope) (map[string]string, error) {
out, err := s.Exec("show-options", OptionsScopeFlags(scope))
if err != nil {
return nil, err
}
return s.parseOptions(out), nil
}
func (s *Tmux) parseOptions(options []byte) map[string]string {
scanner := bufio.NewScanner(bytes.NewBuffer(options))
result := map[string]string{}
for scanner.Scan() {
match := optMatcher.FindSubmatch(scanner.Bytes())
if len(match) > 2 {
result[string(match[1])] = string(s.unwrap(match[2], quote))
}
}
return result
}
func (s *Tmux) unwrap(input, wrap []byte) []byte {
if bytes.HasPrefix(input, wrap) && bytes.HasSuffix(input, wrap) {
return bytes.TrimSuffix(bytes.TrimPrefix(input, wrap), wrap)
}
return input
}