summaryrefslogtreecommitdiffhomepage
path: root/packages/tui
diff options
context:
space:
mode:
authoradamdotdevin <[email protected]>2025-07-29 13:11:38 -0500
committeradamdotdevin <[email protected]>2025-07-29 13:11:38 -0500
commita129e122aad1e3eef34ead4b5970c6be4fb2004a (patch)
tree29f17f193a03a0612739ffe1d9c9525f04942249 /packages/tui
parentc0ee6a6d05983d7d24adedbf0ab67dd562ccfb81 (diff)
downloadopencode-a129e122aad1e3eef34ead4b5970c6be4fb2004a.tar.gz
opencode-a129e122aad1e3eef34ead4b5970c6be4fb2004a.zip
feat: show git diff in reverted messages
Diffstat (limited to 'packages/tui')
-rw-r--r--packages/tui/internal/components/chat/messages.go33
-rw-r--r--packages/tui/internal/components/diff/parse.go58
2 files changed, 91 insertions, 0 deletions
diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go
index fa0ec5e54..23de97ed2 100644
--- a/packages/tui/internal/components/chat/messages.go
+++ b/packages/tui/internal/components/chat/messages.go
@@ -5,6 +5,8 @@ import (
"fmt"
"log/slog"
"slices"
+ "sort"
+ "strconv"
"strings"
tea "github.com/charmbracelet/bubbletea/v2"
@@ -14,6 +16,7 @@ import (
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/commands"
"github.com/sst/opencode/internal/components/dialog"
+ "github.com/sst/opencode/internal/components/diff"
"github.com/sst/opencode/internal/components/toast"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
@@ -569,6 +572,36 @@ func (m *messagesComponent) renderView() tea.Cmd {
hint += revertedStyle.Render(" (or /redo) to restore")
content += "\n" + hint
+ if m.app.Session.Revert.Diff != "" {
+ t := theme.CurrentTheme()
+ s := styles.NewStyle().Background(t.BackgroundPanel())
+ green := s.Foreground(t.Success()).Render
+ red := s.Foreground(t.Error()).Render
+ content += "\n"
+ stats, err := diff.ParseStats(m.app.Session.Revert.Diff)
+ if err != nil {
+ slog.Error("Failed to parse diff stats", "error", err)
+ } else {
+ var files []string
+ for file := range stats {
+ files = append(files, file)
+ }
+ sort.Strings(files)
+
+ for _, file := range files {
+ fileStats := stats[file]
+ display := file
+ if fileStats.Added > 0 {
+ display += green(" +" + strconv.Itoa(int(fileStats.Added)))
+ }
+ if fileStats.Removed > 0 {
+ display += red(" -" + strconv.Itoa(int(fileStats.Removed)))
+ }
+ content += "\n" + display
+ }
+ }
+ }
+
content = styles.NewStyle().
Background(t.BackgroundPanel()).
Width(width - 6).
diff --git a/packages/tui/internal/components/diff/parse.go b/packages/tui/internal/components/diff/parse.go
new file mode 100644
index 000000000..261ba5970
--- /dev/null
+++ b/packages/tui/internal/components/diff/parse.go
@@ -0,0 +1,58 @@
+package diff
+
+import (
+ "bufio"
+ "fmt"
+ "strings"
+)
+
+type DiffStats struct {
+ Added int
+ Removed int
+ Modified int
+}
+
+func ParseStats(diff string) (map[string]DiffStats, error) {
+ stats := make(map[string]DiffStats)
+ var currentFile string
+ scanner := bufio.NewScanner(strings.NewReader(diff))
+
+ for scanner.Scan() {
+ line := scanner.Text()
+ if strings.HasPrefix(line, "---") {
+ continue
+ } else if strings.HasPrefix(line, "+++") {
+ parts := strings.SplitN(line, " ", 2)
+ if len(parts) == 2 {
+ currentFile = strings.TrimPrefix(parts[1], "b/")
+ }
+ continue
+ }
+ if strings.HasPrefix(line, "@@") {
+ continue
+ }
+ if currentFile == "" {
+ continue
+ }
+
+ fileStats := stats[currentFile]
+ switch {
+ case strings.HasPrefix(line, "+"):
+ fileStats.Added++
+ case strings.HasPrefix(line, "-"):
+ fileStats.Removed++
+ }
+ stats[currentFile] = fileStats
+ }
+
+ if err := scanner.Err(); err != nil {
+ return nil, fmt.Errorf("error reading diff string: %w", err)
+ }
+
+ for file, fileStats := range stats {
+ fileStats.Modified = fileStats.Added + fileStats.Removed
+ stats[file] = fileStats
+ }
+
+ return stats, nil
+}