v0.23.2 bfd5eb4

borders.go RawHistoryFolder

1package focus
2
3import (
4	"context"
5
6	"github.com/bnema/dumber/internal/logging"
7	"github.com/bnema/dumber/internal/ui/input"
8	"github.com/bnema/dumber/internal/ui/layout"
9)
10
11// CSS classes for mode borders.
12const (
13	paneModeClass    = "pane-mode-active"
14	tabModeClass     = "tab-mode-active"
15	sessionModeClass = "session-mode-active"
16)
17
18// BorderManager manages mode indicator borders on the workspace container.
19// It creates a transparent overlay box that displays colored borders when
20// the user enters tab mode or pane mode.
21type BorderManager struct {
22	borderOverlay layout.BoxWidget
23	currentMode   input.Mode
24}
25
26// NewBorderManager creates a border manager.
27// It creates a border overlay widget that should be added to the workspace container.
28func NewBorderManager(factory layout.WidgetFactory) *BorderManager {
29	// Create overlay box for mode borders
30	borderBox := factory.NewBox(layout.OrientationVertical, 0)
31	borderBox.SetCanFocus(false)
32	borderBox.SetCanTarget(false) // Don't intercept pointer events
33	borderBox.SetHexpand(true)
34	borderBox.SetVexpand(true)
35	borderBox.SetVisible(false) // Hidden in normal mode
36
37	return &BorderManager{
38		borderOverlay: borderBox,
39		currentMode:   input.ModeNormal,
40	}
41}
42
43// Widget returns the border overlay widget for adding to workspace overlay.
44func (bm *BorderManager) Widget() layout.Widget {
45	return bm.borderOverlay
46}
47
48// OnModeChange updates border visibility based on mode.
49func (bm *BorderManager) OnModeChange(ctx context.Context, from, to input.Mode) {
50	log := logging.FromContext(ctx)
51	log.Debug().
52		Str("from", from.String()).
53		Str("to", to.String()).
54		Msg("border manager: mode changed")
55
56	// Remove old mode class
57	switch from {
58	case input.ModePane:
59		bm.borderOverlay.RemoveCssClass(paneModeClass)
60	case input.ModeTab:
61		bm.borderOverlay.RemoveCssClass(tabModeClass)
62	case input.ModeSession:
63		bm.borderOverlay.RemoveCssClass(sessionModeClass)
64	}
65
66	// Add new mode class and set visibility
67	switch to {
68	case input.ModePane:
69		bm.borderOverlay.AddCssClass(paneModeClass)
70		bm.borderOverlay.SetVisible(true)
71	case input.ModeTab:
72		bm.borderOverlay.AddCssClass(tabModeClass)
73		bm.borderOverlay.SetVisible(true)
74	case input.ModeSession:
75		bm.borderOverlay.AddCssClass(sessionModeClass)
76		bm.borderOverlay.SetVisible(true)
77	case input.ModeNormal:
78		bm.borderOverlay.SetVisible(false)
79	default:
80		// Resize mode is handled by per-pane stack border, not global overlay.
81		bm.borderOverlay.SetVisible(false)
82	}
83
84	bm.currentMode = to
85}
86
87// CurrentMode returns the current input mode.
88func (bm *BorderManager) CurrentMode() input.Mode {
89	return bm.currentMode
90}

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