diff --git a/.editorconfig b/.editorconfig old mode 100644 new mode 100755 diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml old mode 100644 new mode 100755 diff --git a/.github/workflows/manual-homebrew-release.yml b/.github/workflows/manual-homebrew-release.yml old mode 100644 new mode 100755 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml old mode 100644 new mode 100755 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.golangci.yml b/.golangci.yml old mode 100644 new mode 100755 diff --git a/.prettierrc b/.prettierrc old mode 100644 new mode 100755 diff --git a/CHANGELOG.md b/CHANGELOG.md old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/go.mod b/go.mod old mode 100644 new mode 100755 diff --git a/go.sum b/go.sum old mode 100644 new mode 100755 diff --git a/internal/config/config.go b/internal/config/config.go old mode 100644 new mode 100755 diff --git a/internal/config/config_test.go b/internal/config/config_test.go old mode 100644 new mode 100755 diff --git a/internal/runner/runner.go b/internal/runner/runner.go old mode 100644 new mode 100755 diff --git a/internal/runner/runner_test.go b/internal/runner/runner_test.go old mode 100644 new mode 100755 diff --git a/internal/ui/ui.go b/internal/ui/ui.go old mode 100644 new mode 100755 index b5f181b..de9b26d --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -57,6 +57,7 @@ type model struct { streaming bool // true while command is running (streaming output) streamResult *runner.StreamingResult // current streaming result lastLineCount int // track line count for updates + userScrolled bool // true if user manually scrolled during streaming spinnerFrame int // current spinner animation frame errorMsg string statusMsg string // temporary status message (e.g., "Yanked!") @@ -162,6 +163,7 @@ func (m *model) startStreaming() tea.Cmd { m.lastLineCount = 0 m.exitCode = -1 m.errorMsg = "" + m.userScrolled = false return m.streamTickCmd() } @@ -201,6 +203,15 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.lines = newLines m.lastLineCount = newCount m.updateFiltered() + + // Auto-scroll to bottom if user hasn't manually scrolled + if !m.userScrolled { + visible := m.visibleLines() + if visible > 0 { + m.cursor = max(len(m.filtered)-1, 0) + m.offset = max(len(m.filtered)-visible, 0) + } + } } // Check if command completed @@ -309,24 +320,32 @@ func (m *model) handleKeyPress(msg tea.KeyMsg) (tea.Model, tea.Cmd) { return m, tea.Quit case "j", "down", "ctrl+n": + m.userScrolled = true m.moveCursor(1) case "k", "up", "ctrl+p": + m.userScrolled = true m.moveCursor(-1) case "g", "home": + m.userScrolled = true m.cursor = 0 m.offset = 0 case "G", "end": + m.userScrolled = false // Resume following output if len(m.filtered) > 0 { m.cursor = len(m.filtered) - 1 m.adjustOffset() } case "ctrl+d": + m.userScrolled = true m.moveCursor(m.visibleLines() / 2) case "ctrl+u": + m.userScrolled = true m.moveCursor(-m.visibleLines() / 2) case "pgdown", "ctrl+f": + m.userScrolled = true m.moveCursor(m.visibleLines()) case "pgup", "ctrl+b": + m.userScrolled = true m.moveCursor(-m.visibleLines()) case "p": m.showPreview = !m.showPreview @@ -494,7 +513,16 @@ func (m *model) updateFiltered() { if m.cursor < 0 { m.cursor = 0 } - m.offset = 0 + + // Clamp offset to valid bounds instead of resetting to 0 + // This preserves scroll position during streaming updates + visible := m.visibleLines() + if visible > 0 { + maxOffset := max(len(m.filtered)-visible, 0) + if m.offset > maxOffset { + m.offset = maxOffset + } + } } // renderHelpOverlay creates the help box content (without positioning) diff --git a/internal/ui/ui_test.go b/internal/ui/ui_test.go old mode 100644 new mode 100755 diff --git a/main.go b/main.go old mode 100644 new mode 100755 diff --git a/version.txt b/version.txt old mode 100644 new mode 100755