mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-24 03:04:21 +01:00
basic undo feature (#1268)
Co-authored-by: adamdotdevin <2363879+adamdottv@users.noreply.github.com> Co-authored-by: Jay V <air@live.ca> Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Co-authored-by: Andrew Joslin <andrew@ajoslin.com> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Tobias Walle <9933601+tobias-walle@users.noreply.github.com>
This commit is contained in:
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/sst/opencode/internal/commands"
|
||||
"github.com/sst/opencode/internal/components/dialog"
|
||||
"github.com/sst/opencode/internal/components/textarea"
|
||||
"github.com/sst/opencode/internal/components/toast"
|
||||
"github.com/sst/opencode/internal/styles"
|
||||
"github.com/sst/opencode/internal/theme"
|
||||
"github.com/sst/opencode/internal/util"
|
||||
@@ -57,6 +58,7 @@ type editorComponent struct {
|
||||
historyIndex int // -1 means current (not in history)
|
||||
currentText string // Store current text when navigating history
|
||||
pasteCounter int
|
||||
reverted bool
|
||||
}
|
||||
|
||||
func (m *editorComponent) Init() tea.Cmd {
|
||||
@@ -122,10 +124,34 @@ func (m *editorComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
// Maximize editor responsiveness for printable characters
|
||||
if msg.Text != "" {
|
||||
m.reverted = false
|
||||
m.textarea, cmd = m.textarea.Update(msg)
|
||||
cmds = append(cmds, cmd)
|
||||
return m, tea.Batch(cmds...)
|
||||
}
|
||||
case app.MessageRevertedMsg:
|
||||
if msg.Session.ID == m.app.Session.ID {
|
||||
switch msg.Message.Info.(type) {
|
||||
case opencode.UserMessage:
|
||||
prompt, err := msg.Message.ToPrompt()
|
||||
if err != nil {
|
||||
return m, toast.NewErrorToast("Failed to revert message")
|
||||
}
|
||||
m.RestoreFromPrompt(*prompt)
|
||||
m.textarea.MoveToEnd()
|
||||
m.reverted = true
|
||||
return m, nil
|
||||
}
|
||||
}
|
||||
case app.SessionUnrevertedMsg:
|
||||
if msg.Session.ID == m.app.Session.ID {
|
||||
if m.reverted {
|
||||
updated, cmd := m.Clear()
|
||||
m = updated.(*editorComponent)
|
||||
return m, cmd
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
case tea.PasteMsg:
|
||||
text := string(msg)
|
||||
|
||||
@@ -646,21 +672,14 @@ func NewEditorComponent(app *app.App) EditorComponent {
|
||||
return m
|
||||
}
|
||||
|
||||
// RestoreFromHistory restores a message from history at the given index
|
||||
func (m *editorComponent) RestoreFromHistory(index int) {
|
||||
if index < 0 || index >= len(m.app.State.MessageHistory) {
|
||||
return
|
||||
}
|
||||
|
||||
entry := m.app.State.MessageHistory[index]
|
||||
|
||||
func (m *editorComponent) RestoreFromPrompt(prompt app.Prompt) {
|
||||
m.textarea.Reset()
|
||||
m.textarea.SetValue(entry.Text)
|
||||
m.textarea.SetValue(prompt.Text)
|
||||
|
||||
// Sort attachments by start index in reverse order (process from end to beginning)
|
||||
// This prevents index shifting issues
|
||||
attachmentsCopy := make([]*attachment.Attachment, len(entry.Attachments))
|
||||
copy(attachmentsCopy, entry.Attachments)
|
||||
attachmentsCopy := make([]*attachment.Attachment, len(prompt.Attachments))
|
||||
copy(attachmentsCopy, prompt.Attachments)
|
||||
|
||||
for i := 0; i < len(attachmentsCopy)-1; i++ {
|
||||
for j := i + 1; j < len(attachmentsCopy); j++ {
|
||||
@@ -677,6 +696,15 @@ func (m *editorComponent) RestoreFromHistory(index int) {
|
||||
}
|
||||
}
|
||||
|
||||
// RestoreFromHistory restores a message from history at the given index
|
||||
func (m *editorComponent) RestoreFromHistory(index int) {
|
||||
if index < 0 || index >= len(m.app.State.MessageHistory) {
|
||||
return
|
||||
}
|
||||
entry := m.app.State.MessageHistory[index]
|
||||
m.RestoreFromPrompt(entry)
|
||||
}
|
||||
|
||||
func getMediaTypeFromExtension(ext string) string {
|
||||
switch strings.ToLower(ext) {
|
||||
case ".jpg":
|
||||
|
||||
Reference in New Issue
Block a user