Skip to content

Commit e6dd7df

Browse files
authored
ui,preview: fix preview pane ctrl-u/d scrolling (#472)
Commit 8481b92 broke ctrl-u/d scrolling in the preview pane, see below code: ``` if common.IsInputMessage(msg) { if m.oplog != nil { cmds = append(cmds, m.oplog.Update(msg)) } else { cmds = append(cmds, m.revisions.Update(msg)) } return tea.Batch(cmds...) } ``` This causes unhandled key messages to be routed only to oplog or revisions, and then returns early, so they never reach the preview model's Update() call which happens later in the function. This fix groups preview related commands and make sure they are always handled. Also, added a YOffset() method to internal/ui/preview/preview.go to expose the viewport's Y offset for testing purposes.
1 parent 25dcfc0 commit e6dd7df

File tree

3 files changed

+128
-5
lines changed

3 files changed

+128
-5
lines changed

internal/ui/preview/preview.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ func (m *Model) WindowPercentage() float64 {
110110
return m.previewWindowPercentage
111111
}
112112

113+
func (m *Model) YOffset() int {
114+
return m.view.YOffset
115+
}
116+
113117
func (m *Model) Scroll(delta int) tea.Cmd {
114118
if delta > 0 {
115119
m.view.ScrollDown(delta)
@@ -204,6 +208,10 @@ func (m *Model) Update(msg tea.Msg) tea.Cmd {
204208
m.view.HalfPageDown()
205209
case key.Matches(msg, m.keyMap.Preview.HalfPageUp):
206210
m.view.HalfPageUp()
211+
case key.Matches(msg, m.keyMap.Preview.Expand):
212+
m.Expand()
213+
case key.Matches(msg, m.keyMap.Preview.Shrink):
214+
m.Shrink()
207215
}
208216
}
209217
return nil

internal/ui/ui.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,15 @@ func (m *Model) Update(msg tea.Msg) tea.Cmd {
274274
m.previewModel.ToggleVisible()
275275
cmds = append(cmds, common.SelectionChanged(m.context.SelectedItem))
276276
return tea.Batch(cmds...)
277-
case key.Matches(msg, m.keyMap.Preview.Expand) && m.previewModel.Visible():
278-
m.previewModel.Expand()
279-
return tea.Batch(cmds...)
280-
case key.Matches(msg, m.keyMap.Preview.Shrink) && m.previewModel.Visible():
281-
m.previewModel.Shrink()
277+
case m.previewModel.Visible() && key.Matches(msg,
278+
m.keyMap.Preview.Expand,
279+
m.keyMap.Preview.Shrink,
280+
m.keyMap.Preview.HalfPageDown,
281+
m.keyMap.Preview.HalfPageUp,
282+
m.keyMap.Preview.ScrollDown,
283+
m.keyMap.Preview.ScrollUp):
284+
cmd := m.previewModel.Update(msg)
285+
cmds = append(cmds, cmd)
282286
return tea.Batch(cmds...)
283287
case key.Matches(msg, m.keyMap.CustomCommands):
284288
model := customcommands.NewModel(m.context)

internal/ui/ui_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package ui
22

33
import (
4+
"strings"
45
"testing"
56

7+
tea "github.com/charmbracelet/bubbletea"
8+
"github.com/charmbracelet/x/cellbuf"
69
"github.com/stretchr/testify/assert"
710

811
"github.com/idursun/jjui/internal/ui/common"
@@ -21,3 +24,111 @@ func Test_Update_RevsetWithEmptyInputKeepsDefaultRevset(t *testing.T) {
2124

2225
assert.Equal(t, ctx.DefaultRevset, ctx.CurrentRevset)
2326
}
27+
28+
func Test_Update_PreviewScrollKeysWorkWhenVisible(t *testing.T) {
29+
tests := []struct {
30+
name string
31+
key tea.KeyMsg
32+
expectedScroll int // positive = down, negative = up
33+
}{
34+
{
35+
name: "ctrl+d scrolls half page down",
36+
key: tea.KeyMsg{Type: tea.KeyCtrlD},
37+
expectedScroll: 1,
38+
},
39+
{
40+
name: "ctrl+u scrolls half page up",
41+
key: tea.KeyMsg{Type: tea.KeyCtrlU},
42+
expectedScroll: -1,
43+
},
44+
{
45+
name: "ctrl+n scrolls down",
46+
key: tea.KeyMsg{Type: tea.KeyCtrlN},
47+
expectedScroll: 1,
48+
},
49+
{
50+
name: "ctrl+p scrolls up",
51+
key: tea.KeyMsg{Type: tea.KeyCtrlP},
52+
expectedScroll: -1,
53+
},
54+
}
55+
56+
for _, tc := range tests {
57+
t.Run(tc.name, func(t *testing.T) {
58+
commandRunner := test.NewTestCommandRunner(t)
59+
ctx := test.NewTestContext(commandRunner)
60+
61+
model := NewUI(ctx)
62+
model.SetFrame(cellbuf.Rect(0, 0, 100, 50))
63+
64+
model.previewModel.SetVisible(true)
65+
model.previewModel.SetFrame(cellbuf.Rect(50, 0, 50, 5))
66+
67+
var content strings.Builder
68+
for range 100 {
69+
content.WriteString("line content here\n")
70+
}
71+
model.previewModel.SetContent(content.String())
72+
73+
initialYOffset := model.previewModel.YOffset()
74+
75+
// Send the key message
76+
model.Update(tc.key)
77+
78+
newYOffset := model.previewModel.YOffset()
79+
if tc.expectedScroll > 0 {
80+
assert.Greater(t, newYOffset, initialYOffset, "expected scroll down for key %s", tc.name)
81+
} else {
82+
// For scroll up, we need content scrolled down first
83+
model.previewModel.Scroll(50) // scroll down first
84+
scrolledYOffset := model.previewModel.YOffset()
85+
model.Update(tc.key)
86+
newYOffset = model.previewModel.YOffset()
87+
assert.Less(t, newYOffset, scrolledYOffset, "expected scroll up for key %s", tc.name)
88+
}
89+
})
90+
}
91+
}
92+
93+
func Test_Update_PreviewResizeKeysWorkWhenVisible(t *testing.T) {
94+
tests := []struct {
95+
name string
96+
key tea.KeyMsg
97+
expectedResize int // positive = expand, negative = shrink
98+
}{
99+
{
100+
name: "ctrl+l shrinks preview",
101+
key: tea.KeyMsg{Type: tea.KeyCtrlL},
102+
expectedResize: -1,
103+
},
104+
{
105+
name: "ctrl+h expands preview",
106+
key: tea.KeyMsg{Type: tea.KeyCtrlH},
107+
expectedResize: 1,
108+
},
109+
}
110+
111+
for _, tc := range tests {
112+
t.Run(tc.name, func(t *testing.T) {
113+
commandRunner := test.NewTestCommandRunner(t)
114+
ctx := test.NewTestContext(commandRunner)
115+
116+
model := NewUI(ctx)
117+
model.SetFrame(cellbuf.Rect(0, 0, 100, 50))
118+
119+
model.previewModel.SetVisible(true)
120+
model.previewModel.SetFrame(cellbuf.Rect(50, 0, 50, 5))
121+
122+
initialWidth := model.previewModel.WindowPercentage()
123+
124+
model.Update(tc.key)
125+
126+
newWidth := model.previewModel.WindowPercentage()
127+
if tc.expectedResize > 0 {
128+
assert.Greater(t, newWidth, initialWidth, "expected preview to expand for key %s", tc.name)
129+
} else {
130+
assert.Less(t, newWidth, initialWidth, "expected preview to shrink for key %s", tc.name)
131+
}
132+
})
133+
}
134+
}

0 commit comments

Comments
 (0)