diff --git a/go.mod b/go.mod index aee19f7..cfe65c7 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/charmbracelet/bubbletea v0.26.0 github.com/charmbracelet/lipgloss v0.11.0 gopkg.in/yaml.v3 v3.0.1 + mvdan.cc/sh/v3 v3.7.0 ) require ( diff --git a/go.sum b/go.sum index 7846397..ff9c5e4 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,10 @@ github.com/charmbracelet/x/ansi v0.1.1 h1:CGAduulr6egay/YVbGc8Hsu8deMg1xZ/bkaXTP github.com/charmbracelet/x/ansi v0.1.1/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= +github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -33,6 +37,7 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97 h1:3RPlVWzZ/PDqmVuf/FKHARG5EMid/tl7cv54Sw/QRVY= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -47,3 +52,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +mvdan.cc/sh/v3 v3.7.0 h1:lSTjdP/1xsddtaKfGg7Myu7DnlHItd3/M2tomOcNNBg= +mvdan.cc/sh/v3 v3.7.0/go.mod h1:K2gwkaesF/D7av7Kxl0HbF5kGOd2ArupNTX3X44+8l8= diff --git a/internal/tui/update.go b/internal/tui/update.go index 6ff8a23..4355716 100644 --- a/internal/tui/update.go +++ b/internal/tui/update.go @@ -4,11 +4,12 @@ import ( "fmt" "os/exec" + "github.com/Bharath-code/git-scope/internal/model" + "github.com/Bharath-code/git-scope/internal/stats" "github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" - "github.com/Bharath-code/git-scope/internal/model" - "github.com/Bharath-code/git-scope/internal/stats" + "mvdan.cc/sh/v3/shell" ) // Update handles messages and updates the model @@ -50,14 +51,21 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil case openEditorMsg: - // Check if editor exists in PATH before trying to launch - _, err := exec.LookPath(m.cfg.Editor) + // Parse editor command (handles "editor --flag" style configs) + fields, err := shell.Fields(m.cfg.Editor, nil) + if err != nil || len(fields) == 0 { + m.statusMsg = fmt.Sprintf("❌ Invalid editor command: '%s'", m.cfg.Editor) + return m, nil + } + // Check if editor binary exists in PATH + _, err = exec.LookPath(fields[0]) if err != nil { - m.statusMsg = fmt.Sprintf("❌ Editor '%s' not found. Press 'e' to change editor or install it first.", m.cfg.Editor) + m.statusMsg = fmt.Sprintf("❌ Editor '%s' not found. Press 'e' to change editor or install it first.", fields[0]) return m, nil } - - c := exec.Command(m.cfg.Editor, msg.path) + + args := append(fields[1:], msg.path) + c := exec.Command(fields[0], args...) return m, tea.ExecProcess(c, func(err error) tea.Msg { if err != nil { return editorClosedMsg{err: err} @@ -194,10 +202,12 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "e": if m.state == StateReady { - // Check if editor exists - _, err := exec.LookPath(m.cfg.Editor) - if err != nil { - m.statusMsg = fmt.Sprintf("❌ Editor '%s' not found in PATH. Install it or edit ~/.config/git-scope/config.yml", m.cfg.Editor) + // Check if editor exists (parse command to get binary name) + fields, err := shell.Fields(m.cfg.Editor, nil) + if err != nil || len(fields) == 0 { + m.statusMsg = fmt.Sprintf("❌ Invalid editor command: '%s'", m.cfg.Editor) + } else if _, err := exec.LookPath(fields[0]); err != nil { + m.statusMsg = fmt.Sprintf("❌ Editor '%s' not found in PATH. Install it or edit ~/.config/git-scope/config.yml", fields[0]) } else { m.statusMsg = fmt.Sprintf("✓ Editor: %s (edit config at ~/.config/git-scope/config.yml)", m.cfg.Editor) }