on main help sign in
perf: drop reflection usage and use string builder
commit1dccc979c7e2d5c7d5e6de20b76cfbbb62d11ce4 authorRaphael Amorim <rapha850@gmail.com> dateMon 16 Jun 2025, 14:25 (1 year ago) parentd957f5d
20 files changed+224−71
internal/llm/tools/diagnostics.go+16−16 internal/llm/tools/grep.go+9−9 internal/llm/tools/ls.go+1−1 internal/tui/components/chat/editor/keys.go+9−2 internal/tui/components/completions/keys.go+11−2 internal/tui/components/core/layout/layout.go+3−12 internal/tui/components/core/list/keys.go+17−2 internal/tui/components/core/status/keys.go+11−2 internal/tui/components/dialogs/commands/keys.go+22−3 internal/tui/components/dialogs/compact/keys.go+12−2 internal/tui/components/dialogs/filepicker/keys.go+13−2 internal/tui/components/dialogs/init/keys.go+12−2 internal/tui/components/dialogs/keys.go+8−2 internal/tui/components/dialogs/models/keys.go+11−2 internal/tui/components/dialogs/permissions/keys.go+14−2 internal/tui/components/dialogs/quit/keys.go+13−2 internal/tui/components/dialogs/sessions/keys.go+11−2 internal/tui/keys.go+12−2 internal/tui/page/chat/keys.go+11−2 internal/tui/page/logs/keys.go+8−2
internal/llm/tools/diagnostics.go+16−16
@@ -245,28 +245,28 @@ func getDiagnostics(filePath string, lsps map[string]*lsp.Client) string {
245245 return projectDiagnostics[i] < projectDiagnostics[j]
246246 })
247247
248− output := ""
248+ var output strings.Builder
249249
250250 if len(fileDiagnostics) > 0 {
251− output += "\n<file_diagnostics>\n"
251+ output.WriteString("\n<file_diagnostics>\n")
252252 if len(fileDiagnostics) > 10 {
253− output += strings.Join(fileDiagnostics[:10], "\n")
254− output += fmt.Sprintf("\n... and %d more diagnostics", len(fileDiagnostics)-10)
253+ output.WriteString(strings.Join(fileDiagnostics[:10], "\n"))
254+ fmt.Fprintf(&output, "\n... and %d more diagnostics", len(fileDiagnostics)-10)
255255 } else {
256− output += strings.Join(fileDiagnostics, "\n")
256+ output.WriteString(strings.Join(fileDiagnostics, "\n"))
257257 }
258− output += "\n</file_diagnostics>\n"
258+ output.WriteString("\n</file_diagnostics>\n")
259259 }
260260
261261 if len(projectDiagnostics) > 0 {
262− output += "\n<project_diagnostics>\n"
262+ output.WriteString("\n<project_diagnostics>\n")
263263 if len(projectDiagnostics) > 10 {
264− output += strings.Join(projectDiagnostics[:10], "\n")
265− output += fmt.Sprintf("\n... and %d more diagnostics", len(projectDiagnostics)-10)
264+ output.WriteString(strings.Join(projectDiagnostics[:10], "\n"))
265+ fmt.Fprintf(&output, "\n... and %d more diagnostics", len(projectDiagnostics)-10)
266266 } else {
267− output += strings.Join(projectDiagnostics, "\n")
267+ output.WriteString(strings.Join(projectDiagnostics, "\n"))
268268 }
269− output += "\n</project_diagnostics>\n"
269+ output.WriteString("\n</project_diagnostics>\n")
270270 }
271271
272272 if len(fileDiagnostics) > 0 || len(projectDiagnostics) > 0 {
@@ -275,13 +275,13 @@ func getDiagnostics(filePath string, lsps map[string]*lsp.Client) string {
275275 projectErrors := countSeverity(projectDiagnostics, "Error")
276276 projectWarnings := countSeverity(projectDiagnostics, "Warn")
277277
278− output += "\n<diagnostic_summary>\n"
279− output += fmt.Sprintf("Current file: %d errors, %d warnings\n", fileErrors, fileWarnings)
280− output += fmt.Sprintf("Project: %d errors, %d warnings\n", projectErrors, projectWarnings)
281− output += "</diagnostic_summary>\n"
278+ output.WriteString("\n<diagnostic_summary>\n")
279+ fmt.Fprintf(&output, "Current file: %d errors, %d warnings\n", fileErrors, fileWarnings)
280+ fmt.Fprintf(&output, "Project: %d errors, %d warnings\n", projectErrors, projectWarnings)
281+ output.WriteString("</diagnostic_summary>\n")
282282 }
283283
284− return output
284+ return output.String()
285285}
286286
287287func countSeverity(diagnostics []string, severity string) int {
internal/llm/tools/grep.go+9−9
@@ -198,35 +198,35 @@ func (g *grepTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error)
198198 return ToolResponse{}, fmt.Errorf("error searching files: %w", err)
199199 }
200200
201− var output string
201+ var output strings.Builder
202202 if len(matches) == 0 {
203− output = "No files found"
203+ output.WriteString("No files found")
204204 } else {
205− output = fmt.Sprintf("Found %d matches\n", len(matches))
205+ fmt.Fprintf(&output, "Found %d matches\n", len(matches))
206206
207207 currentFile := ""
208208 for _, match := range matches {
209209 if currentFile != match.path {
210210 if currentFile != "" {
211− output += "\n"
211+ output.WriteString("\n")
212212 }
213213 currentFile = match.path
214− output += fmt.Sprintf("%s:\n", match.path)
214+ fmt.Fprintf(&output, "%s:\n", match.path)
215215 }
216216 if match.lineNum > 0 {
217− output += fmt.Sprintf(" Line %d: %s\n", match.lineNum, match.lineText)
217+ fmt.Fprintf(&output, " Line %d: %s\n", match.lineNum, match.lineText)
218218 } else {
219− output += fmt.Sprintf(" %s\n", match.path)
219+ fmt.Fprintf(&output, " %s\n", match.path)
220220 }
221221 }
222222
223223 if truncated {
224− output += "\n(Results are truncated. Consider using a more specific path or pattern.)"
224+ output.WriteString("\n(Results are truncated. Consider using a more specific path or pattern.)")
225225 }
226226 }
227227
228228 return WithResponseMetadata(
229− NewTextResponse(output),
229+ NewTextResponse(output.String()),
230230 GrepResponseMetadata{
231231 NumberOfMatches: len(matches),
232232 Truncated: truncated,
internal/llm/tools/ls.go+1−1
@@ -209,7 +209,7 @@ func printNode(builder *strings.Builder, node *TreeNode, level int) {
209209
210210 nodeName := node.Name
211211 if node.Type == "directory" {
212− nodeName += string(filepath.Separator)
212+ nodeName = nodeName + string(filepath.Separator)
213213 }
214214
215215 fmt.Fprintf(builder, "%s- %s\n", indent, nodeName)
internal/tui/components/chat/editor/keys.go+9−2
@@ -2,7 +2,6 @@ package editor
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type EditorKeyMap struct {
@@ -23,10 +22,18 @@ func DefaultEditorKeyMap() EditorKeyMap {
2322 }
2423}
2524
25+// KeyBindings implements layout.KeyMapProvider
26+func (k EditorKeyMap) KeyBindings() []key.Binding {
27+ return []key.Binding{
28+ k.Send,
29+ k.OpenEditor,
30+ }
31+}
32+
2633// FullHelp implements help.KeyMap.
2734func (k EditorKeyMap) FullHelp() [][]key.Binding {
2835 m := [][]key.Binding{}
29− slice := layout.KeyMapToSlice(k)
36+ slice := k.KeyBindings()
3037 for i := 0; i < len(slice); i += 4 {
3138 end := min(i+4, len(slice))
3239 m = append(m, slice[i:end])
internal/tui/components/completions/keys.go+11−2
@@ -2,7 +2,6 @@ package completions
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type KeyMap struct {
@@ -33,10 +32,20 @@ func DefaultKeyMap() KeyMap {
3332 }
3433}
3534
35+// KeyBindings implements layout.KeyMapProvider
36+func (k KeyMap) KeyBindings() []key.Binding {
37+ return []key.Binding{
38+ k.Down,
39+ k.Up,
40+ k.Select,
41+ k.Cancel,
42+ }
43+}
44+
3645// FullHelp implements help.KeyMap.
3746func (k KeyMap) FullHelp() [][]key.Binding {
3847 m := [][]key.Binding{}
39− slice := layout.KeyMapToSlice(k)
48+ slice := k.KeyBindings()
4049 for i := 0; i < len(slice); i += 4 {
4150 end := min(i+4, len(slice))
4251 m = append(m, slice[i:end])
internal/tui/components/core/layout/layout.go+3−12
@@ -1,8 +1,6 @@
11package layout
22
33import (
4− "reflect"
5−
64 "github.com/charmbracelet/bubbles/v2/help"
75 "github.com/charmbracelet/bubbles/v2/key"
86 tea "github.com/charmbracelet/bubbletea/v2"
@@ -27,14 +25,7 @@ type Positionable interface {
2725 SetPosition(x, y int) tea.Cmd
2826}
2927
30−func KeyMapToSlice(t any) (bindings []key.Binding) {
31− typ := reflect.TypeOf(t)
32− if typ.Kind() != reflect.Struct {
33− return nil
34− }
35− for i := range typ.NumField() {
36− v := reflect.ValueOf(t).Field(i)
37− bindings = append(bindings, v.Interface().(key.Binding))
38− }
39− return
28+// KeyMapProvider defines an interface for types that can provide their key bindings as a slice
29+type KeyMapProvider interface {
30+ KeyBindings() []key.Binding
4031}
internal/tui/components/core/list/keys.go+17−2
@@ -2,7 +2,6 @@ package list
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type KeyMap struct {
@@ -53,10 +52,26 @@ func DefaultKeyMap() KeyMap {
5352 }
5453}
5554
55+// KeyBindings implements layout.KeyMapProvider
56+func (k KeyMap) KeyBindings() []key.Binding {
57+ return []key.Binding{
58+ k.Down,
59+ k.Up,
60+ k.NDown,
61+ k.NUp,
62+ k.DownOneItem,
63+ k.UpOneItem,
64+ k.HalfPageDown,
65+ k.HalfPageUp,
66+ k.Home,
67+ k.End,
68+ }
69+}
70+
5671// FullHelp implements help.KeyMap.
5772func (k KeyMap) FullHelp() [][]key.Binding {
5873 m := [][]key.Binding{}
59− slice := layout.KeyMapToSlice(k)
74+ slice := k.KeyBindings()
6075 for i := 0; i < len(slice); i += 4 {
6176 end := min(i+4, len(slice))
6277 m = append(m, slice[i:end])
internal/tui/components/core/status/keys.go+11−2
@@ -2,7 +2,6 @@ package status
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type KeyMap struct {
@@ -33,10 +32,20 @@ func DefaultKeyMap(tabHelp string) KeyMap {
3332 }
3433}
3534
35+// KeyBindings implements layout.KeyMapProvider
36+func (k KeyMap) KeyBindings() []key.Binding {
37+ return []key.Binding{
38+ k.Tab,
39+ k.Commands,
40+ k.Sessions,
41+ k.Help,
42+ }
43+}
44+
3645// FullHelp implements help.KeyMap.
3746func (k KeyMap) FullHelp() [][]key.Binding {
3847 m := [][]key.Binding{}
39− slice := layout.KeyMapToSlice(k)
48+ slice := k.KeyBindings()
4049 for i := 0; i < len(slice); i += 4 {
4150 end := min(i+4, len(slice))
4251 m = append(m, slice[i:end])
internal/tui/components/dialogs/commands/keys.go+22−3
@@ -2,7 +2,6 @@ package commands
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type CommandsDialogKeyMap struct {
@@ -38,10 +37,21 @@ func DefaultCommandsDialogKeyMap() CommandsDialogKeyMap {
3837 }
3938}
4039
40+// KeyBindings implements layout.KeyMapProvider
41+func (k CommandsDialogKeyMap) KeyBindings() []key.Binding {
42+ return []key.Binding{
43+ k.Select,
44+ k.Next,
45+ k.Previous,
46+ k.Tab,
47+ k.Close,
48+ }
49+}
50+
4151// FullHelp implements help.KeyMap.
4252func (k CommandsDialogKeyMap) FullHelp() [][]key.Binding {
4353 m := [][]key.Binding{}
44− slice := layout.KeyMapToSlice(k)
54+ slice := k.KeyBindings()
4555 for i := 0; i < len(slice); i += 4 {
4656 end := min(i+4, len(slice))
4757 m = append(m, slice[i:end])
@@ -86,10 +96,19 @@ func DefaultArgumentsDialogKeyMap() ArgumentsDialogKeyMap {
8696 }
8797}
8898
99+// KeyBindings implements layout.KeyMapProvider
100+func (k ArgumentsDialogKeyMap) KeyBindings() []key.Binding {
101+ return []key.Binding{
102+ k.Confirm,
103+ k.Next,
104+ k.Previous,
105+ }
106+}
107+
89108// FullHelp implements help.KeyMap.
90109func (k ArgumentsDialogKeyMap) FullHelp() [][]key.Binding {
91110 m := [][]key.Binding{}
92− slice := layout.KeyMapToSlice(k)
111+ slice := k.KeyBindings()
93112 for i := 0; i < len(slice); i += 4 {
94113 end := min(i+4, len(slice))
95114 m = append(m, slice[i:end])
internal/tui/components/dialogs/compact/keys.go+12−2
@@ -2,7 +2,6 @@ package compact
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87// KeyMap defines the key bindings for the compact dialog.
@@ -40,10 +39,21 @@ func DefaultKeyMap() KeyMap {
4039 }
4140}
4241
42+// KeyBindings implements layout.KeyMapProvider
43+func (k KeyMap) KeyBindings() []key.Binding {
44+ return []key.Binding{
45+ k.ChangeSelection,
46+ k.Select,
47+ k.Y,
48+ k.N,
49+ k.Close,
50+ }
51+}
52+
4353// FullHelp implements help.KeyMap.
4454func (k KeyMap) FullHelp() [][]key.Binding {
4555 m := [][]key.Binding{}
46− slice := layout.KeyMapToSlice(k)
56+ slice := k.KeyBindings()
4757 for i := 0; i < len(slice); i += 4 {
4858 end := min(i+4, len(slice))
4959 m = append(m, slice[i:end])
internal/tui/components/dialogs/filepicker/keys.go+13−2
@@ -2,7 +2,6 @@ package filepicker
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87// KeyMap defines keyboard bindings for dialog management.
@@ -45,10 +44,22 @@ func DefaultKeyMap() KeyMap {
4544 }
4645}
4746
47+// KeyBindings implements layout.KeyMapProvider
48+func (k KeyMap) KeyBindings() []key.Binding {
49+ return []key.Binding{
50+ k.Select,
51+ k.Down,
52+ k.Up,
53+ k.Forward,
54+ k.Backward,
55+ k.Close,
56+ }
57+}
58+
4859// FullHelp implements help.KeyMap.
4960func (k KeyMap) FullHelp() [][]key.Binding {
5061 m := [][]key.Binding{}
51− slice := layout.KeyMapToSlice(k)
62+ slice := k.KeyBindings()
5263 for i := 0; i < len(slice); i += 4 {
5364 end := min(i+4, len(slice))
5465 m = append(m, slice[i:end])
internal/tui/components/dialogs/init/keys.go+12−2
@@ -2,7 +2,6 @@ package init
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type KeyMap struct {
@@ -38,10 +37,21 @@ func DefaultKeyMap() KeyMap {
3837 }
3938}
4039
40+// KeyBindings implements layout.KeyMapProvider
41+func (k KeyMap) KeyBindings() []key.Binding {
42+ return []key.Binding{
43+ k.ChangeSelection,
44+ k.Select,
45+ k.Y,
46+ k.N,
47+ k.Close,
48+ }
49+}
50+
4151// FullHelp implements help.KeyMap.
4252func (k KeyMap) FullHelp() [][]key.Binding {
4353 m := [][]key.Binding{}
44− slice := layout.KeyMapToSlice(k)
54+ slice := k.KeyBindings()
4555 for i := 0; i < len(slice); i += 4 {
4656 end := min(i+4, len(slice))
4757 m = append(m, slice[i:end])
internal/tui/components/dialogs/keys.go+8−2
@@ -2,7 +2,6 @@ package dialogs
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87// KeyMap defines keyboard bindings for dialog management.
@@ -18,10 +17,17 @@ func DefaultKeyMap() KeyMap {
1817 }
1918}
2019
20+// KeyBindings implements layout.KeyMapProvider
21+func (k KeyMap) KeyBindings() []key.Binding {
22+ return []key.Binding{
23+ k.Close,
24+ }
25+}
26+
2127// FullHelp implements help.KeyMap.
2228func (k KeyMap) FullHelp() [][]key.Binding {
2329 m := [][]key.Binding{}
24− slice := layout.KeyMapToSlice(k)
30+ slice := k.KeyBindings()
2531 for i := 0; i < len(slice); i += 4 {
2632 end := min(i+4, len(slice))
2733 m = append(m, slice[i:end])
internal/tui/components/dialogs/models/keys.go+11−2
@@ -2,7 +2,6 @@ package models
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type KeyMap struct {
@@ -33,10 +32,20 @@ func DefaultKeyMap() KeyMap {
3332 }
3433}
3534
35+// KeyBindings implements layout.KeyMapProvider
36+func (k KeyMap) KeyBindings() []key.Binding {
37+ return []key.Binding{
38+ k.Select,
39+ k.Next,
40+ k.Previous,
41+ k.Close,
42+ }
43+}
44+
3645// FullHelp implements help.KeyMap.
3746func (k KeyMap) FullHelp() [][]key.Binding {
3847 m := [][]key.Binding{}
39− slice := layout.KeyMapToSlice(k)
48+ slice := k.KeyBindings()
4049 for i := 0; i < len(slice); i += 4 {
4150 end := min(i+4, len(slice))
4251 m = append(m, slice[i:end])
internal/tui/components/dialogs/permissions/keys.go+14−2
@@ -2,7 +2,6 @@ package permissions
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type KeyMap struct {
@@ -48,10 +47,23 @@ func DefaultKeyMap() KeyMap {
4847 }
4948}
5049
50+// KeyBindings implements layout.KeyMapProvider
51+func (k KeyMap) KeyBindings() []key.Binding {
52+ return []key.Binding{
53+ k.Left,
54+ k.Right,
55+ k.Tab,
56+ k.Select,
57+ k.Allow,
58+ k.AllowSession,
59+ k.Deny,
60+ }
61+}
62+
5163// FullHelp implements help.KeyMap.
5264func (k KeyMap) FullHelp() [][]key.Binding {
5365 m := [][]key.Binding{}
54− slice := layout.KeyMapToSlice(k)
66+ slice := k.KeyBindings()
5567 for i := 0; i < len(slice); i += 4 {
5668 end := min(i+4, len(slice))
5769 m = append(m, slice[i:end])
internal/tui/components/dialogs/quit/keys.go+13−2
@@ -2,7 +2,6 @@ package quit
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87// KeyMap defines the keyboard bindings for the quit dialog.
@@ -44,10 +43,22 @@ func DefaultKeymap() KeyMap {
4443 }
4544}
4645
46+// KeyBindings implements layout.KeyMapProvider
47+func (k KeyMap) KeyBindings() []key.Binding {
48+ return []key.Binding{
49+ k.LeftRight,
50+ k.EnterSpace,
51+ k.Yes,
52+ k.No,
53+ k.Tab,
54+ k.Close,
55+ }
56+}
57+
4758// FullHelp implements help.KeyMap.
4859func (k KeyMap) FullHelp() [][]key.Binding {
4960 m := [][]key.Binding{}
50− slice := layout.KeyMapToSlice(k)
61+ slice := k.KeyBindings()
5162 for i := 0; i < len(slice); i += 4 {
5263 end := min(i+4, len(slice))
5364 m = append(m, slice[i:end])
internal/tui/components/dialogs/sessions/keys.go+11−2
@@ -2,7 +2,6 @@ package sessions
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type KeyMap struct {
@@ -33,10 +32,20 @@ func DefaultKeyMap() KeyMap {
3332 }
3433}
3534
35+// KeyBindings implements layout.KeyMapProvider
36+func (k KeyMap) KeyBindings() []key.Binding {
37+ return []key.Binding{
38+ k.Select,
39+ k.Next,
40+ k.Previous,
41+ k.Close,
42+ }
43+}
44+
3645// FullHelp implements help.KeyMap.
3746func (k KeyMap) FullHelp() [][]key.Binding {
3847 m := [][]key.Binding{}
39− slice := layout.KeyMapToSlice(k)
48+ slice := k.KeyBindings()
4049 for i := 0; i < len(slice); i += 4 {
4150 end := min(i+4, len(slice))
4251 m = append(m, slice[i:end])
internal/tui/keys.go+12−2
@@ -2,7 +2,6 @@ package tui
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type KeyMap struct {
@@ -42,7 +41,7 @@ func DefaultKeyMap() KeyMap {
4241// FullHelp implements help.KeyMap.
4342func (k KeyMap) FullHelp() [][]key.Binding {
4443 m := [][]key.Binding{}
45− slice := layout.KeyMapToSlice(k)
44+ slice := k.KeyBindings()
4645 for i := 0; i < len(slice); i += 4 {
4746 end := min(i+4, len(slice))
4847 m = append(m, slice[i:end])
@@ -50,6 +49,17 @@ func (k KeyMap) FullHelp() [][]key.Binding {
5049 return m
5150}
5251
52+// KeyBindings implements layout.KeyMapProvider
53+func (k KeyMap) KeyBindings() []key.Binding {
54+ return []key.Binding{
55+ k.Logs,
56+ k.Quit,
57+ k.Help,
58+ k.Commands,
59+ k.Sessions,
60+ }
61+}
62+
5363// ShortHelp implements help.KeyMap.
5464func (k KeyMap) ShortHelp() []key.Binding {
5565 return []key.Binding{}
internal/tui/page/chat/keys.go+11−2
@@ -2,7 +2,6 @@ package chat
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type KeyMap struct {
@@ -33,10 +32,20 @@ func DefaultKeyMap() KeyMap {
3332 }
3433}
3534
35+// KeyBindings implements layout.KeyMapProvider
36+func (k KeyMap) KeyBindings() []key.Binding {
37+ return []key.Binding{
38+ k.NewSession,
39+ k.FilePicker,
40+ k.Cancel,
41+ k.Tab,
42+ }
43+}
44+
3645// FullHelp implements help.KeyMap.
3746func (k KeyMap) FullHelp() [][]key.Binding {
3847 m := [][]key.Binding{}
39− slice := layout.KeyMapToSlice(k)
48+ slice := k.KeyBindings()
4049 for i := 0; i < len(slice); i += 4 {
4150 end := min(i+4, len(slice))
4251 m = append(m, slice[i:end])
internal/tui/page/logs/keys.go+8−2
@@ -2,7 +2,6 @@ package logs
22
33import (
44 "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/crush/internal/tui/components/core/layout"
65)
76
87type KeyMap struct {
@@ -18,10 +17,17 @@ func DefaultKeyMap() KeyMap {
1817 }
1918}
2019
20+// KeyBindings implements layout.KeyMapProvider
21+func (k KeyMap) KeyBindings() []key.Binding {
22+ return []key.Binding{
23+ k.Back,
24+ }
25+}
26+
2127// FullHelp implements help.KeyMap.
2228func (k KeyMap) FullHelp() [][]key.Binding {
2329 m := [][]key.Binding{}
24− slice := layout.KeyMapToSlice(k)
30+ slice := k.KeyBindings()
2531 for i := 0; i < len(slice); i += 4 {
2632 end := min(i+4, len(slice))
2733 m = append(m, slice[i:end])