detached dd428b6

fix(vim): align rebased mode identifiers

commit
dd428b68ad8350894be3a57a79b357f5c7a20a88
author
brice · · 2026-08-13 08:53 UTC
committer
bnema · · 2026-08-14 02:42 UTC
parent
1f4a728
signature
unsigned
3 files · +60 -22
M internal/domain/entity/config_types.go +35 -8
@@ -78,7 +78,7 @@ func (t *TabModeConfig) GetKeyBindings() map[string]string {
7878 return keyBindingsFromActions(t.Actions)
7979 }
8080
81-// VimModeConfig holds page scroll mode shortcut configuration.
81+// VimModeConfig holds vim scroll mode shortcut configuration.
8282 type VimModeConfig struct {
8383 ActivationShortcut string `mapstructure:"activation_shortcut" yaml:"activation_shortcut" toml:"activation_shortcut" json:"activation_shortcut"` //nolint:lll // struct tags must stay on one line
8484 TimeoutMilliseconds int `mapstructure:"timeout_ms" yaml:"timeout_ms" toml:"timeout_ms" json:"timeout_ms"`
@@ -211,15 +211,42 @@ type BrowsingContextConfig struct {
211211 // Deprecated: PopupBehaviorConfig is a compatibility alias for BrowsingContextConfig.
212212 type PopupBehaviorConfig = BrowsingContextConfig
213213
214+// ExternalLinkBehavior defines how externally opened URLs are placed in the workspace.
215+type ExternalLinkBehavior string
216+
217+const (
218+ ExternalLinkBehaviorWindowed ExternalLinkBehavior = "windowed"
219+ ExternalLinkBehaviorTabbed ExternalLinkBehavior = "tabbed"
220+ ExternalLinkBehaviorSplit ExternalLinkBehavior = "split"
221+ ExternalLinkBehaviorStacked ExternalLinkBehavior = "stacked"
222+)
223+
224+// ExternalLinkPlacement defines the direction used when splitting for an external URL.
225+type ExternalLinkPlacement string
226+
227+const (
228+ ExternalLinkPlacementRight ExternalLinkPlacement = "right"
229+ ExternalLinkPlacementLeft ExternalLinkPlacement = "left"
230+ ExternalLinkPlacementTop ExternalLinkPlacement = "top"
231+ ExternalLinkPlacementBottom ExternalLinkPlacement = "bottom"
232+)
233+
234+// ExternalLinksConfig controls how externally opened URLs are placed in the workspace.
235+type ExternalLinksConfig struct {
236+ Behavior ExternalLinkBehavior `mapstructure:"behavior" yaml:"behavior" toml:"behavior" json:"behavior"`
237+ Placement ExternalLinkPlacement `mapstructure:"placement" yaml:"placement" toml:"placement" json:"placement"`
238+}
239+
214240 // WorkspaceConfig holds all workspace layout and behavior settings.
215241 type WorkspaceConfig struct {
216- NewPaneURL string `mapstructure:"new_pane_url" yaml:"new_pane_url" toml:"new_pane_url" json:"new_pane_url"`
217- PaneMode PaneModeConfig `mapstructure:"pane_mode" yaml:"pane_mode" toml:"pane_mode" json:"pane_mode"`
218- TabMode TabModeConfig `mapstructure:"tab_mode" yaml:"tab_mode" toml:"tab_mode" json:"tab_mode"`
219- VimMode VimModeConfig `mapstructure:"vim_mode" yaml:"vim_mode" toml:"vim_mode" json:"vim_mode"`
220- ResizeMode ResizeModeConfig `mapstructure:"resize_mode" yaml:"resize_mode" toml:"resize_mode" json:"resize_mode"`
221- Shortcuts GlobalShortcutsConfig `mapstructure:"shortcuts" yaml:"shortcuts" toml:"shortcuts" json:"shortcuts"`
222- FloatingPane FloatingPaneConfig `mapstructure:"floating_pane" yaml:"floating_pane" toml:"floating_pane" json:"floating_pane"`
242+ NewPaneURL string `mapstructure:"new_pane_url" yaml:"new_pane_url" toml:"new_pane_url" json:"new_pane_url"`
243+ PaneMode PaneModeConfig `mapstructure:"pane_mode" yaml:"pane_mode" toml:"pane_mode" json:"pane_mode"`
244+ TabMode TabModeConfig `mapstructure:"tab_mode" yaml:"tab_mode" toml:"tab_mode" json:"tab_mode"`
245+ VimMode VimModeConfig `mapstructure:"vim_mode" yaml:"vim_mode" toml:"vim_mode" json:"vim_mode"`
246+ ResizeMode ResizeModeConfig `mapstructure:"resize_mode" yaml:"resize_mode" toml:"resize_mode" json:"resize_mode"`
247+ Shortcuts GlobalShortcutsConfig `mapstructure:"shortcuts" yaml:"shortcuts" toml:"shortcuts" json:"shortcuts"`
248+ FloatingPane FloatingPaneConfig `mapstructure:"floating_pane" yaml:"floating_pane" toml:"floating_pane" json:"floating_pane"`
249+ ExternalLinks ExternalLinksConfig `mapstructure:"external_links" yaml:"external_links" toml:"external_links" json:"external_links"`
223250
224251 TabBarPosition string `mapstructure:"tab_bar_position" yaml:"tab_bar_position" toml:"tab_bar_position" json:"tab_bar_position"`
225252 HideTabBarWhenSingleTab bool `mapstructure:"hide_tab_bar_when_single_tab" yaml:"hide_tab_bar_when_single_tab" toml:"hide_tab_bar_when_single_tab" json:"hide_tab_bar_when_single_tab"` //nolint:lll // struct tags must stay on one line
@@ -78,7 +78,7 @@ func (t *TabModeConfig) GetKeyBindings() map[string]string {
78 return keyBindingsFromActions(t.Actions)78 return keyBindingsFromActions(t.Actions)
79 }79 }
80 80
81-// VimModeConfig holds page scroll mode shortcut configuration.81+// VimModeConfig holds vim scroll mode shortcut configuration.
82 type VimModeConfig struct {82 type VimModeConfig struct {
83 ActivationShortcut string `mapstructure:"activation_shortcut" yaml:"activation_shortcut" toml:"activation_shortcut" json:"activation_shortcut"` //nolint:lll // struct tags must stay on one line83 ActivationShortcut string `mapstructure:"activation_shortcut" yaml:"activation_shortcut" toml:"activation_shortcut" json:"activation_shortcut"` //nolint:lll // struct tags must stay on one line
84 TimeoutMilliseconds int `mapstructure:"timeout_ms" yaml:"timeout_ms" toml:"timeout_ms" json:"timeout_ms"`84 TimeoutMilliseconds int `mapstructure:"timeout_ms" yaml:"timeout_ms" toml:"timeout_ms" json:"timeout_ms"`
@@ -211,15 +211,42 @@ type BrowsingContextConfig struct {
211 // Deprecated: PopupBehaviorConfig is a compatibility alias for BrowsingContextConfig.211 // Deprecated: PopupBehaviorConfig is a compatibility alias for BrowsingContextConfig.
212 type PopupBehaviorConfig = BrowsingContextConfig212 type PopupBehaviorConfig = BrowsingContextConfig
213 213
214+// ExternalLinkBehavior defines how externally opened URLs are placed in the workspace.
215+type ExternalLinkBehavior string
216+
217+const (
218+ ExternalLinkBehaviorWindowed ExternalLinkBehavior = "windowed"
219+ ExternalLinkBehaviorTabbed ExternalLinkBehavior = "tabbed"
220+ ExternalLinkBehaviorSplit ExternalLinkBehavior = "split"
221+ ExternalLinkBehaviorStacked ExternalLinkBehavior = "stacked"
222+)
223+
224+// ExternalLinkPlacement defines the direction used when splitting for an external URL.
225+type ExternalLinkPlacement string
226+
227+const (
228+ ExternalLinkPlacementRight ExternalLinkPlacement = "right"
229+ ExternalLinkPlacementLeft ExternalLinkPlacement = "left"
230+ ExternalLinkPlacementTop ExternalLinkPlacement = "top"
231+ ExternalLinkPlacementBottom ExternalLinkPlacement = "bottom"
232+)
233+
234+// ExternalLinksConfig controls how externally opened URLs are placed in the workspace.
235+type ExternalLinksConfig struct {
236+ Behavior ExternalLinkBehavior `mapstructure:"behavior" yaml:"behavior" toml:"behavior" json:"behavior"`
237+ Placement ExternalLinkPlacement `mapstructure:"placement" yaml:"placement" toml:"placement" json:"placement"`
238+}
239+
214 // WorkspaceConfig holds all workspace layout and behavior settings.240 // WorkspaceConfig holds all workspace layout and behavior settings.
215 type WorkspaceConfig struct {241 type WorkspaceConfig struct {
216- NewPaneURL string `mapstructure:"new_pane_url" yaml:"new_pane_url" toml:"new_pane_url" json:"new_pane_url"`242+ NewPaneURL string `mapstructure:"new_pane_url" yaml:"new_pane_url" toml:"new_pane_url" json:"new_pane_url"`
217- PaneMode PaneModeConfig `mapstructure:"pane_mode" yaml:"pane_mode" toml:"pane_mode" json:"pane_mode"`243+ PaneMode PaneModeConfig `mapstructure:"pane_mode" yaml:"pane_mode" toml:"pane_mode" json:"pane_mode"`
218- TabMode TabModeConfig `mapstructure:"tab_mode" yaml:"tab_mode" toml:"tab_mode" json:"tab_mode"`244+ TabMode TabModeConfig `mapstructure:"tab_mode" yaml:"tab_mode" toml:"tab_mode" json:"tab_mode"`
219- VimMode VimModeConfig `mapstructure:"vim_mode" yaml:"vim_mode" toml:"vim_mode" json:"vim_mode"`245+ VimMode VimModeConfig `mapstructure:"vim_mode" yaml:"vim_mode" toml:"vim_mode" json:"vim_mode"`
220- ResizeMode ResizeModeConfig `mapstructure:"resize_mode" yaml:"resize_mode" toml:"resize_mode" json:"resize_mode"`246+ ResizeMode ResizeModeConfig `mapstructure:"resize_mode" yaml:"resize_mode" toml:"resize_mode" json:"resize_mode"`
221- Shortcuts GlobalShortcutsConfig `mapstructure:"shortcuts" yaml:"shortcuts" toml:"shortcuts" json:"shortcuts"`247+ Shortcuts GlobalShortcutsConfig `mapstructure:"shortcuts" yaml:"shortcuts" toml:"shortcuts" json:"shortcuts"`
222- FloatingPane FloatingPaneConfig `mapstructure:"floating_pane" yaml:"floating_pane" toml:"floating_pane" json:"floating_pane"`248+ FloatingPane FloatingPaneConfig `mapstructure:"floating_pane" yaml:"floating_pane" toml:"floating_pane" json:"floating_pane"`
249+ ExternalLinks ExternalLinksConfig `mapstructure:"external_links" yaml:"external_links" toml:"external_links" json:"external_links"`
223 250
224 TabBarPosition string `mapstructure:"tab_bar_position" yaml:"tab_bar_position" toml:"tab_bar_position" json:"tab_bar_position"`251 TabBarPosition string `mapstructure:"tab_bar_position" yaml:"tab_bar_position" toml:"tab_bar_position" json:"tab_bar_position"`
225 HideTabBarWhenSingleTab bool `mapstructure:"hide_tab_bar_when_single_tab" yaml:"hide_tab_bar_when_single_tab" toml:"hide_tab_bar_when_single_tab" json:"hide_tab_bar_when_single_tab"` //nolint:lll // struct tags must stay on one line252 HideTabBarWhenSingleTab bool `mapstructure:"hide_tab_bar_when_single_tab" yaml:"hide_tab_bar_when_single_tab" toml:"hide_tab_bar_when_single_tab" json:"hide_tab_bar_when_single_tab"` //nolint:lll // struct tags must stay on one line
M internal/infrastructure/config/loader.go +17 -6
@@ -175,10 +175,6 @@ func (m *Manager) transformLegacyConfig() {
175175 transformer.TransformLegacyPopupsToBrowsingContexts(rawConfig)
176176 }
177177
178- // Merge newly added default actions into in-memory config so existing persisted
179- // action maps keep working before the user writes a migrated config to disk.
180- configMigrator.mergeMissingDefaultActions(rawConfig)
181-
182178 // Apply transformed config back to viper
183179 for key, value := range rawConfig {
184180 m.viper.Set(key, value)
@@ -378,6 +374,7 @@ func ensureDatabasePath(config *Config) error {
378374 }
379375
380376 func normalizeConfig(config *Config) {
377+ normalizeExternalLinks(config)
381378 normalizeAppearance(config)
382379 normalizeMedia(config)
383380 normalizeEngineConfig(config)
@@ -390,6 +387,20 @@ func normalizeBrowsingContexts(config *Config) {
390387 config.Workspace.Popups = config.Workspace.BrowsingContexts
391388 }
392389
390+func normalizeExternalLinks(config *Config) {
391+ switch config.Workspace.ExternalLinks.Behavior {
392+ case ExternalLinkBehaviorWindowed, ExternalLinkBehaviorTabbed, ExternalLinkBehaviorSplit, ExternalLinkBehaviorStacked:
393+ default:
394+ config.Workspace.ExternalLinks.Behavior = defaultExternalLinkBehavior
395+ }
396+
397+ switch config.Workspace.ExternalLinks.Placement {
398+ case ExternalLinkPlacementRight, ExternalLinkPlacementLeft, ExternalLinkPlacementTop, ExternalLinkPlacementBottom:
399+ default:
400+ config.Workspace.ExternalLinks.Placement = defaultExternalLinkPlacement
401+ }
402+}
403+
393404 func normalizeEngineConfig(config *Config) {
394405 // Normalize GSK renderer (engine.webkit)
395406 switch strings.ToLower(string(config.Engine.WebKit.GSKRenderer)) {
@@ -697,8 +708,6 @@ func (m *Manager) setWorkspaceDefaults(defaults *Config) {
697708 m.viper.SetDefault("workspace.tab_mode.actions", defaults.Workspace.TabMode.Actions)
698709 m.viper.SetDefault("workspace.vim_mode.activation_shortcut", defaults.Workspace.VimMode.ActivationShortcut)
699710 m.viper.SetDefault("workspace.vim_mode.timeout_ms", defaults.Workspace.VimMode.TimeoutMilliseconds)
700- m.viper.SetDefault("workspace.vim_mode.sequence_timeout_ms", defaults.Workspace.VimMode.SequenceTimeoutMilliseconds)
701- m.viper.SetDefault("workspace.vim_mode.preload_accessibility", defaults.Workspace.VimMode.PreloadAccessibility)
702711 m.viper.SetDefault("workspace.vim_mode.actions", defaults.Workspace.VimMode.Actions)
703712 m.viper.SetDefault("workspace.resize_mode.activation_shortcut", defaults.Workspace.ResizeMode.ActivationShortcut)
704713 m.viper.SetDefault("workspace.resize_mode.timeout_ms", defaults.Workspace.ResizeMode.TimeoutMilliseconds)
@@ -709,6 +718,8 @@ func (m *Manager) setWorkspaceDefaults(defaults *Config) {
709718 m.viper.SetDefault("workspace.floating_pane.width_pct", defaults.Workspace.FloatingPane.WidthPct)
710719 m.viper.SetDefault("workspace.floating_pane.height_pct", defaults.Workspace.FloatingPane.HeightPct)
711720 m.viper.SetDefault("workspace.floating_pane.profiles", defaults.Workspace.FloatingPane.Profiles)
721+ m.viper.SetDefault("workspace.external_links.behavior", string(defaults.Workspace.ExternalLinks.Behavior))
722+ m.viper.SetDefault("workspace.external_links.placement", string(defaults.Workspace.ExternalLinks.Placement))
712723 m.viper.SetDefault("workspace.tab_bar_position", defaults.Workspace.TabBarPosition)
713724 m.viper.SetDefault("workspace.hide_tab_bar_when_single_tab", defaults.Workspace.HideTabBarWhenSingleTab)
714725 m.viper.SetDefault("workspace.switch_to_tab_on_move", defaults.Workspace.SwitchToTabOnMove)
@@ -175,10 +175,6 @@ func (m *Manager) transformLegacyConfig() {
175 transformer.TransformLegacyPopupsToBrowsingContexts(rawConfig)175 transformer.TransformLegacyPopupsToBrowsingContexts(rawConfig)
176 }176 }
177 177
178- // Merge newly added default actions into in-memory config so existing persisted
179- // action maps keep working before the user writes a migrated config to disk.
180- configMigrator.mergeMissingDefaultActions(rawConfig)
181-
182 // Apply transformed config back to viper178 // Apply transformed config back to viper
183 for key, value := range rawConfig {179 for key, value := range rawConfig {
184 m.viper.Set(key, value)180 m.viper.Set(key, value)
@@ -378,6 +374,7 @@ func ensureDatabasePath(config *Config) error {
378 }374 }
379 375
380 func normalizeConfig(config *Config) {376 func normalizeConfig(config *Config) {
377+ normalizeExternalLinks(config)
381 normalizeAppearance(config)378 normalizeAppearance(config)
382 normalizeMedia(config)379 normalizeMedia(config)
383 normalizeEngineConfig(config)380 normalizeEngineConfig(config)
@@ -390,6 +387,20 @@ func normalizeBrowsingContexts(config *Config) {
390 config.Workspace.Popups = config.Workspace.BrowsingContexts387 config.Workspace.Popups = config.Workspace.BrowsingContexts
391 }388 }
392 389
390+func normalizeExternalLinks(config *Config) {
391+ switch config.Workspace.ExternalLinks.Behavior {
392+ case ExternalLinkBehaviorWindowed, ExternalLinkBehaviorTabbed, ExternalLinkBehaviorSplit, ExternalLinkBehaviorStacked:
393+ default:
394+ config.Workspace.ExternalLinks.Behavior = defaultExternalLinkBehavior
395+ }
396+
397+ switch config.Workspace.ExternalLinks.Placement {
398+ case ExternalLinkPlacementRight, ExternalLinkPlacementLeft, ExternalLinkPlacementTop, ExternalLinkPlacementBottom:
399+ default:
400+ config.Workspace.ExternalLinks.Placement = defaultExternalLinkPlacement
401+ }
402+}
403+
393 func normalizeEngineConfig(config *Config) {404 func normalizeEngineConfig(config *Config) {
394 // Normalize GSK renderer (engine.webkit)405 // Normalize GSK renderer (engine.webkit)
395 switch strings.ToLower(string(config.Engine.WebKit.GSKRenderer)) {406 switch strings.ToLower(string(config.Engine.WebKit.GSKRenderer)) {
@@ -697,8 +708,6 @@ func (m *Manager) setWorkspaceDefaults(defaults *Config) {
697 m.viper.SetDefault("workspace.tab_mode.actions", defaults.Workspace.TabMode.Actions)708 m.viper.SetDefault("workspace.tab_mode.actions", defaults.Workspace.TabMode.Actions)
698 m.viper.SetDefault("workspace.vim_mode.activation_shortcut", defaults.Workspace.VimMode.ActivationShortcut)709 m.viper.SetDefault("workspace.vim_mode.activation_shortcut", defaults.Workspace.VimMode.ActivationShortcut)
699 m.viper.SetDefault("workspace.vim_mode.timeout_ms", defaults.Workspace.VimMode.TimeoutMilliseconds)710 m.viper.SetDefault("workspace.vim_mode.timeout_ms", defaults.Workspace.VimMode.TimeoutMilliseconds)
700- m.viper.SetDefault("workspace.vim_mode.sequence_timeout_ms", defaults.Workspace.VimMode.SequenceTimeoutMilliseconds)
701- m.viper.SetDefault("workspace.vim_mode.preload_accessibility", defaults.Workspace.VimMode.PreloadAccessibility)
702 m.viper.SetDefault("workspace.vim_mode.actions", defaults.Workspace.VimMode.Actions)711 m.viper.SetDefault("workspace.vim_mode.actions", defaults.Workspace.VimMode.Actions)
703 m.viper.SetDefault("workspace.resize_mode.activation_shortcut", defaults.Workspace.ResizeMode.ActivationShortcut)712 m.viper.SetDefault("workspace.resize_mode.activation_shortcut", defaults.Workspace.ResizeMode.ActivationShortcut)
704 m.viper.SetDefault("workspace.resize_mode.timeout_ms", defaults.Workspace.ResizeMode.TimeoutMilliseconds)713 m.viper.SetDefault("workspace.resize_mode.timeout_ms", defaults.Workspace.ResizeMode.TimeoutMilliseconds)
@@ -709,6 +718,8 @@ func (m *Manager) setWorkspaceDefaults(defaults *Config) {
709 m.viper.SetDefault("workspace.floating_pane.width_pct", defaults.Workspace.FloatingPane.WidthPct)718 m.viper.SetDefault("workspace.floating_pane.width_pct", defaults.Workspace.FloatingPane.WidthPct)
710 m.viper.SetDefault("workspace.floating_pane.height_pct", defaults.Workspace.FloatingPane.HeightPct)719 m.viper.SetDefault("workspace.floating_pane.height_pct", defaults.Workspace.FloatingPane.HeightPct)
711 m.viper.SetDefault("workspace.floating_pane.profiles", defaults.Workspace.FloatingPane.Profiles)720 m.viper.SetDefault("workspace.floating_pane.profiles", defaults.Workspace.FloatingPane.Profiles)
721+ m.viper.SetDefault("workspace.external_links.behavior", string(defaults.Workspace.ExternalLinks.Behavior))
722+ m.viper.SetDefault("workspace.external_links.placement", string(defaults.Workspace.ExternalLinks.Placement))
712 m.viper.SetDefault("workspace.tab_bar_position", defaults.Workspace.TabBarPosition)723 m.viper.SetDefault("workspace.tab_bar_position", defaults.Workspace.TabBarPosition)
713 m.viper.SetDefault("workspace.hide_tab_bar_when_single_tab", defaults.Workspace.HideTabBarWhenSingleTab)724 m.viper.SetDefault("workspace.hide_tab_bar_when_single_tab", defaults.Workspace.HideTabBarWhenSingleTab)
714 m.viper.SetDefault("workspace.switch_to_tab_on_move", defaults.Workspace.SwitchToTabOnMove)725 m.viper.SetDefault("workspace.switch_to_tab_on_move", defaults.Workspace.SwitchToTabOnMove)
M internal/ui/app.go +8 -8
@@ -1100,7 +1100,7 @@ func (a *App) initBrowserWindowInput(ctx context.Context, bw *browserWindow) {
11001100 a.activateBrowserWindow(bw)
11011101 a.handleModeChange(ctx, bw, from, to)
11021102 })
1103- a.bindPageModeSequenceToaster(ctx, bw)
1103+ a.bindVimModeSequenceToaster(ctx, bw)
11041104 bw.keyboardHandler.SetRouteKey(func(kc input.KeyContext) input.KeyRoute {
11051105 if bw.sessionManager != nil && bw.sessionManager.IsVisible() {
11061106 return input.RoutePassToWidget
@@ -4055,9 +4055,9 @@ func (a *App) updateModeIndicatorToaster(ctx context.Context, bw *browserWindow,
40554055 )
40564056 }
40574057
4058-// bindPageModeSequenceToaster wires pending Vim-sequence text onto this
4058+// bindVimModeSequenceToaster wires pending Vim-sequence text onto this
40594059 // window's modeToaster only (never appToaster / pane toasters).
4060-func (a *App) bindPageModeSequenceToaster(ctx context.Context, bw *browserWindow) {
4060+func (a *App) bindVimModeSequenceToaster(ctx context.Context, bw *browserWindow) {
40614061 if a == nil || bw == nil || bw.keyboardHandler == nil {
40624062 return
40634063 }
@@ -4066,7 +4066,7 @@ func (a *App) bindPageModeSequenceToaster(ctx context.Context, bw *browserWindow
40664066 })
40674067 logging.FromContext(ctx).Debug().
40684068 Str("window_id", bw.id).
4069- Msg("page mode pending sequence toaster bound")
4069+ Msg("vim mode pending sequence toaster bound")
40704070 }
40714071
40724072 // showPendingSequence shows "PAGE MODE · pending" on the per-window modeToaster
@@ -4080,24 +4080,24 @@ func (a *App) showPendingSequence(ctx context.Context, bw *browserWindow, pendin
40804080 log := logging.FromContext(ctx)
40814081 if !a.runtimeConfigSnapshot().UI.Workspace.Styling.ModeIndicatorToasterEnabled {
40824082 bw.modeToaster.Hide()
4083- log.Debug().Str("window_id", bw.id).Msg("page mode pending toaster hidden (disabled)")
4083+ log.Debug().Str("window_id", bw.id).Msg("vim mode pending toaster hidden (disabled)")
40844084 return
40854085 }
40864086
4087- text := input.ModePage.DisplayName()
4087+ text := input.ModeVim.DisplayName()
40884088 if pending != "" {
40894089 text = text + " · " + pending
40904090 }
40914091 bw.modeToaster.Show(ctx, text, component.ToastInfo,
40924092 component.WithDuration(0),
40934093 component.WithPosition(component.ToastPositionBottomLeft),
4094- component.WithModeClass(getModeToastClass(input.ModePage)),
4094+ component.WithModeClass(getModeToastClass(input.ModeVim)),
40954095 )
40964096 log.Debug().
40974097 Str("window_id", bw.id).
40984098 Str("pending", pending).
40994099 Str("toast_text", text).
4100- Msg("page mode pending toaster updated")
4100+ Msg("vim mode pending toaster updated")
41014101 }
41024102
41034103 // getModeToastClass returns the CSS class for the given mode's toast styling.
@@ -1100,7 +1100,7 @@ func (a *App) initBrowserWindowInput(ctx context.Context, bw *browserWindow) {
1100 a.activateBrowserWindow(bw)1100 a.activateBrowserWindow(bw)
1101 a.handleModeChange(ctx, bw, from, to)1101 a.handleModeChange(ctx, bw, from, to)
1102 })1102 })
1103- a.bindPageModeSequenceToaster(ctx, bw)1103+ a.bindVimModeSequenceToaster(ctx, bw)
1104 bw.keyboardHandler.SetRouteKey(func(kc input.KeyContext) input.KeyRoute {1104 bw.keyboardHandler.SetRouteKey(func(kc input.KeyContext) input.KeyRoute {
1105 if bw.sessionManager != nil && bw.sessionManager.IsVisible() {1105 if bw.sessionManager != nil && bw.sessionManager.IsVisible() {
1106 return input.RoutePassToWidget1106 return input.RoutePassToWidget
@@ -4055,9 +4055,9 @@ func (a *App) updateModeIndicatorToaster(ctx context.Context, bw *browserWindow,
4055 )4055 )
4056 }4056 }
4057 4057
4058-// bindPageModeSequenceToaster wires pending Vim-sequence text onto this4058+// bindVimModeSequenceToaster wires pending Vim-sequence text onto this
4059 // window's modeToaster only (never appToaster / pane toasters).4059 // window's modeToaster only (never appToaster / pane toasters).
4060-func (a *App) bindPageModeSequenceToaster(ctx context.Context, bw *browserWindow) {4060+func (a *App) bindVimModeSequenceToaster(ctx context.Context, bw *browserWindow) {
4061 if a == nil || bw == nil || bw.keyboardHandler == nil {4061 if a == nil || bw == nil || bw.keyboardHandler == nil {
4062 return4062 return
4063 }4063 }
@@ -4066,7 +4066,7 @@ func (a *App) bindPageModeSequenceToaster(ctx context.Context, bw *browserWindow
4066 })4066 })
4067 logging.FromContext(ctx).Debug().4067 logging.FromContext(ctx).Debug().
4068 Str("window_id", bw.id).4068 Str("window_id", bw.id).
4069- Msg("page mode pending sequence toaster bound")4069+ Msg("vim mode pending sequence toaster bound")
4070 }4070 }
4071 4071
4072 // showPendingSequence shows "PAGE MODE · pending" on the per-window modeToaster4072 // showPendingSequence shows "PAGE MODE · pending" on the per-window modeToaster
@@ -4080,24 +4080,24 @@ func (a *App) showPendingSequence(ctx context.Context, bw *browserWindow, pendin
4080 log := logging.FromContext(ctx)4080 log := logging.FromContext(ctx)
4081 if !a.runtimeConfigSnapshot().UI.Workspace.Styling.ModeIndicatorToasterEnabled {4081 if !a.runtimeConfigSnapshot().UI.Workspace.Styling.ModeIndicatorToasterEnabled {
4082 bw.modeToaster.Hide()4082 bw.modeToaster.Hide()
4083- log.Debug().Str("window_id", bw.id).Msg("page mode pending toaster hidden (disabled)")4083+ log.Debug().Str("window_id", bw.id).Msg("vim mode pending toaster hidden (disabled)")
4084 return4084 return
4085 }4085 }
4086 4086
4087- text := input.ModePage.DisplayName()4087+ text := input.ModeVim.DisplayName()
4088 if pending != "" {4088 if pending != "" {
4089 text = text + " · " + pending4089 text = text + " · " + pending
4090 }4090 }
4091 bw.modeToaster.Show(ctx, text, component.ToastInfo,4091 bw.modeToaster.Show(ctx, text, component.ToastInfo,
4092 component.WithDuration(0),4092 component.WithDuration(0),
4093 component.WithPosition(component.ToastPositionBottomLeft),4093 component.WithPosition(component.ToastPositionBottomLeft),
4094- component.WithModeClass(getModeToastClass(input.ModePage)),4094+ component.WithModeClass(getModeToastClass(input.ModeVim)),
4095 )4095 )
4096 log.Debug().4096 log.Debug().
4097 Str("window_id", bw.id).4097 Str("window_id", bw.id).
4098 Str("pending", pending).4098 Str("pending", pending).
4099 Str("toast_text", text).4099 Str("toast_text", text).
4100- Msg("page mode pending toaster updated")4100+ Msg("vim mode pending toaster updated")
4101 }4101 }
4102 4102
4103 // getModeToastClass returns the CSS class for the given mode's toast styling.4103 // getModeToastClass returns the CSS class for the given mode's toast styling.

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