detached 5a4101a

refactor(callers): update calls to pass context to refactored components

Update all callers across the codebase to pass context as first parameter
to refactored methods in SettingsManager, WebViewPool, TreeRenderer,
KeyboardHandler, and ModalState. Files updated:
- internal/ui/app.go: Pool.Prewarm, Pool.Close
- internal/ui/component/workspace_view.go
- internal/ui/controller/tab_controller.go
- internal/ui/coordinator/content.go
- internal/ui/coordinator/workspace.go
commit
5a4101a1b78e9cff0ca8c7a067d0b7849371f6fc
author
brice · · 2025-12-17 06:45 UTC
parent
4d6f6fd
signature
unsigned
5 files · +30 -24
M internal/ui/app.go +2 -2
@@ -142,7 +142,7 @@ func (a *App) onActivate(ctx context.Context) {
142142
143143 // Prewarm WebView pool now that GTK is initialized
144144 if a.pool != nil {
145- a.pool.Prewarm(0)
145+ a.pool.Prewarm(ctx, 0)
146146 }
147147
148148 // Create the main window
@@ -228,7 +228,7 @@ func (a *App) onShutdown(ctx context.Context) {
228228 a.faviconCache.Close()
229229 }
230230 if a.deps.Pool != nil {
231- a.deps.Pool.Close()
231+ a.deps.Pool.Close(ctx)
232232 }
233233
234234 log.Info().Msg("application shutdown complete")
@@ -142,7 +142,7 @@ func (a *App) onActivate(ctx context.Context) {
142 142
143 // Prewarm WebView pool now that GTK is initialized143 // Prewarm WebView pool now that GTK is initialized
144 if a.pool != nil {144 if a.pool != nil {
145- a.pool.Prewarm(0)145+ a.pool.Prewarm(ctx, 0)
146 }146 }
147 147
148 // Create the main window148 // Create the main window
@@ -228,7 +228,7 @@ func (a *App) onShutdown(ctx context.Context) {
228 a.faviconCache.Close()228 a.faviconCache.Close()
229 }229 }
230 if a.deps.Pool != nil {230 if a.deps.Pool != nil {
231- a.deps.Pool.Close()231+ a.deps.Pool.Close(ctx)
232 }232 }
233 233
234 log.Info().Msg("application shutdown complete")234 log.Info().Msg("application shutdown complete")
M internal/ui/component/workspace_view.go +2 -2
@@ -130,7 +130,7 @@ func (wv *WorkspaceView) SetWorkspace(ws *entity.Workspace) error {
130130
131131 // Build new tree
132132 if ws.Root != nil {
133- widget, err := wv.treeRenderer.Build(ws.Root)
133+ widget, err := wv.treeRenderer.Build(ctx, ws.Root)
134134 if err != nil {
135135 return err
136136 }
@@ -231,7 +231,7 @@ func (wv *WorkspaceView) SetOnPaneFocused(fn func(paneID entity.PaneID)) {
231231
232232 // Rebuild rebuilds the widget tree from the current workspace.
233233 // Use this after structural changes like splits or closes.
234-func (wv *WorkspaceView) Rebuild() error {
234+func (wv *WorkspaceView) Rebuild(ctx context.Context) error {
235235 wv.mu.RLock()
236236 ws := wv.workspace
237237 wv.mu.RUnlock()
@@ -130,7 +130,7 @@ func (wv *WorkspaceView) SetWorkspace(ws *entity.Workspace) error {
130 130
131 // Build new tree131 // Build new tree
132 if ws.Root != nil {132 if ws.Root != nil {
133- widget, err := wv.treeRenderer.Build(ws.Root)133+ widget, err := wv.treeRenderer.Build(ctx, ws.Root)
134 if err != nil {134 if err != nil {
135 return err135 return err
136 }136 }
@@ -231,7 +231,7 @@ func (wv *WorkspaceView) SetOnPaneFocused(fn func(paneID entity.PaneID)) {
231 231
232 // Rebuild rebuilds the widget tree from the current workspace.232 // Rebuild rebuilds the widget tree from the current workspace.
233 // Use this after structural changes like splits or closes.233 // Use this after structural changes like splits or closes.
234-func (wv *WorkspaceView) Rebuild() error {234+func (wv *WorkspaceView) Rebuild(ctx context.Context) error {
235 wv.mu.RLock()235 wv.mu.RLock()
236 ws := wv.workspace236 ws := wv.workspace
237 wv.mu.RUnlock()237 wv.mu.RUnlock()
M internal/ui/controller/tab_controller.go +21 -15
@@ -21,9 +21,8 @@ type TabController struct {
2121 // Callback when tab switch requires content swap
2222 onTabSwitch func(tabID entity.TabID, tab *entity.Tab)
2323
24- ctx context.Context
25- logger *zerolog.Logger
26- mu sync.RWMutex
24+ ctx context.Context
25+ mu sync.RWMutex
2726 }
2827
2928 // NewTabController creates a new controller linking TabList to TabBar.
@@ -33,14 +32,14 @@ func NewTabController(
3332 tabBar *component.TabBar,
3433 tabsUC *usecase.ManageTabsUseCase,
3534 ) *TabController {
36- logger := logging.FromContext(ctx)
35+ log := logging.FromContext(ctx)
36+ log.Debug().Msg("creating tab controller")
3737
3838 tc := &TabController{
3939 tabs: tabs,
4040 tabBar: tabBar,
4141 tabsUC: tabsUC,
4242 ctx: ctx,
43- logger: logger,
4443 }
4544
4645 // Wire tab bar callbacks to controller methods
@@ -61,6 +60,8 @@ func (tc *TabController) SetOnTabSwitch(fn func(tabID entity.TabID, tab *entity.
6160
6261 // handleTabSwitch handles tab button click events from the tab bar.
6362 func (tc *TabController) handleTabSwitch(tabID entity.TabID) {
63+ log := logging.FromContext(tc.ctx)
64+
6465 tc.mu.RLock()
6566 currentActive := tc.tabs.ActiveTabID
6667 tc.mu.RUnlock()
@@ -69,14 +70,14 @@ func (tc *TabController) handleTabSwitch(tabID entity.TabID) {
6970 return // Already active
7071 }
7172
72- tc.logger.Debug().
73+ log.Debug().
7374 Str("from", string(currentActive)).
7475 Str("to", string(tabID)).
7576 Msg("switching tab")
7677
7778 // Use the use case to update domain state
7879 if err := tc.tabsUC.Switch(tc.ctx, tc.tabs, tabID); err != nil {
79- tc.logger.Error().Err(err).Str("tab_id", string(tabID)).Msg("failed to switch tab")
80+ log.Error().Err(err).Str("tab_id", string(tabID)).Msg("failed to switch tab")
8081 return
8182 }
8283
@@ -96,11 +97,12 @@ func (tc *TabController) handleTabSwitch(tabID entity.TabID) {
9697
9798 // handleTabClose handles tab close button click events.
9899 func (tc *TabController) handleTabClose(tabID entity.TabID) {
99- tc.logger.Debug().Str("tab_id", string(tabID)).Msg("closing tab")
100+ log := logging.FromContext(tc.ctx)
101+ log.Debug().Str("tab_id", string(tabID)).Msg("closing tab")
100102
101103 wasLast, err := tc.tabsUC.Close(tc.ctx, tc.tabs, tabID)
102104 if err != nil {
103- tc.logger.Error().Err(err).Str("tab_id", string(tabID)).Msg("failed to close tab")
105+ log.Error().Err(err).Str("tab_id", string(tabID)).Msg("failed to close tab")
104106 return
105107 }
106108
@@ -108,7 +110,7 @@ func (tc *TabController) handleTabClose(tabID entity.TabID) {
108110 tc.tabBar.RemoveTab(tabID)
109111
110112 if wasLast {
111- tc.logger.Info().Msg("last tab closed, application should exit")
113+ log.Info().Msg("last tab closed, application should exit")
112114 // The application should handle this by monitoring tab count
113115 return
114116 }
@@ -134,7 +136,8 @@ func (tc *TabController) handleTabCreate() {
134136
135137 // CreateTab creates a new tab with the given name and URL.
136138 func (tc *TabController) CreateTab(name, url string) *entity.Tab {
137- tc.logger.Debug().
139+ log := logging.FromContext(tc.ctx)
140+ log.Debug().
138141 Str("name", name).
139142 Str("url", url).
140143 Msg("creating new tab")
@@ -145,7 +148,7 @@ func (tc *TabController) CreateTab(name, url string) *entity.Tab {
145148 InitialURL: url,
146149 })
147150 if err != nil {
148- tc.logger.Error().Err(err).Msg("failed to create tab")
151+ log.Error().Err(err).Msg("failed to create tab")
149152 return nil
150153 }
151154
@@ -172,8 +175,9 @@ func (tc *TabController) SwitchToTab(tabID entity.TabID) {
172175
173176 // SwitchToNextTab switches to the next tab.
174177 func (tc *TabController) SwitchToNextTab() {
178+ log := logging.FromContext(tc.ctx)
175179 if err := tc.tabsUC.SwitchNext(tc.ctx, tc.tabs); err != nil {
176- tc.logger.Error().Err(err).Msg("failed to switch to next tab")
180+ log.Error().Err(err).Msg("failed to switch to next tab")
177181 return
178182 }
179183
@@ -192,8 +196,9 @@ func (tc *TabController) SwitchToNextTab() {
192196
193197 // SwitchToPreviousTab switches to the previous tab.
194198 func (tc *TabController) SwitchToPreviousTab() {
199+ log := logging.FromContext(tc.ctx)
195200 if err := tc.tabsUC.SwitchPrevious(tc.ctx, tc.tabs); err != nil {
196- tc.logger.Error().Err(err).Msg("failed to switch to previous tab")
201+ log.Error().Err(err).Msg("failed to switch to previous tab")
197202 return
198203 }
199204
@@ -212,8 +217,9 @@ func (tc *TabController) SwitchToPreviousTab() {
212217
213218 // SwitchToTabByIndex switches to tab at the given 0-based index.
214219 func (tc *TabController) SwitchToTabByIndex(index int) {
220+ log := logging.FromContext(tc.ctx)
215221 if err := tc.tabsUC.SwitchByIndex(tc.ctx, tc.tabs, index); err != nil {
216- tc.logger.Error().Err(err).Int("index", index).Msg("failed to switch to tab by index")
222+ log.Error().Err(err).Int("index", index).Msg("failed to switch to tab by index")
217223 return
218224 }
219225
@@ -21,9 +21,8 @@ type TabController struct {
21 // Callback when tab switch requires content swap21 // Callback when tab switch requires content swap
22 onTabSwitch func(tabID entity.TabID, tab *entity.Tab)22 onTabSwitch func(tabID entity.TabID, tab *entity.Tab)
23 23
24- ctx context.Context24+ ctx context.Context
25- logger *zerolog.Logger25+ mu sync.RWMutex
26- mu sync.RWMutex
27 }26 }
28 27
29 // NewTabController creates a new controller linking TabList to TabBar.28 // NewTabController creates a new controller linking TabList to TabBar.
@@ -33,14 +32,14 @@ func NewTabController(
33 tabBar *component.TabBar,32 tabBar *component.TabBar,
34 tabsUC *usecase.ManageTabsUseCase,33 tabsUC *usecase.ManageTabsUseCase,
35 ) *TabController {34 ) *TabController {
36- logger := logging.FromContext(ctx)35+ log := logging.FromContext(ctx)
36+ log.Debug().Msg("creating tab controller")
37 37
38 tc := &TabController{38 tc := &TabController{
39 tabs: tabs,39 tabs: tabs,
40 tabBar: tabBar,40 tabBar: tabBar,
41 tabsUC: tabsUC,41 tabsUC: tabsUC,
42 ctx: ctx,42 ctx: ctx,
43- logger: logger,
44 }43 }
45 44
46 // Wire tab bar callbacks to controller methods45 // Wire tab bar callbacks to controller methods
@@ -61,6 +60,8 @@ func (tc *TabController) SetOnTabSwitch(fn func(tabID entity.TabID, tab *entity.
61 60
62 // handleTabSwitch handles tab button click events from the tab bar.61 // handleTabSwitch handles tab button click events from the tab bar.
63 func (tc *TabController) handleTabSwitch(tabID entity.TabID) {62 func (tc *TabController) handleTabSwitch(tabID entity.TabID) {
63+ log := logging.FromContext(tc.ctx)
64+
64 tc.mu.RLock()65 tc.mu.RLock()
65 currentActive := tc.tabs.ActiveTabID66 currentActive := tc.tabs.ActiveTabID
66 tc.mu.RUnlock()67 tc.mu.RUnlock()
@@ -69,14 +70,14 @@ func (tc *TabController) handleTabSwitch(tabID entity.TabID) {
69 return // Already active70 return // Already active
70 }71 }
71 72
72- tc.logger.Debug().73+ log.Debug().
73 Str("from", string(currentActive)).74 Str("from", string(currentActive)).
74 Str("to", string(tabID)).75 Str("to", string(tabID)).
75 Msg("switching tab")76 Msg("switching tab")
76 77
77 // Use the use case to update domain state78 // Use the use case to update domain state
78 if err := tc.tabsUC.Switch(tc.ctx, tc.tabs, tabID); err != nil {79 if err := tc.tabsUC.Switch(tc.ctx, tc.tabs, tabID); err != nil {
79- tc.logger.Error().Err(err).Str("tab_id", string(tabID)).Msg("failed to switch tab")80+ log.Error().Err(err).Str("tab_id", string(tabID)).Msg("failed to switch tab")
80 return81 return
81 }82 }
82 83
@@ -96,11 +97,12 @@ func (tc *TabController) handleTabSwitch(tabID entity.TabID) {
96 97
97 // handleTabClose handles tab close button click events.98 // handleTabClose handles tab close button click events.
98 func (tc *TabController) handleTabClose(tabID entity.TabID) {99 func (tc *TabController) handleTabClose(tabID entity.TabID) {
99- tc.logger.Debug().Str("tab_id", string(tabID)).Msg("closing tab")100+ log := logging.FromContext(tc.ctx)
101+ log.Debug().Str("tab_id", string(tabID)).Msg("closing tab")
100 102
101 wasLast, err := tc.tabsUC.Close(tc.ctx, tc.tabs, tabID)103 wasLast, err := tc.tabsUC.Close(tc.ctx, tc.tabs, tabID)
102 if err != nil {104 if err != nil {
103- tc.logger.Error().Err(err).Str("tab_id", string(tabID)).Msg("failed to close tab")105+ log.Error().Err(err).Str("tab_id", string(tabID)).Msg("failed to close tab")
104 return106 return
105 }107 }
106 108
@@ -108,7 +110,7 @@ func (tc *TabController) handleTabClose(tabID entity.TabID) {
108 tc.tabBar.RemoveTab(tabID)110 tc.tabBar.RemoveTab(tabID)
109 111
110 if wasLast {112 if wasLast {
111- tc.logger.Info().Msg("last tab closed, application should exit")113+ log.Info().Msg("last tab closed, application should exit")
112 // The application should handle this by monitoring tab count114 // The application should handle this by monitoring tab count
113 return115 return
114 }116 }
@@ -134,7 +136,8 @@ func (tc *TabController) handleTabCreate() {
134 136
135 // CreateTab creates a new tab with the given name and URL.137 // CreateTab creates a new tab with the given name and URL.
136 func (tc *TabController) CreateTab(name, url string) *entity.Tab {138 func (tc *TabController) CreateTab(name, url string) *entity.Tab {
137- tc.logger.Debug().139+ log := logging.FromContext(tc.ctx)
140+ log.Debug().
138 Str("name", name).141 Str("name", name).
139 Str("url", url).142 Str("url", url).
140 Msg("creating new tab")143 Msg("creating new tab")
@@ -145,7 +148,7 @@ func (tc *TabController) CreateTab(name, url string) *entity.Tab {
145 InitialURL: url,148 InitialURL: url,
146 })149 })
147 if err != nil {150 if err != nil {
148- tc.logger.Error().Err(err).Msg("failed to create tab")151+ log.Error().Err(err).Msg("failed to create tab")
149 return nil152 return nil
150 }153 }
151 154
@@ -172,8 +175,9 @@ func (tc *TabController) SwitchToTab(tabID entity.TabID) {
172 175
173 // SwitchToNextTab switches to the next tab.176 // SwitchToNextTab switches to the next tab.
174 func (tc *TabController) SwitchToNextTab() {177 func (tc *TabController) SwitchToNextTab() {
178+ log := logging.FromContext(tc.ctx)
175 if err := tc.tabsUC.SwitchNext(tc.ctx, tc.tabs); err != nil {179 if err := tc.tabsUC.SwitchNext(tc.ctx, tc.tabs); err != nil {
176- tc.logger.Error().Err(err).Msg("failed to switch to next tab")180+ log.Error().Err(err).Msg("failed to switch to next tab")
177 return181 return
178 }182 }
179 183
@@ -192,8 +196,9 @@ func (tc *TabController) SwitchToNextTab() {
192 196
193 // SwitchToPreviousTab switches to the previous tab.197 // SwitchToPreviousTab switches to the previous tab.
194 func (tc *TabController) SwitchToPreviousTab() {198 func (tc *TabController) SwitchToPreviousTab() {
199+ log := logging.FromContext(tc.ctx)
195 if err := tc.tabsUC.SwitchPrevious(tc.ctx, tc.tabs); err != nil {200 if err := tc.tabsUC.SwitchPrevious(tc.ctx, tc.tabs); err != nil {
196- tc.logger.Error().Err(err).Msg("failed to switch to previous tab")201+ log.Error().Err(err).Msg("failed to switch to previous tab")
197 return202 return
198 }203 }
199 204
@@ -212,8 +217,9 @@ func (tc *TabController) SwitchToPreviousTab() {
212 217
213 // SwitchToTabByIndex switches to tab at the given 0-based index.218 // SwitchToTabByIndex switches to tab at the given 0-based index.
214 func (tc *TabController) SwitchToTabByIndex(index int) {219 func (tc *TabController) SwitchToTabByIndex(index int) {
220+ log := logging.FromContext(tc.ctx)
215 if err := tc.tabsUC.SwitchByIndex(tc.ctx, tc.tabs, index); err != nil {221 if err := tc.tabsUC.SwitchByIndex(tc.ctx, tc.tabs, index); err != nil {
216- tc.logger.Error().Err(err).Int("index", index).Msg("failed to switch to tab by index")222+ log.Error().Err(err).Int("index", index).Msg("failed to switch to tab by index")
217 return223 return
218 }224 }
219 225
M internal/ui/coordinator/content.go +1 -1
@@ -117,7 +117,7 @@ func (c *ContentCoordinator) ReleaseWebView(ctx context.Context, paneID entity.P
117117 c.navOriginMu.Unlock()
118118
119119 if c.pool != nil {
120- c.pool.Release(wv)
120+ c.pool.Release(ctx, wv)
121121 } else {
122122 wv.Destroy()
123123 }
@@ -117,7 +117,7 @@ func (c *ContentCoordinator) ReleaseWebView(ctx context.Context, paneID entity.P
117 c.navOriginMu.Unlock()117 c.navOriginMu.Unlock()
118 118
119 if c.pool != nil {119 if c.pool != nil {
120- c.pool.Release(wv)120+ c.pool.Release(ctx, wv)
121 } else {121 } else {
122 wv.Destroy()122 wv.Destroy()
123 }123 }
M internal/ui/coordinator/workspace.go +4 -4
@@ -131,7 +131,7 @@ func (c *WorkspaceCoordinator) Split(ctx context.Context, direction usecase.Spli
131131 if splitErr != nil {
132132 log.Warn().Err(splitErr).Msg("incremental split failed, falling back to rebuild")
133133 // Fallback to full rebuild
134- if err := wsView.Rebuild(); err != nil {
134+ if err := wsView.Rebuild(ctx); err != nil {
135135 log.Error().Err(err).Msg("failed to rebuild workspace view")
136136 }
137137 c.contentCoord.AttachToWorkspace(ctx, ws, wsView)
@@ -143,7 +143,7 @@ func (c *WorkspaceCoordinator) Split(ctx context.Context, direction usecase.Spli
143143 wsView.FocusPane(ws.ActivePaneID)
144144 } else if wsView != nil {
145145 // No existing widget (shouldn't happen), fallback to rebuild
146- if err := wsView.Rebuild(); err != nil {
146+ if err := wsView.Rebuild(ctx); err != nil {
147147 log.Error().Err(err).Msg("failed to rebuild workspace view")
148148 }
149149 c.contentCoord.AttachToWorkspace(ctx, ws, wsView)
@@ -544,7 +544,7 @@ func (c *WorkspaceCoordinator) ClosePane(ctx context.Context) error {
544544 if closeErr != nil {
545545 log.Warn().Err(closeErr).Msg("incremental close failed, falling back to rebuild")
546546 // Fallback to full rebuild
547- if err := wsView.Rebuild(); err != nil {
547+ if err := wsView.Rebuild(ctx); err != nil {
548548 log.Error().Err(err).Msg("failed to rebuild workspace view")
549549 }
550550 c.contentCoord.ReleaseWebView(ctx, closingPaneID)
@@ -557,7 +557,7 @@ func (c *WorkspaceCoordinator) ClosePane(ctx context.Context) error {
557557 wsView.FocusPane(ws.ActivePaneID)
558558 } else if wsView != nil {
559559 // Fallback to rebuild if we couldn't get context
560- if err := wsView.Rebuild(); err != nil {
560+ if err := wsView.Rebuild(ctx); err != nil {
561561 log.Error().Err(err).Msg("failed to rebuild workspace view")
562562 }
563563 c.contentCoord.ReleaseWebView(ctx, closingPaneID)
@@ -131,7 +131,7 @@ func (c *WorkspaceCoordinator) Split(ctx context.Context, direction usecase.Spli
131 if splitErr != nil {131 if splitErr != nil {
132 log.Warn().Err(splitErr).Msg("incremental split failed, falling back to rebuild")132 log.Warn().Err(splitErr).Msg("incremental split failed, falling back to rebuild")
133 // Fallback to full rebuild133 // Fallback to full rebuild
134- if err := wsView.Rebuild(); err != nil {134+ if err := wsView.Rebuild(ctx); err != nil {
135 log.Error().Err(err).Msg("failed to rebuild workspace view")135 log.Error().Err(err).Msg("failed to rebuild workspace view")
136 }136 }
137 c.contentCoord.AttachToWorkspace(ctx, ws, wsView)137 c.contentCoord.AttachToWorkspace(ctx, ws, wsView)
@@ -143,7 +143,7 @@ func (c *WorkspaceCoordinator) Split(ctx context.Context, direction usecase.Spli
143 wsView.FocusPane(ws.ActivePaneID)143 wsView.FocusPane(ws.ActivePaneID)
144 } else if wsView != nil {144 } else if wsView != nil {
145 // No existing widget (shouldn't happen), fallback to rebuild145 // No existing widget (shouldn't happen), fallback to rebuild
146- if err := wsView.Rebuild(); err != nil {146+ if err := wsView.Rebuild(ctx); err != nil {
147 log.Error().Err(err).Msg("failed to rebuild workspace view")147 log.Error().Err(err).Msg("failed to rebuild workspace view")
148 }148 }
149 c.contentCoord.AttachToWorkspace(ctx, ws, wsView)149 c.contentCoord.AttachToWorkspace(ctx, ws, wsView)
@@ -544,7 +544,7 @@ func (c *WorkspaceCoordinator) ClosePane(ctx context.Context) error {
544 if closeErr != nil {544 if closeErr != nil {
545 log.Warn().Err(closeErr).Msg("incremental close failed, falling back to rebuild")545 log.Warn().Err(closeErr).Msg("incremental close failed, falling back to rebuild")
546 // Fallback to full rebuild546 // Fallback to full rebuild
547- if err := wsView.Rebuild(); err != nil {547+ if err := wsView.Rebuild(ctx); err != nil {
548 log.Error().Err(err).Msg("failed to rebuild workspace view")548 log.Error().Err(err).Msg("failed to rebuild workspace view")
549 }549 }
550 c.contentCoord.ReleaseWebView(ctx, closingPaneID)550 c.contentCoord.ReleaseWebView(ctx, closingPaneID)
@@ -557,7 +557,7 @@ func (c *WorkspaceCoordinator) ClosePane(ctx context.Context) error {
557 wsView.FocusPane(ws.ActivePaneID)557 wsView.FocusPane(ws.ActivePaneID)
558 } else if wsView != nil {558 } else if wsView != nil {
559 // Fallback to rebuild if we couldn't get context559 // Fallback to rebuild if we couldn't get context
560- if err := wsView.Rebuild(); err != nil {560+ if err := wsView.Rebuild(ctx); err != nil {
561 log.Error().Err(err).Msg("failed to rebuild workspace view")561 log.Error().Err(err).Msg("failed to rebuild workspace view")
562 }562 }
563 c.contentCoord.ReleaseWebView(ctx, closingPaneID)563 c.contentCoord.ReleaseWebView(ctx, closingPaneID)

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