on main help sign in
feat: open editor in the right position (#1804)
467418dCarlos Alexandro Becker
go.mod+2−1
@@ -3,7 +3,7 @@ module github.com/charmbracelet/crush
3go 1.25.5
3go 1.25.5
4
4
5require (
5require (
6− charm.land/bubbles/v2 v2.0.0-rc.1
6+ charm.land/bubbles/v2 v2.0.0-rc.1.0.20260109112849-ae99f46cec66
7 charm.land/bubbletea/v2 v2.0.0-rc.2.0.20251216153312-819e2e89c62e
7 charm.land/bubbletea/v2 v2.0.0-rc.2.0.20251216153312-819e2e89c62e
8 charm.land/fantasy v0.6.0
8 charm.land/fantasy v0.6.0
9 charm.land/glamour/v2 v2.0.0-20251110203732-69649f93d3b1
9 charm.land/glamour/v2 v2.0.0-20251110203732-69649f93d3b1
@@ -23,6 +23,7 @@ require (
23 github.com/charmbracelet/fang v0.4.4
23 github.com/charmbracelet/fang v0.4.4
24 github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560
24 github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560
25 github.com/charmbracelet/x/ansi v0.11.3
25 github.com/charmbracelet/x/ansi v0.11.3
26+ github.com/charmbracelet/x/editor v0.2.0
26 github.com/charmbracelet/x/etag v0.2.0
27 github.com/charmbracelet/x/etag v0.2.0
27 github.com/charmbracelet/x/exp/charmtone v0.0.0-20250708181618-a60a724ba6c3
28 github.com/charmbracelet/x/exp/charmtone v0.0.0-20250708181618-a60a724ba6c3
28 github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f
29 github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f
go.sum+4−2
@@ -1,5 +1,5 @@
1−charm.land/bubbles/v2 v2.0.0-rc.1 h1:EiIFVAc3Zi/yY86td+79mPhHR7AqZ1OxF+6ztpOCRaM=
1+charm.land/bubbles/v2 v2.0.0-rc.1.0.20260109112849-ae99f46cec66 h1:2BdJynsAW+8rv9xq6ZS+x0mtacfxpxjIK1KUIeTqBOs=
2−charm.land/bubbles/v2 v2.0.0-rc.1/go.mod h1:5AbN6cEd/47gkEf8TgiQ2O3RZ5QxMS14l9W+7F9fPC4=
2+charm.land/bubbles/v2 v2.0.0-rc.1.0.20260109112849-ae99f46cec66/go.mod h1:5AbN6cEd/47gkEf8TgiQ2O3RZ5QxMS14l9W+7F9fPC4=
3charm.land/bubbletea/v2 v2.0.0-rc.2.0.20251216153312-819e2e89c62e h1:tXwTmgGpwZT7ParKF5xbEQBVjM2e1uKhKi/GpfU3mYQ=
3charm.land/bubbletea/v2 v2.0.0-rc.2.0.20251216153312-819e2e89c62e h1:tXwTmgGpwZT7ParKF5xbEQBVjM2e1uKhKi/GpfU3mYQ=
4charm.land/bubbletea/v2 v2.0.0-rc.2.0.20251216153312-819e2e89c62e/go.mod h1:pDM18flq3Z4njKZPA3zCvyVSSIJbMcoqlE82BdGUtL8=
4charm.land/bubbletea/v2 v2.0.0-rc.2.0.20251216153312-819e2e89c62e/go.mod h1:pDM18flq3Z4njKZPA3zCvyVSSIJbMcoqlE82BdGUtL8=
5charm.land/fantasy v0.6.0 h1:0PZfZ/w6c70UdlumGGFW6s9zTV6f4xAV/bXo6vGuZsc=
5charm.land/fantasy v0.6.0 h1:0PZfZ/w6c70UdlumGGFW6s9zTV6f4xAV/bXo6vGuZsc=
@@ -104,6 +104,8 @@ github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560 h1:j3PW2
104github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560/go.mod h1:VWATWLRwYP06VYCEur7FsNR2B1xAo7Y+xl1PTbd1ePc=
104github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560/go.mod h1:VWATWLRwYP06VYCEur7FsNR2B1xAo7Y+xl1PTbd1ePc=
105github.com/charmbracelet/x/ansi v0.11.3 h1:6DcVaqWI82BBVM/atTyq6yBoRLZFBsnoDoX9GCu2YOI=
105github.com/charmbracelet/x/ansi v0.11.3 h1:6DcVaqWI82BBVM/atTyq6yBoRLZFBsnoDoX9GCu2YOI=
106github.com/charmbracelet/x/ansi v0.11.3/go.mod h1:yI7Zslym9tCJcedxz5+WBq+eUGMJT0bM06Fqy1/Y4dI=
106github.com/charmbracelet/x/ansi v0.11.3/go.mod h1:yI7Zslym9tCJcedxz5+WBq+eUGMJT0bM06Fqy1/Y4dI=
107+github.com/charmbracelet/x/editor v0.2.0 h1:7XLUKtaRaB8jN7bWU2p2UChiySyaAuIfYiIRg8gGWwk=
108+github.com/charmbracelet/x/editor v0.2.0/go.mod h1:p3oQ28TSL3YPd+GKJ1fHWcp+7bVGpedHpXmo0D6t1dY=
107github.com/charmbracelet/x/etag v0.2.0 h1:Euj1VkheoHfTYA9y+TCwkeXF/hN8Fb9l4LqZl79pt04=
109github.com/charmbracelet/x/etag v0.2.0 h1:Euj1VkheoHfTYA9y+TCwkeXF/hN8Fb9l4LqZl79pt04=
108github.com/charmbracelet/x/etag v0.2.0/go.mod h1:C1B7/bsgvzzxpfu0Rabbd+rTHJa5TmC/qgTseCf6DF0=
110github.com/charmbracelet/x/etag v0.2.0/go.mod h1:C1B7/bsgvzzxpfu0Rabbd+rTHJa5TmC/qgTseCf6DF0=
109github.com/charmbracelet/x/exp/charmtone v0.0.0-20250708181618-a60a724ba6c3 h1:1xwHZg6eMZ9Wv5TE1UGub6ARubyOd1Lo5kPUI/6VL50=
111github.com/charmbracelet/x/exp/charmtone v0.0.0-20250708181618-a60a724ba6c3 h1:1xwHZg6eMZ9Wv5TE1UGub6ARubyOd1Lo5kPUI/6VL50=
internal/tui/components/chat/editor/editor.go+13−14
@@ -1,14 +1,12 @@
1package editor
1package editor
2
2
3import (
3import (
4− "context"
5 "errors"
4 "errors"
6 "fmt"
5 "fmt"
7 "math/rand"
6 "math/rand"
8 "net/http"
7 "net/http"
9 "os"
8 "os"
10 "path/filepath"
9 "path/filepath"
11− "runtime"
12 "slices"
10 "slices"
13 "strings"
11 "strings"
14 "unicode"
12 "unicode"
@@ -32,6 +30,7 @@ import (
32 "github.com/charmbracelet/crush/internal/tui/styles"
30 "github.com/charmbracelet/crush/internal/tui/styles"
33 "github.com/charmbracelet/crush/internal/tui/util"
31 "github.com/charmbracelet/crush/internal/tui/util"
34 "github.com/charmbracelet/x/ansi"
32 "github.com/charmbracelet/x/ansi"
33+ "github.com/charmbracelet/x/editor"
35)
34)
36
35
37type Editor interface {
36type Editor interface {
@@ -94,16 +93,6 @@ type OpenEditorMsg struct {
94}
93}
95
94
96func (m *editorCmp) openEditor(value string) tea.Cmd {
95func (m *editorCmp) openEditor(value string) tea.Cmd {
97− editor := os.Getenv("EDITOR")
98− if editor == "" {
99− // Use platform-appropriate default editor
100− if runtime.GOOS == "windows" {
101− editor = "notepad"
102− } else {
103− editor = "nvim"
104− }
105− }
106−
107 tmpfile, err := os.CreateTemp("", "msg_*.md")
96 tmpfile, err := os.CreateTemp("", "msg_*.md")
108 if err != nil {
97 if err != nil {
109 return util.ReportError(err)
98 return util.ReportError(err)
@@ -112,8 +101,18 @@ func (m *editorCmp) openEditor(value string) tea.Cmd {
112 if _, err := tmpfile.WriteString(value); err != nil {
101 if _, err := tmpfile.WriteString(value); err != nil {
113 return util.ReportError(err)
102 return util.ReportError(err)
114 }
103 }
104+ cmd, err := editor.Command(
105+ "crush",
115− cmdStr := editor + " " + tmpfile.Name()
106+ tmpfile.Name(),
116− return util.ExecShell(context.TODO(), cmdStr, func(err error) tea.Msg {
107+ editor.AtPosition(
108+ m.textarea.Line()+1,
109+ m.textarea.Column()+1,
110+ ),
111+ )
112+ if err != nil {
113+ return util.ReportError(err)
114+ }
115+ return tea.ExecProcess(cmd, func(err error) tea.Msg {
117 if err != nil {
116 if err != nil {
118 return util.ReportError(err)
117 return util.ReportError(err)
119 }
118 }