Skip to content

Commit 36e5d64

Browse files
zambettibjarneo
andauthored
Update keymap to respect responsive height (#167)
* Update keymap to respect responsive height * Use 'ctrl+x' for expand/collapse height (was 'x') to avoid conflicts with typed filter/search input * Simplify keymap overlay: deduplicate visible-row calc, remove global scroll state, drop j/k/g/G bindings that conflict with search filter * Update docs for Ctrl+X expand/collapse keybinding --------- Co-authored-by: Bjarne Øverli <bjarne.oeverli@gmail.com>
1 parent 6782a8c commit 36e5d64

6 files changed

Lines changed: 100 additions & 35 deletions

File tree

docs/keybindings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Press `Ctrl+K` in the player to see all keybindings.
2929
| `h` `l` | EQ cursor left/right |
3030
| `Enter` | Play selected track |
3131
| `/` | Search playlist |
32-
| `x` | Expand/collapse playlist |
32+
| `Ctrl+X` | Expand/collapse playlist |
3333
| `o` | Open file browser |
3434
| `b` `Esc` | Back to provider |
3535

site/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,7 @@
12751275
<div class="key-row"><kbd>u</kbd><span>Load URL (stream/playlist)</span></div>
12761276
<div class="key-row"><kbd>y</kbd><span>Show lyrics</span></div>
12771277
<div class="key-row"><kbd>Ctrl+J</kbd><span>Jump to time</span></div>
1278-
<div class="key-row"><kbd>x</kbd><span>Expand playlist</span></div>
1278+
<div class="key-row"><kbd>Ctrl+X</kbd><span>Expand playlist</span></div>
12791279
<div class="key-row"><kbd>o</kbd><span>Open file browser</span></div>
12801280
<div class="key-row"><kbd>a</kbd><span>Queue (play next)</span></div>
12811281
<div class="key-row"><kbd>A</kbd><span>Queue manager</span></div>

ui/model/filebrowser.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ func (m *Model) handleFileBrowserKey(msg tea.KeyPressMsg) tea.Cmd {
210210
case "esc", "o", "q":
211211
m.fileBrowser.visible = false
212212

213-
case "x":
213+
case "ctrl+x":
214214
m.toggleExpandPlaylist()
215215
m.fbMaybeAdjustScroll(m.fbVisible())
216216

ui/model/keymap.go

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ var keymapEntries = []keymapEntry{
4747
{"p", "Playlist manager"},
4848
{"i", "Track info / metadata"},
4949
{"Ctrl+S", "Save/download track to ~/Music"},
50-
{"x", "Expand/collapse playlist"},
50+
{"Ctrl+X", "Expand/collapse playlist"},
5151
{"/", "Search playlist"},
5252
{"f", "Find on YouTube (queue play next)"},
5353
{"Ctrl+F", "Find on SoundCloud (queue play next)"},
@@ -61,56 +61,86 @@ var keymapEntries = []keymapEntry{
6161
{"q", "Quit"},
6262
}
6363

64+
func (m Model) keymapCount() int {
65+
if m.keymap.search != "" {
66+
return len(m.keymap.filtered)
67+
}
68+
return len(keymapEntries)
69+
}
70+
6471
// handleKeymapKey processes key presses while the keymap overlay is open.
6572
func (m *Model) handleKeymapKey(msg tea.KeyPressMsg) tea.Cmd {
66-
switch msg.Code {
67-
case tea.KeyEscape:
73+
key := msg.String()
74+
75+
switch {
76+
case key == "ctrl+c":
77+
m.keymap.visible = false
78+
return m.quit()
79+
80+
case msg.Code == tea.KeyEscape:
6881
m.keymap.visible = false
6982
m.keymap.search = ""
7083
m.keymap.filtered = nil
7184
m.keymap.cursor = 0
72-
case tea.KeyUp:
85+
86+
case msg.Code == tea.KeyUp:
87+
count := m.keymapCount()
7388
if m.keymap.cursor > 0 {
7489
m.keymap.cursor--
75-
} else {
76-
count := len(keymapEntries)
77-
if m.keymap.search != "" {
78-
count = len(m.keymap.filtered)
79-
}
80-
if count > 0 {
81-
m.keymap.cursor = count - 1
82-
}
83-
}
84-
case tea.KeyDown:
85-
count := len(keymapEntries)
86-
if m.keymap.search != "" {
87-
count = len(m.keymap.filtered)
90+
} else if count > 0 {
91+
m.keymap.cursor = count - 1
8892
}
93+
94+
case msg.Code == tea.KeyDown:
95+
count := m.keymapCount()
8996
if m.keymap.cursor < count-1 {
9097
m.keymap.cursor++
9198
} else if count > 0 {
9299
m.keymap.cursor = 0
93100
}
94-
case tea.KeyBackspace:
101+
102+
case key == "ctrl+x":
103+
m.toggleExpandPlaylist()
104+
105+
case key == "pgup" || key == "ctrl+u":
106+
if m.keymap.cursor > 0 {
107+
step := max(1, m.keymapVisibleRows())
108+
m.keymap.cursor -= min(m.keymap.cursor, step)
109+
}
110+
111+
case key == "pgdown" || key == "ctrl+d":
112+
count := m.keymapCount()
113+
if m.keymap.cursor < count-1 {
114+
step := max(1, m.keymapVisibleRows())
115+
m.keymap.cursor = min(count-1, m.keymap.cursor+step)
116+
}
117+
118+
case msg.Code == tea.KeyHome:
119+
m.keymap.cursor = 0
120+
121+
case msg.Code == tea.KeyEnd:
122+
count := m.keymapCount()
123+
if count > 0 {
124+
m.keymap.cursor = count - 1
125+
}
126+
127+
case msg.Code == tea.KeyBackspace:
95128
if m.keymap.search != "" {
96129
m.keymap.search = removeLastRune(m.keymap.search)
97130
m.updateKeymapFilter()
98131
}
99-
case tea.KeySpace:
132+
133+
case msg.Code == tea.KeySpace:
100134
m.keymap.search += " "
101135
m.updateKeymapFilter()
136+
102137
default:
103-
switch msg.String() {
104-
case "ctrl+c":
105-
m.keymap.visible = false
106-
return m.quit()
107-
default:
108-
if len(msg.Text) > 0 {
109-
m.keymap.search += msg.Text
110-
m.updateKeymapFilter()
111-
}
138+
if len(msg.Text) > 0 {
139+
m.keymap.search += msg.Text
140+
m.updateKeymapFilter()
112141
}
113142
}
143+
114144
return nil
115145
}
116146

ui/model/keys.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ func (m *Model) handleKey(msg tea.KeyPressMsg) tea.Cmd {
339339
m.openJumpMode()
340340
case "J":
341341
return m.switchToProvider("jellyfin")
342-
case "x":
342+
case "ctrl+x":
343343
m.toggleExpandPlaylist()
344344
}
345345
return nil
@@ -714,7 +714,7 @@ func (m *Model) handleKey(msg tea.KeyPressMsg) tea.Cmd {
714714
m.restorePanelWidth()
715715
}
716716

717-
case "x":
717+
case "ctrl+x":
718718
if m.focus == focusPlaylist {
719719
m.toggleExpandPlaylist()
720720
}

ui/model/view_overlays.go

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"fmt"
66
"strings"
77

8+
"charm.land/lipgloss/v2"
9+
810
"cliamp/lyrics"
911
"cliamp/theme"
1012
"cliamp/ui"
@@ -60,6 +62,39 @@ func (m Model) renderDeviceOverlay() string {
6062
return m.centerOverlay(strings.Join(lines, "\n"))
6163
}
6264

65+
func (m Model) keymapHelpLine() string {
66+
return helpKey("↑↓", "Navigate ") + helpKey("PgUp/Dn", "Page ") +
67+
helpKey("Home/End", "Jump ") + helpKey("Type", "Filter ") + helpKey("Esc", "Close")
68+
}
69+
70+
func (m Model) keymapVisibleRows() int {
71+
probeSearch := dimStyle.Render(" Type to filter…")
72+
if m.keymap.search != "" {
73+
probeSearch = playlistSelectedStyle.Render(" / " + m.keymap.search + "_")
74+
}
75+
76+
probeSections := []string{
77+
titleStyle.Render("K E Y M A P"),
78+
"",
79+
probeSearch,
80+
"",
81+
"x", // list placeholder (1 row)
82+
"",
83+
dimStyle.Render(" 0/0 keys"),
84+
"",
85+
m.keymapHelpLine(),
86+
}
87+
88+
probeFrame := ui.FrameStyle.Render(strings.Join(probeSections, "\n"))
89+
fixedHeight := lipgloss.Height(probeFrame) - 1
90+
91+
limit := maxPlVisible
92+
if m.heightExpanded {
93+
limit = m.height
94+
}
95+
return max(3, min(limit, m.height-fixedHeight))
96+
}
97+
6398
func (m Model) renderKeymapOverlay() string {
6499
lines := []string{
65100
titleStyle.Render("K E Y M A P"),
@@ -82,7 +117,7 @@ func (m Model) renderKeymapOverlay() string {
82117
visible = entries
83118
}
84119

85-
maxVisible := 12
120+
maxVisible := m.keymapVisibleRows()
86121
rendered := 0
87122

88123
if len(visible) == 0 {
@@ -99,7 +134,7 @@ func (m Model) renderKeymapOverlay() string {
99134

100135
lines = padLines(lines, maxVisible, rendered)
101136
lines = append(lines, "", dimStyle.Render(fmt.Sprintf(" %d/%d keys", len(visible), len(entries))))
102-
lines = append(lines, "", helpKey("↑↓", "Navigate ")+helpKey("Type", "Filter ")+helpKey("Esc", "Close"))
137+
lines = append(lines, "", m.keymapHelpLine())
103138

104139
return m.centerOverlay(strings.Join(lines, "\n"))
105140
}

0 commit comments

Comments
 (0)