Merge pull request #116 from charmbracelet/editor-text-close

feat(tui): set the textarea value back after closing the editor
This commit is contained in:
Kujtim Hoxha
2025-07-10 20:38:40 +02:00
committed by GitHub
5 changed files with 35 additions and 19 deletions

2
go.mod
View File

@@ -16,7 +16,7 @@ require (
github.com/aymanbagabas/go-udiff v0.3.1
github.com/bmatcuk/doublestar/v4 v4.8.1
github.com/charlievieth/fastwalk v1.0.11
github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250607113720-eb5e1cf3b09e
github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250710161907-a4c42b579198
github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.1
github.com/charmbracelet/fang v0.1.0
github.com/charmbracelet/glamour/v2 v2.0.0-20250516160903-6f1e2c8f9ebe

2
go.sum
View File

@@ -70,6 +70,8 @@ github.com/charlievieth/fastwalk v1.0.11 h1:5sLT/q9+d9xMdpKExawLppqvXFZCVKf6JHnr
github.com/charlievieth/fastwalk v1.0.11/go.mod h1:yGy1zbxog41ZVMcKA/i8ojXLFsuayX5VvwhQVoj9PBI=
github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250607113720-eb5e1cf3b09e h1:99Ugtt633rqauFsXjZobZmtkNpeaWialfj8dl6COC6A=
github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250607113720-eb5e1cf3b09e/go.mod h1:6HamsBKWqEC/FVHuQMHgQL+knPyvHH55HwJDHl/adMw=
github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250710161907-a4c42b579198 h1:CkMS9Ah9ac1Ego5JDC5NJyZyAAqu23Z+O0yDwsa3IxM=
github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250710161907-a4c42b579198/go.mod h1:6HamsBKWqEC/FVHuQMHgQL+knPyvHH55HwJDHl/adMw=
github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250708152737-144080f3d891 h1:wh6N1dR4XkDh6XsiZh1/tImJAZvYB0yVLmaUKvJXvK0=
github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250708152737-144080f3d891/go.mod h1:SwBB+WoaQVMMOM9hknbN/7FNT86kgKG0LSHGTmLphX8=
github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40=

View File

@@ -67,6 +67,10 @@ const (
maxAttachments = 5
)
type openEditorMsg struct {
Text string
}
func (m *editorCmp) openEditor(value string) tea.Cmd {
editor := os.Getenv("EDITOR")
if editor == "" {
@@ -102,11 +106,8 @@ func (m *editorCmp) openEditor(value string) tea.Cmd {
return util.ReportWarn("Message is empty")
}
os.Remove(tmpfile.Name())
attachments := m.attachments
m.attachments = nil
return chat.SendMsg{
Text: string(content),
Attachments: attachments,
return openEditorMsg{
Text: strings.TrimSpace(string(content)),
}
})
}
@@ -184,6 +185,9 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.completionsStartIndex = 0
return m, nil
}
case openEditorMsg:
m.textarea.SetValue(msg.Text)
m.textarea.MoveToEnd()
case tea.KeyPressMsg:
switch {
// Completions
@@ -387,11 +391,11 @@ func NewEditorCmp(app *app.App) util.Model {
t := styles.CurrentTheme()
ta := textarea.New()
ta.SetStyles(t.S().TextArea)
ta.SetPromptFunc(4, func(lineIndex int, focused bool) string {
if lineIndex == 0 {
ta.SetPromptFunc(4, func(info textarea.PromptInfo) string {
if info.LineNumber == 0 {
return " > "
}
if focused {
if info.Focused {
return t.S().Base.Foreground(t.GreenDark).Render("::: ")
} else {
return t.S().Muted.Render("::: ")

View File

@@ -133,6 +133,13 @@ type LineInfo struct {
CharOffset int
}
// PromptInfo is a struct that can be used to store information about the
// prompt.
type PromptInfo struct {
LineNumber int
Focused bool
}
// CursorStyle is the style for real and virtual cursors.
type CursorStyle struct {
// Style styles the cursor block.
@@ -287,7 +294,7 @@ type Model struct {
// If promptFunc is set, it replaces Prompt as a generator for
// prompt strings at the beginning of each line.
promptFunc func(line int, focused bool) string
promptFunc func(PromptInfo) string
// promptWidth is the width of the prompt.
promptWidth int
@@ -983,14 +990,14 @@ func (m Model) Width() int {
return m.width
}
// moveToBegin moves the cursor to the beginning of the input.
func (m *Model) moveToBegin() {
// MoveToBegin moves the cursor to the beginning of the input.
func (m *Model) MoveToBegin() {
m.row = 0
m.SetCursorColumn(0)
}
// moveToEnd moves the cursor to the end of the input.
func (m *Model) moveToEnd() {
// MoveToEnd moves the cursor to the end of the input.
func (m *Model) MoveToEnd() {
m.row = len(m.value) - 1
m.SetCursorColumn(len(m.value[m.row]))
}
@@ -1052,7 +1059,7 @@ func (m *Model) SetWidth(w int) {
// promptWidth, it will be padded to the left. If it returns a prompt that is
// longer, display artifacts may occur; the caller is responsible for computing
// an adequate promptWidth.
func (m *Model) SetPromptFunc(promptWidth int, fn func(lineIndex int, focused bool) string) {
func (m *Model) SetPromptFunc(promptWidth int, fn func(PromptInfo) string) {
m.promptFunc = fn
m.promptWidth = promptWidth
}
@@ -1170,9 +1177,9 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
case key.Matches(msg, m.KeyMap.WordBackward):
m.wordLeft()
case key.Matches(msg, m.KeyMap.InputBegin):
m.moveToBegin()
m.MoveToBegin()
case key.Matches(msg, m.KeyMap.InputEnd):
m.moveToEnd()
m.MoveToEnd()
case key.Matches(msg, m.KeyMap.LowercaseWordForward):
m.lowercaseRight()
case key.Matches(msg, m.KeyMap.UppercaseWordForward):
@@ -1320,7 +1327,10 @@ func (m Model) promptView(displayLine int) (prompt string) {
if m.promptFunc == nil {
return prompt
}
prompt = m.promptFunc(displayLine, m.focus)
prompt = m.promptFunc(PromptInfo{
LineNumber: displayLine,
Focused: m.focus,
})
width := lipgloss.Width(prompt)
if width < m.promptWidth {
prompt = fmt.Sprintf("%*s%s", m.promptWidth-width, "", prompt)

2
vendor/modules.txt vendored
View File

@@ -242,7 +242,7 @@ github.com/bmatcuk/doublestar/v4
github.com/charlievieth/fastwalk
github.com/charlievieth/fastwalk/internal/dirent
github.com/charlievieth/fastwalk/internal/fmtdirent
# github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250607113720-eb5e1cf3b09e
# github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250710161907-a4c42b579198
## explicit; go 1.23.0
github.com/charmbracelet/bubbles/v2/cursor
github.com/charmbracelet/bubbles/v2/filepicker