main 5041353

named_context_registry.go RawHistoryFolder

1package content
2
3import (
4	"sync"
5
6	"github.com/bnema/dumber/internal/application/port"
7	"github.com/bnema/dumber/internal/domain/entity"
8)
9
10type namedBrowsingContextKey struct {
11	OwnerWindowID string
12	Name          string
13}
14
15type namedBrowsingContextState struct {
16	PaneID       entity.PaneID
17	WebViewID    port.WebViewID
18	HostWindowID string
19}
20
21type namedBrowsingContextRegistry struct {
22	mu       sync.RWMutex
23	contexts map[namedBrowsingContextKey]namedBrowsingContextState
24}
25
26func newNamedBrowsingContextRegistry() *namedBrowsingContextRegistry {
27	return &namedBrowsingContextRegistry{
28		contexts: make(map[namedBrowsingContextKey]namedBrowsingContextState),
29	}
30}
31
32func (r *namedBrowsingContextRegistry) Register(ownerWindowID, hostWindowID, name string, paneID entity.PaneID, webViewID port.WebViewID) {
33	if r == nil || ownerWindowID == "" || hostWindowID == "" || name == "" || paneID == "" || webViewID == 0 {
34		return
35	}
36	r.mu.Lock()
37	r.contexts[namedBrowsingContextKey{OwnerWindowID: ownerWindowID, Name: name}] = namedBrowsingContextState{
38		PaneID: paneID, WebViewID: webViewID, HostWindowID: hostWindowID,
39	}
40	r.mu.Unlock()
41}
42
43func (r *namedBrowsingContextRegistry) Lookup(
44	windowID, name string,
45	lookupWebView func(entity.PaneID) port.WebView,
46	resolveWindowID func(entity.PaneID) (string, bool),
47) (namedBrowsingContextState, port.WebView, bool) {
48	if r == nil || windowID == "" || name == "" || lookupWebView == nil || resolveWindowID == nil {
49		return namedBrowsingContextState{}, nil, false
50	}
51
52	key := namedBrowsingContextKey{OwnerWindowID: windowID, Name: name}
53	r.mu.RLock()
54	state, ok := r.contexts[key]
55	r.mu.RUnlock()
56	if !ok {
57		return namedBrowsingContextState{}, nil, false
58	}
59
60	currentWindowID, ok := resolveWindowID(state.PaneID)
61	if !ok || currentWindowID != state.HostWindowID {
62		r.deleteIfStateMatches(key, state)
63		return namedBrowsingContextState{}, nil, false
64	}
65
66	wv := lookupWebView(state.PaneID)
67	if wv == nil || wv.IsDestroyed() || wv.ID() != state.WebViewID {
68		r.deleteIfStateMatches(key, state)
69		return namedBrowsingContextState{}, nil, false
70	}
71
72	return state, wv, true
73}
74
75func (r *namedBrowsingContextRegistry) deleteIfStateMatches(key namedBrowsingContextKey, state namedBrowsingContextState) {
76	if r == nil {
77		return
78	}
79	r.mu.Lock()
80	if currentState, ok := r.contexts[key]; ok && currentState == state {
81		delete(r.contexts, key)
82	}
83	r.mu.Unlock()
84}
85
86func (r *namedBrowsingContextRegistry) UnregisterByPaneID(paneID entity.PaneID) {
87	if r == nil || paneID == "" {
88		return
89	}
90	r.mu.Lock()
91	for key, state := range r.contexts {
92		if state.PaneID == paneID {
93			delete(r.contexts, key)
94		}
95	}
96	r.mu.Unlock()
97}
98
99func (r *namedBrowsingContextRegistry) UnregisterByWebViewID(webViewID port.WebViewID) {
100	if r == nil || webViewID == 0 {
101		return
102	}
103	r.mu.Lock()
104	for key, state := range r.contexts {
105		if state.WebViewID == webViewID {
106			delete(r.contexts, key)
107		}
108	}
109	r.mu.Unlock()
110}
111
112func (r *namedBrowsingContextRegistry) UnregisterWindow(windowID string) {
113	if r == nil || windowID == "" {
114		return
115	}
116	r.mu.Lock()
117	for key, state := range r.contexts {
118		if key.OwnerWindowID == windowID || state.HostWindowID == windowID {
119			delete(r.contexts, key)
120		}
121	}
122	r.mu.Unlock()
123}

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