mirror of
https://github.com/sst/opencode.git
synced 2025-07-07 16:14:59 +00:00
fix: preserve textarea content when external editor fails
Only clear textarea when external editor exits successfully, rather than clearing immediately and restoring on failure. This simpler approach prevents content loss when the editor exits with non-zero status. 🤖 Generated with [opencode](https://opencode.ai) Co-Authored-By: opencode <noreply@opencode.ai>
This commit is contained in:
parent
a1161fd0e8
commit
cd8411691d
2 changed files with 22 additions and 24 deletions
|
@ -27,7 +27,6 @@ type EditorComponent interface {
|
|||
Content(width int) string
|
||||
Lines() int
|
||||
Value() string
|
||||
SetValue(value string)
|
||||
Focused() bool
|
||||
Focus() (tea.Model, tea.Cmd)
|
||||
Blur()
|
||||
|
@ -231,10 +230,6 @@ func (m *editorComponent) Value() string {
|
|||
return m.textarea.Value()
|
||||
}
|
||||
|
||||
func (m *editorComponent) SetValue(value string) {
|
||||
m.textarea.SetValue(value)
|
||||
}
|
||||
|
||||
func (m *editorComponent) Submit() (tea.Model, tea.Cmd) {
|
||||
value := strings.TrimSpace(m.Value())
|
||||
if value == "" {
|
||||
|
|
|
@ -32,9 +32,10 @@ import (
|
|||
// InterruptDebounceTimeoutMsg is sent when the interrupt key debounce timeout expires
|
||||
type InterruptDebounceTimeoutMsg struct{}
|
||||
|
||||
// EditorRestoreMsg is sent when the external editor fails and we need to restore the original content
|
||||
type EditorRestoreMsg struct {
|
||||
Content string
|
||||
// EditorSuccessMsg is sent when the external editor succeeds and we should clear textarea and send the message
|
||||
type EditorSuccessMsg struct {
|
||||
Text string
|
||||
Attachments []opencode.FilePartParam
|
||||
}
|
||||
|
||||
// InterruptKeyState tracks the state of interrupt key presses for debouncing
|
||||
|
@ -491,9 +492,12 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
// Reset interrupt key state after timeout
|
||||
a.interruptKeyState = InterruptKeyIdle
|
||||
a.editor.SetInterruptKeyInDebounce(false)
|
||||
case EditorRestoreMsg:
|
||||
// Restore the original content to the textarea when editor fails
|
||||
a.editor.SetValue(msg.Content)
|
||||
case EditorSuccessMsg:
|
||||
// Clear the textarea and send the message when editor succeeds
|
||||
updated, cmd := a.editor.Clear()
|
||||
a.editor = updated.(chat.EditorComponent)
|
||||
cmds = append(cmds, cmd)
|
||||
cmds = append(cmds, util.CmdHandler(app.SendMsg{Text: msg.Text, Attachments: msg.Attachments}))
|
||||
case dialog.FindSelectedMsg:
|
||||
return a.openFile(msg.FilePath)
|
||||
}
|
||||
|
@ -781,9 +785,6 @@ func (a appModel) executeCommand(command commands.Command) (tea.Model, tea.Cmd)
|
|||
}
|
||||
|
||||
value := a.editor.Value()
|
||||
updated, cmd := a.editor.Clear()
|
||||
a.editor = updated.(chat.EditorComponent)
|
||||
cmds = append(cmds, cmd)
|
||||
|
||||
tmpfile, err := os.CreateTemp("", "msg_*.md")
|
||||
tmpfile.WriteString(value)
|
||||
|
@ -803,28 +804,30 @@ func (a appModel) executeCommand(command commands.Command) (tea.Model, tea.Cmd)
|
|||
if err != nil {
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
slog.Warn("Editor exited with non-zero status", "exitCode", exitError.ExitCode())
|
||||
// Restore original content when editor exits unsuccessfully
|
||||
return EditorRestoreMsg{Content: value}
|
||||
// Don't clear textarea on failure
|
||||
return nil
|
||||
} else {
|
||||
slog.Error("Failed to open editor", "error", err)
|
||||
// Restore original content when editor fails to start
|
||||
return EditorRestoreMsg{Content: value}
|
||||
// Don't clear textarea on failure
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
content, err := os.ReadFile(tmpfile.Name())
|
||||
if err != nil {
|
||||
slog.Error("Failed to read file", "error", err)
|
||||
// Restore original content when file read fails
|
||||
return EditorRestoreMsg{Content: value}
|
||||
// Don't clear textarea on failure
|
||||
return nil
|
||||
}
|
||||
if len(content) == 0 {
|
||||
slog.Warn("Message is empty")
|
||||
// Restore original content when message is empty
|
||||
return EditorRestoreMsg{Content: value}
|
||||
// Don't clear textarea on failure
|
||||
return nil
|
||||
}
|
||||
return app.SendMsg{
|
||||
Text: string(content),
|
||||
// Only clear and send if everything succeeded
|
||||
return EditorSuccessMsg{
|
||||
Text: string(content),
|
||||
Attachments: []opencode.FilePartParam{}, // attachments,
|
||||
}
|
||||
})
|
||||
cmds = append(cmds, cmd)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue