v0.29.0 21b3150

keybindings.go RawHistoryFolder

1package handlers
2
3import (
4	"context"
5	"encoding/json"
6	"fmt"
7
8	"github.com/bnema/dumber/internal/application/port"
9	"github.com/bnema/dumber/internal/logging"
10)
11
12// KeybindingsHandler handles keybinding-related messages.
13type KeybindingsHandler struct {
14	getUC      port.KeybindingsGetter
15	setUC      port.KeybindingSetter
16	resetUC    port.KeybindingResetter
17	resetAllUC port.AllKeybindingsResetter
18}
19
20// NewKeybindingsHandler creates a new KeybindingsHandler.
21func NewKeybindingsHandler(
22	getUC port.KeybindingsGetter,
23	setUC port.KeybindingSetter,
24	resetUC port.KeybindingResetter,
25	resetAllUC port.AllKeybindingsResetter,
26) *KeybindingsHandler {
27	return &KeybindingsHandler{
28		getUC:      getUC,
29		setUC:      setUC,
30		resetUC:    resetUC,
31		resetAllUC: resetAllUC,
32	}
33}
34
35// HandleGetKeybindings returns all keybindings grouped by mode.
36func (h *KeybindingsHandler) HandleGetKeybindings(ctx context.Context, _ port.WebViewID, _ json.RawMessage) (any, error) {
37	return h.getUC.Execute(ctx)
38}
39
40// HandleSetKeybinding updates a single keybinding.
41func (h *KeybindingsHandler) HandleSetKeybinding(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
42	log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()
43	log.Debug().RawJSON("payload", payload).Msg("HandleSetKeybinding called")
44
45	var req port.SetKeybindingRequest
46	if err := json.Unmarshal(payload, &req); err != nil {
47		log.Error().Err(err).RawJSON("payload", payload).Msg("failed to unmarshal request")
48		return nil, fmt.Errorf("invalid request: %w", err)
49	}
50
51	resp, err := h.setUC.Execute(ctx, req)
52	if err != nil {
53		return nil, err
54	}
55
56	return map[string]any{
57		"status":    "success",
58		"conflicts": resp.Conflicts,
59	}, nil
60}
61
62// HandleResetKeybinding resets a keybinding to default.
63func (h *KeybindingsHandler) HandleResetKeybinding(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
64	log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()
65
66	var req port.ResetKeybindingRequest
67	if err := json.Unmarshal(payload, &req); err != nil {
68		return nil, fmt.Errorf("invalid request: %w", err)
69	}
70
71	log.Info().Str("mode", req.Mode).Str("action", req.Action).Msg("resetting keybinding to default")
72
73	if err := h.resetUC.Execute(ctx, req); err != nil {
74		return nil, err
75	}
76
77	return map[string]any{"status": "success"}, nil
78}
79
80// HandleResetAllKeybindings resets all keybindings to defaults.
81func (h *KeybindingsHandler) HandleResetAllKeybindings(ctx context.Context, _ port.WebViewID, _ json.RawMessage) (any, error) {
82	log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()
83	log.Info().Msg("resetting all keybindings to defaults")
84
85	if err := h.resetAllUC.Execute(ctx); err != nil {
86		return nil, err
87	}
88
89	return map[string]any{"status": "success"}, nil
90}
91
92// RegisterKeybindingsHandlers registers keybindings handlers with the router.
93func RegisterKeybindingsHandlers(ctx context.Context, router port.WebUIHandlerRouter, handler *KeybindingsHandler) error {
94	log := logging.FromContext(ctx).With().Str("component", "handlers").Logger()
95
96	// Get all keybindings
97	if err := router.RegisterHandlerWithCallbacks(
98		"get_keybindings",
99		"__dumber_keybindings_loaded",
100		"__dumber_keybindings_error",
101		"",
102		port.WebUIMessageHandlerFunc(handler.HandleGetKeybindings),
103	); err != nil {
104		return err
105	}
106
107	// Set a single keybinding
108	if err := router.RegisterHandlerWithCallbacks(
109		"set_keybinding",
110		"__dumber_keybinding_set",
111		"__dumber_keybinding_set_error",
112		"",
113		port.WebUIMessageHandlerFunc(handler.HandleSetKeybinding),
114	); err != nil {
115		return err
116	}
117
118	// Reset a single keybinding
119	if err := router.RegisterHandlerWithCallbacks(
120		"reset_keybinding",
121		"__dumber_keybinding_reset",
122		"__dumber_keybinding_reset_error",
123		"",
124		port.WebUIMessageHandlerFunc(handler.HandleResetKeybinding),
125	); err != nil {
126		return err
127	}
128
129	// Reset all keybindings
130	if err := router.RegisterHandlerWithCallbacks(
131		"reset_all_keybindings",
132		"__dumber_keybindings_reset_all",
133		"__dumber_keybindings_reset_all_error",
134		"",
135		port.WebUIMessageHandlerFunc(handler.HandleResetAllKeybindings),
136	); err != nil {
137		return err
138	}
139
140	log.Info().Msg("registered keybindings handlers")
141	return nil
142}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close