feat(config): add resize mode configuration
- commit
- 9631504faadf0064d5283f8e4e17f2a91c43cd5e
- author
- brice · · 2025-12-26 07:03 UTC
- parent
- 35136f8
- signature
- unsigned
3 files · +72 -6
M internal/infrastructure/config/defaults.go +36 -6
| @@ -19,12 +19,16 @@ const ( | |||
| 19 | 19 | defaultOmniboxInitialBehavior = "recent" | |
| 20 | 20 | ||
| 21 | 21 | // Workspace defaults | |
| 22 | - | defaultPaneActivationShortcut = "ctrl+p" | |
| 23 | - | defaultPaneTimeoutMilliseconds = 3000 | |
| 24 | - | defaultTabActivationShortcut = "ctrl+t" | |
| 25 | - | defaultTabTimeoutMilliseconds = 3000 | |
| 26 | - | defaultTabBarPosition = "bottom" | |
| 27 | - | defaultPopupPlacement = "right" | |
| 22 | + | defaultPaneActivationShortcut = "ctrl+p" | |
| 23 | + | defaultPaneTimeoutMilliseconds = 3000 | |
| 24 | + | defaultTabActivationShortcut = "ctrl+t" | |
| 25 | + | defaultTabTimeoutMilliseconds = 3000 | |
| 26 | + | defaultResizeActivationShortcut = "ctrl+n" | |
| 27 | + | defaultResizeTimeoutMilliseconds = 3000 | |
| 28 | + | defaultResizeStepPercent = 5.0 | |
| 29 | + | defaultResizeMinPanePercent = 10.0 | |
| 30 | + | defaultTabBarPosition = "bottom" | |
| 31 | + | defaultPopupPlacement = "right" | |
| 28 | 32 | ||
| 29 | 33 | // Session defaults | |
| 30 | 34 | defaultSessionActivationShortcut = "ctrl+o" | |
| @@ -50,6 +54,10 @@ const ( | |||
| 50 | 54 | defaultSessionModeBorderWidth = 4 | |
| 51 | 55 | defaultSessionModeBorderColor = "#9B59B6" // Purple for session mode indicator | |
| 52 | 56 | ||
| 57 | + | // Resize mode border (Ctrl+N - overlay) | |
| 58 | + | defaultResizeModeBorderWidth = 4 | |
| 59 | + | defaultResizeModeBorderColor = "#00D4AA" // Cyan/teal for resize mode indicator | |
| 60 | + | ||
| 53 | 61 | // Other styling | |
| 54 | 62 | defaultTransitionDuration = 120 | |
| 55 | 63 | defaultUIScale = 1.0 // UI scale multiplier (1.0 = 100%, 1.2 = 120%) | |
| @@ -174,6 +182,26 @@ func DefaultConfig() *Config { | |||
| 174 | 182 | "cancel": {"escape"}, | |
| 175 | 183 | }, | |
| 176 | 184 | }, | |
| 185 | + | ResizeMode: ResizeModeConfig{ | |
| 186 | + | ActivationShortcut: defaultResizeActivationShortcut, | |
| 187 | + | TimeoutMilliseconds: defaultResizeTimeoutMilliseconds, | |
| 188 | + | StepPercent: defaultResizeStepPercent, | |
| 189 | + | MinPanePercent: defaultResizeMinPanePercent, | |
| 190 | + | Actions: map[string][]string{ | |
| 191 | + | "resize-increase-left": {"h", "arrowleft"}, | |
| 192 | + | "resize-increase-down": {"j", "arrowdown"}, | |
| 193 | + | "resize-increase-up": {"k", "arrowup"}, | |
| 194 | + | "resize-increase-right": {"l", "arrowright"}, | |
| 195 | + | "resize-decrease-left": {"H"}, | |
| 196 | + | "resize-decrease-down": {"J"}, | |
| 197 | + | "resize-decrease-up": {"K"}, | |
| 198 | + | "resize-decrease-right": {"L"}, | |
| 199 | + | "resize-increase": {"+", "="}, | |
| 200 | + | "resize-decrease": {"-"}, | |
| 201 | + | "confirm": {"enter"}, | |
| 202 | + | "cancel": {"escape"}, | |
| 203 | + | }, | |
| 204 | + | }, | |
| 177 | 205 | Shortcuts: GlobalShortcutsConfig{ | |
| 178 | 206 | ClosePane: "ctrl+w", | |
| 179 | 207 | NextTab: "ctrl+tab", | |
| @@ -199,6 +227,8 @@ func DefaultConfig() *Config { | |||
| 199 | 227 | TabModeBorderColor: defaultTabModeBorderColor, | |
| 200 | 228 | SessionModeBorderWidth: defaultSessionModeBorderWidth, | |
| 201 | 229 | SessionModeBorderColor: defaultSessionModeBorderColor, | |
| 230 | + | ResizeModeBorderWidth: defaultResizeModeBorderWidth, | |
| 231 | + | ResizeModeBorderColor: defaultResizeModeBorderColor, | |
| 202 | 232 | TransitionDuration: defaultTransitionDuration, | |
| 203 | 233 | }, | |
| 204 | 234 | }, | |
| @@ -19,12 +19,16 @@ const ( | |||||
| 19 | defaultOmniboxInitialBehavior = "recent" | 19 | defaultOmniboxInitialBehavior = "recent" | ||
| 20 | 20 | ||||
| 21 | // Workspace defaults | 21 | // Workspace defaults | ||
| 22 | - | defaultPaneActivationShortcut = "ctrl+p" | 22 | + | defaultPaneActivationShortcut = "ctrl+p" |
| 23 | - | defaultPaneTimeoutMilliseconds = 3000 | 23 | + | defaultPaneTimeoutMilliseconds = 3000 |
| 24 | - | defaultTabActivationShortcut = "ctrl+t" | 24 | + | defaultTabActivationShortcut = "ctrl+t" |
| 25 | - | defaultTabTimeoutMilliseconds = 3000 | 25 | + | defaultTabTimeoutMilliseconds = 3000 |
| 26 | - | defaultTabBarPosition = "bottom" | 26 | + | defaultResizeActivationShortcut = "ctrl+n" |
| 27 | - | defaultPopupPlacement = "right" | 27 | + | defaultResizeTimeoutMilliseconds = 3000 |
| 28 | + | defaultResizeStepPercent = 5.0 | |||
| 29 | + | defaultResizeMinPanePercent = 10.0 | |||
| 30 | + | defaultTabBarPosition = "bottom" | |||
| 31 | + | defaultPopupPlacement = "right" | |||
| 28 | 32 | ||||
| 29 | // Session defaults | 33 | // Session defaults | ||
| 30 | defaultSessionActivationShortcut = "ctrl+o" | 34 | defaultSessionActivationShortcut = "ctrl+o" | ||
| @@ -50,6 +54,10 @@ const ( | |||||
| 50 | defaultSessionModeBorderWidth = 4 | 54 | defaultSessionModeBorderWidth = 4 | ||
| 51 | defaultSessionModeBorderColor = "#9B59B6" // Purple for session mode indicator | 55 | defaultSessionModeBorderColor = "#9B59B6" // Purple for session mode indicator | ||
| 52 | 56 | ||||
| 57 | + | // Resize mode border (Ctrl+N - overlay) | |||
| 58 | + | defaultResizeModeBorderWidth = 4 | |||
| 59 | + | defaultResizeModeBorderColor = "#00D4AA" // Cyan/teal for resize mode indicator | |||
| 60 | + | ||||
| 53 | // Other styling | 61 | // Other styling | ||
| 54 | defaultTransitionDuration = 120 | 62 | defaultTransitionDuration = 120 | ||
| 55 | defaultUIScale = 1.0 // UI scale multiplier (1.0 = 100%, 1.2 = 120%) | 63 | defaultUIScale = 1.0 // UI scale multiplier (1.0 = 100%, 1.2 = 120%) | ||
| @@ -174,6 +182,26 @@ func DefaultConfig() *Config { | |||||
| 174 | "cancel": {"escape"}, | 182 | "cancel": {"escape"}, | ||
| 175 | }, | 183 | }, | ||
| 176 | }, | 184 | }, | ||
| 185 | + | ResizeMode: ResizeModeConfig{ | |||
| 186 | + | ActivationShortcut: defaultResizeActivationShortcut, | |||
| 187 | + | TimeoutMilliseconds: defaultResizeTimeoutMilliseconds, | |||
| 188 | + | StepPercent: defaultResizeStepPercent, | |||
| 189 | + | MinPanePercent: defaultResizeMinPanePercent, | |||
| 190 | + | Actions: map[string][]string{ | |||
| 191 | + | "resize-increase-left": {"h", "arrowleft"}, | |||
| 192 | + | "resize-increase-down": {"j", "arrowdown"}, | |||
| 193 | + | "resize-increase-up": {"k", "arrowup"}, | |||
| 194 | + | "resize-increase-right": {"l", "arrowright"}, | |||
| 195 | + | "resize-decrease-left": {"H"}, | |||
| 196 | + | "resize-decrease-down": {"J"}, | |||
| 197 | + | "resize-decrease-up": {"K"}, | |||
| 198 | + | "resize-decrease-right": {"L"}, | |||
| 199 | + | "resize-increase": {"+", "="}, | |||
| 200 | + | "resize-decrease": {"-"}, | |||
| 201 | + | "confirm": {"enter"}, | |||
| 202 | + | "cancel": {"escape"}, | |||
| 203 | + | }, | |||
| 204 | + | }, | |||
| 177 | Shortcuts: GlobalShortcutsConfig{ | 205 | Shortcuts: GlobalShortcutsConfig{ | ||
| 178 | ClosePane: "ctrl+w", | 206 | ClosePane: "ctrl+w", | ||
| 179 | NextTab: "ctrl+tab", | 207 | NextTab: "ctrl+tab", | ||
| @@ -199,6 +227,8 @@ func DefaultConfig() *Config { | |||||
| 199 | TabModeBorderColor: defaultTabModeBorderColor, | 227 | TabModeBorderColor: defaultTabModeBorderColor, | ||
| 200 | SessionModeBorderWidth: defaultSessionModeBorderWidth, | 228 | SessionModeBorderWidth: defaultSessionModeBorderWidth, | ||
| 201 | SessionModeBorderColor: defaultSessionModeBorderColor, | 229 | SessionModeBorderColor: defaultSessionModeBorderColor, | ||
| 230 | + | ResizeModeBorderWidth: defaultResizeModeBorderWidth, | |||
| 231 | + | ResizeModeBorderColor: defaultResizeModeBorderColor, | |||
| 202 | TransitionDuration: defaultTransitionDuration, | 232 | TransitionDuration: defaultTransitionDuration, | ||
| 203 | }, | 233 | }, | ||
| 204 | }, | 234 | }, | ||
M internal/infrastructure/config/loader.go +7 -0
| @@ -386,6 +386,11 @@ func (m *Manager) setWorkspaceDefaults(defaults *Config) { | |||
| 386 | 386 | m.viper.SetDefault("workspace.tab_mode.activation_shortcut", defaults.Workspace.TabMode.ActivationShortcut) | |
| 387 | 387 | m.viper.SetDefault("workspace.tab_mode.timeout_ms", defaults.Workspace.TabMode.TimeoutMilliseconds) | |
| 388 | 388 | m.viper.SetDefault("workspace.tab_mode.actions", defaults.Workspace.TabMode.Actions) | |
| 389 | + | m.viper.SetDefault("workspace.resize_mode.activation_shortcut", defaults.Workspace.ResizeMode.ActivationShortcut) | |
| 390 | + | m.viper.SetDefault("workspace.resize_mode.timeout_ms", defaults.Workspace.ResizeMode.TimeoutMilliseconds) | |
| 391 | + | m.viper.SetDefault("workspace.resize_mode.step_percent", defaults.Workspace.ResizeMode.StepPercent) | |
| 392 | + | m.viper.SetDefault("workspace.resize_mode.min_pane_percent", defaults.Workspace.ResizeMode.MinPanePercent) | |
| 393 | + | m.viper.SetDefault("workspace.resize_mode.actions", defaults.Workspace.ResizeMode.Actions) | |
| 389 | 394 | m.viper.SetDefault("workspace.shortcuts.close_pane", defaults.Workspace.Shortcuts.ClosePane) | |
| 390 | 395 | m.viper.SetDefault("workspace.shortcuts.next_tab", defaults.Workspace.Shortcuts.NextTab) | |
| 391 | 396 | m.viper.SetDefault("workspace.shortcuts.previous_tab", defaults.Workspace.Shortcuts.PreviousTab) | |
| @@ -406,6 +411,8 @@ func (m *Manager) setWorkspaceDefaults(defaults *Config) { | |||
| 406 | 411 | m.viper.SetDefault("workspace.styling.tab_mode_border_color", defaults.Workspace.Styling.TabModeBorderColor) | |
| 407 | 412 | m.viper.SetDefault("workspace.styling.session_mode_border_width", defaults.Workspace.Styling.SessionModeBorderWidth) | |
| 408 | 413 | m.viper.SetDefault("workspace.styling.session_mode_border_color", defaults.Workspace.Styling.SessionModeBorderColor) | |
| 414 | + | m.viper.SetDefault("workspace.styling.resize_mode_border_width", defaults.Workspace.Styling.ResizeModeBorderWidth) | |
| 415 | + | m.viper.SetDefault("workspace.styling.resize_mode_border_color", defaults.Workspace.Styling.ResizeModeBorderColor) | |
| 409 | 416 | m.viper.SetDefault("workspace.styling.transition_duration", defaults.Workspace.Styling.TransitionDuration) | |
| 410 | 417 | } | |
| 411 | 418 | ||
| @@ -386,6 +386,11 @@ func (m *Manager) setWorkspaceDefaults(defaults *Config) { | |||||
| 386 | m.viper.SetDefault("workspace.tab_mode.activation_shortcut", defaults.Workspace.TabMode.ActivationShortcut) | 386 | m.viper.SetDefault("workspace.tab_mode.activation_shortcut", defaults.Workspace.TabMode.ActivationShortcut) | ||
| 387 | m.viper.SetDefault("workspace.tab_mode.timeout_ms", defaults.Workspace.TabMode.TimeoutMilliseconds) | 387 | m.viper.SetDefault("workspace.tab_mode.timeout_ms", defaults.Workspace.TabMode.TimeoutMilliseconds) | ||
| 388 | m.viper.SetDefault("workspace.tab_mode.actions", defaults.Workspace.TabMode.Actions) | 388 | m.viper.SetDefault("workspace.tab_mode.actions", defaults.Workspace.TabMode.Actions) | ||
| 389 | + | m.viper.SetDefault("workspace.resize_mode.activation_shortcut", defaults.Workspace.ResizeMode.ActivationShortcut) | |||
| 390 | + | m.viper.SetDefault("workspace.resize_mode.timeout_ms", defaults.Workspace.ResizeMode.TimeoutMilliseconds) | |||
| 391 | + | m.viper.SetDefault("workspace.resize_mode.step_percent", defaults.Workspace.ResizeMode.StepPercent) | |||
| 392 | + | m.viper.SetDefault("workspace.resize_mode.min_pane_percent", defaults.Workspace.ResizeMode.MinPanePercent) | |||
| 393 | + | m.viper.SetDefault("workspace.resize_mode.actions", defaults.Workspace.ResizeMode.Actions) | |||
| 389 | m.viper.SetDefault("workspace.shortcuts.close_pane", defaults.Workspace.Shortcuts.ClosePane) | 394 | m.viper.SetDefault("workspace.shortcuts.close_pane", defaults.Workspace.Shortcuts.ClosePane) | ||
| 390 | m.viper.SetDefault("workspace.shortcuts.next_tab", defaults.Workspace.Shortcuts.NextTab) | 395 | m.viper.SetDefault("workspace.shortcuts.next_tab", defaults.Workspace.Shortcuts.NextTab) | ||
| 391 | m.viper.SetDefault("workspace.shortcuts.previous_tab", defaults.Workspace.Shortcuts.PreviousTab) | 396 | m.viper.SetDefault("workspace.shortcuts.previous_tab", defaults.Workspace.Shortcuts.PreviousTab) | ||
| @@ -406,6 +411,8 @@ func (m *Manager) setWorkspaceDefaults(defaults *Config) { | |||||
| 406 | m.viper.SetDefault("workspace.styling.tab_mode_border_color", defaults.Workspace.Styling.TabModeBorderColor) | 411 | m.viper.SetDefault("workspace.styling.tab_mode_border_color", defaults.Workspace.Styling.TabModeBorderColor) | ||
| 407 | m.viper.SetDefault("workspace.styling.session_mode_border_width", defaults.Workspace.Styling.SessionModeBorderWidth) | 412 | m.viper.SetDefault("workspace.styling.session_mode_border_width", defaults.Workspace.Styling.SessionModeBorderWidth) | ||
| 408 | m.viper.SetDefault("workspace.styling.session_mode_border_color", defaults.Workspace.Styling.SessionModeBorderColor) | 413 | m.viper.SetDefault("workspace.styling.session_mode_border_color", defaults.Workspace.Styling.SessionModeBorderColor) | ||
| 414 | + | m.viper.SetDefault("workspace.styling.resize_mode_border_width", defaults.Workspace.Styling.ResizeModeBorderWidth) | |||
| 415 | + | m.viper.SetDefault("workspace.styling.resize_mode_border_color", defaults.Workspace.Styling.ResizeModeBorderColor) | |||
| 409 | m.viper.SetDefault("workspace.styling.transition_duration", defaults.Workspace.Styling.TransitionDuration) | 416 | m.viper.SetDefault("workspace.styling.transition_duration", defaults.Workspace.Styling.TransitionDuration) | ||
| 410 | } | 417 | } | ||
| 411 | 418 | ||||
M internal/infrastructure/config/schema.go +29 -0
| @@ -299,6 +299,8 @@ type WorkspaceConfig struct { | |||
| 299 | 299 | PaneMode PaneModeConfig `mapstructure:"pane_mode" yaml:"pane_mode" toml:"pane_mode" json:"pane_mode"` | |
| 300 | 300 | // TabMode defines modal tab behavior and bindings (Alt+T). | |
| 301 | 301 | TabMode TabModeConfig `mapstructure:"tab_mode" yaml:"tab_mode" toml:"tab_mode" json:"tab_mode"` | |
| 302 | + | // ResizeMode defines modal pane resizing behavior and bindings (Ctrl+N). | |
| 303 | + | ResizeMode ResizeModeConfig `mapstructure:"resize_mode" yaml:"resize_mode" toml:"resize_mode" json:"resize_mode"` | |
| 302 | 304 | // Shortcuts holds global (non-modal) keyboard shortcuts. | |
| 303 | 305 | Shortcuts GlobalShortcutsConfig `mapstructure:"shortcuts" yaml:"shortcuts" toml:"shortcuts" json:"shortcuts"` | |
| 304 | 306 | // TabBarPosition determines tab bar placement: "top" or "bottom". | |
| @@ -349,6 +351,27 @@ func (t *TabModeConfig) GetKeyBindings() map[string]string { | |||
| 349 | 351 | return keyToAction | |
| 350 | 352 | } | |
| 351 | 353 | ||
| 354 | + | // ResizeModeConfig defines modal behavior for resizing panes (Zellij-style). | |
| 355 | + | type ResizeModeConfig struct { | |
| 356 | + | ActivationShortcut string `mapstructure:"activation_shortcut" yaml:"activation_shortcut" toml:"activation_shortcut" json:"activation_shortcut"` //nolint:lll // struct tags must stay on one line | |
| 357 | + | TimeoutMilliseconds int `mapstructure:"timeout_ms" yaml:"timeout_ms" toml:"timeout_ms" json:"timeout_ms"` | |
| 358 | + | StepPercent float64 `mapstructure:"step_percent" yaml:"step_percent" toml:"step_percent" json:"step_percent"` | |
| 359 | + | MinPanePercent float64 `mapstructure:"min_pane_percent" yaml:"min_pane_percent" toml:"min_pane_percent" json:"min_pane_percent"` //nolint:lll // struct tags must stay on one line | |
| 360 | + | Actions map[string][]string `mapstructure:"actions" yaml:"actions" toml:"actions" json:"actions"` | |
| 361 | + | } | |
| 362 | + | ||
| 363 | + | // GetKeyBindings returns an inverted map for O(1) key→action lookup. | |
| 364 | + | // This is built from the action→keys structure in the config. | |
| 365 | + | func (r *ResizeModeConfig) GetKeyBindings() map[string]string { | |
| 366 | + | keyToAction := make(map[string]string) | |
| 367 | + | for action, keys := range r.Actions { | |
| 368 | + | for _, key := range keys { | |
| 369 | + | keyToAction[key] = action | |
| 370 | + | } | |
| 371 | + | } | |
| 372 | + | return keyToAction | |
| 373 | + | } | |
| 374 | + | ||
| 352 | 375 | // GlobalShortcutsConfig defines global shortcuts (always active, not modal). | |
| 353 | 376 | type GlobalShortcutsConfig struct { | |
| 354 | 377 | ClosePane string `mapstructure:"close_pane" yaml:"close_pane" toml:"close_pane" json:"close_pane"` | |
| @@ -422,6 +445,12 @@ type WorkspaceStylingConfig struct { | |||
| 422 | 445 | // Defaults to "#9B59B6" (purple) if not set - MUST be different from other mode colors | |
| 423 | 446 | SessionModeBorderColor string `mapstructure:"session_mode_border_color" yaml:"session_mode_border_color" toml:"session_mode_border_color" json:"session_mode_border_color"` //nolint:lll // struct tags must stay on one line | |
| 424 | 447 | ||
| 448 | + | // ResizeModeBorderWidth in pixels for resize mode indicator border (Ctrl+N overlay) | |
| 449 | + | ResizeModeBorderWidth int `mapstructure:"resize_mode_border_width" yaml:"resize_mode_border_width" toml:"resize_mode_border_width" json:"resize_mode_border_width"` //nolint:lll // struct tags must stay on one line | |
| 450 | + | // ResizeModeBorderColor for the resize mode indicator border (CSS color value or theme variable) | |
| 451 | + | // Defaults to "#00D4AA" (cyan/teal) if not set - MUST be different from other mode colors | |
| 452 | + | ResizeModeBorderColor string `mapstructure:"resize_mode_border_color" yaml:"resize_mode_border_color" toml:"resize_mode_border_color" json:"resize_mode_border_color"` //nolint:lll // struct tags must stay on one line | |
| 453 | + | ||
| 425 | 454 | // TransitionDuration in milliseconds for border animations | |
| 426 | 455 | TransitionDuration int `mapstructure:"transition_duration" yaml:"transition_duration" toml:"transition_duration" json:"transition_duration"` //nolint:lll // struct tags must stay on one line | |
| 427 | 456 | } | |
| @@ -299,6 +299,8 @@ type WorkspaceConfig struct { | |||||
| 299 | PaneMode PaneModeConfig `mapstructure:"pane_mode" yaml:"pane_mode" toml:"pane_mode" json:"pane_mode"` | 299 | PaneMode PaneModeConfig `mapstructure:"pane_mode" yaml:"pane_mode" toml:"pane_mode" json:"pane_mode"` | ||
| 300 | // TabMode defines modal tab behavior and bindings (Alt+T). | 300 | // TabMode defines modal tab behavior and bindings (Alt+T). | ||
| 301 | TabMode TabModeConfig `mapstructure:"tab_mode" yaml:"tab_mode" toml:"tab_mode" json:"tab_mode"` | 301 | TabMode TabModeConfig `mapstructure:"tab_mode" yaml:"tab_mode" toml:"tab_mode" json:"tab_mode"` | ||
| 302 | + | // ResizeMode defines modal pane resizing behavior and bindings (Ctrl+N). | |||
| 303 | + | ResizeMode ResizeModeConfig `mapstructure:"resize_mode" yaml:"resize_mode" toml:"resize_mode" json:"resize_mode"` | |||
| 302 | // Shortcuts holds global (non-modal) keyboard shortcuts. | 304 | // Shortcuts holds global (non-modal) keyboard shortcuts. | ||
| 303 | Shortcuts GlobalShortcutsConfig `mapstructure:"shortcuts" yaml:"shortcuts" toml:"shortcuts" json:"shortcuts"` | 305 | Shortcuts GlobalShortcutsConfig `mapstructure:"shortcuts" yaml:"shortcuts" toml:"shortcuts" json:"shortcuts"` | ||
| 304 | // TabBarPosition determines tab bar placement: "top" or "bottom". | 306 | // TabBarPosition determines tab bar placement: "top" or "bottom". | ||
| @@ -349,6 +351,27 @@ func (t *TabModeConfig) GetKeyBindings() map[string]string { | |||||
| 349 | return keyToAction | 351 | return keyToAction | ||
| 350 | } | 352 | } | ||
| 351 | 353 | ||||
| 354 | + | // ResizeModeConfig defines modal behavior for resizing panes (Zellij-style). | |||
| 355 | + | type ResizeModeConfig struct { | |||
| 356 | + | ActivationShortcut string `mapstructure:"activation_shortcut" yaml:"activation_shortcut" toml:"activation_shortcut" json:"activation_shortcut"` //nolint:lll // struct tags must stay on one line | |||
| 357 | + | TimeoutMilliseconds int `mapstructure:"timeout_ms" yaml:"timeout_ms" toml:"timeout_ms" json:"timeout_ms"` | |||
| 358 | + | StepPercent float64 `mapstructure:"step_percent" yaml:"step_percent" toml:"step_percent" json:"step_percent"` | |||
| 359 | + | MinPanePercent float64 `mapstructure:"min_pane_percent" yaml:"min_pane_percent" toml:"min_pane_percent" json:"min_pane_percent"` //nolint:lll // struct tags must stay on one line | |||
| 360 | + | Actions map[string][]string `mapstructure:"actions" yaml:"actions" toml:"actions" json:"actions"` | |||
| 361 | + | } | |||
| 362 | + | ||||
| 363 | + | // GetKeyBindings returns an inverted map for O(1) key→action lookup. | |||
| 364 | + | // This is built from the action→keys structure in the config. | |||
| 365 | + | func (r *ResizeModeConfig) GetKeyBindings() map[string]string { | |||
| 366 | + | keyToAction := make(map[string]string) | |||
| 367 | + | for action, keys := range r.Actions { | |||
| 368 | + | for _, key := range keys { | |||
| 369 | + | keyToAction[key] = action | |||
| 370 | + | } | |||
| 371 | + | } | |||
| 372 | + | return keyToAction | |||
| 373 | + | } | |||
| 374 | + | ||||
| 352 | // GlobalShortcutsConfig defines global shortcuts (always active, not modal). | 375 | // GlobalShortcutsConfig defines global shortcuts (always active, not modal). | ||
| 353 | type GlobalShortcutsConfig struct { | 376 | type GlobalShortcutsConfig struct { | ||
| 354 | ClosePane string `mapstructure:"close_pane" yaml:"close_pane" toml:"close_pane" json:"close_pane"` | 377 | ClosePane string `mapstructure:"close_pane" yaml:"close_pane" toml:"close_pane" json:"close_pane"` | ||
| @@ -422,6 +445,12 @@ type WorkspaceStylingConfig struct { | |||||
| 422 | // Defaults to "#9B59B6" (purple) if not set - MUST be different from other mode colors | 445 | // Defaults to "#9B59B6" (purple) if not set - MUST be different from other mode colors | ||
| 423 | SessionModeBorderColor string `mapstructure:"session_mode_border_color" yaml:"session_mode_border_color" toml:"session_mode_border_color" json:"session_mode_border_color"` //nolint:lll // struct tags must stay on one line | 446 | SessionModeBorderColor string `mapstructure:"session_mode_border_color" yaml:"session_mode_border_color" toml:"session_mode_border_color" json:"session_mode_border_color"` //nolint:lll // struct tags must stay on one line | ||
| 424 | 447 | ||||
| 448 | + | // ResizeModeBorderWidth in pixels for resize mode indicator border (Ctrl+N overlay) | |||
| 449 | + | ResizeModeBorderWidth int `mapstructure:"resize_mode_border_width" yaml:"resize_mode_border_width" toml:"resize_mode_border_width" json:"resize_mode_border_width"` //nolint:lll // struct tags must stay on one line | |||
| 450 | + | // ResizeModeBorderColor for the resize mode indicator border (CSS color value or theme variable) | |||
| 451 | + | // Defaults to "#00D4AA" (cyan/teal) if not set - MUST be different from other mode colors | |||
| 452 | + | ResizeModeBorderColor string `mapstructure:"resize_mode_border_color" yaml:"resize_mode_border_color" toml:"resize_mode_border_color" json:"resize_mode_border_color"` //nolint:lll // struct tags must stay on one line | |||
| 453 | + | ||||
| 425 | // TransitionDuration in milliseconds for border animations | 454 | // TransitionDuration in milliseconds for border animations | ||
| 426 | TransitionDuration int `mapstructure:"transition_duration" yaml:"transition_duration" toml:"transition_duration" json:"transition_duration"` //nolint:lll // struct tags must stay on one line | 455 | TransitionDuration int `mapstructure:"transition_duration" yaml:"transition_duration" toml:"transition_duration" json:"transition_duration"` //nolint:lll // struct tags must stay on one line | ||
| 427 | } | 456 | } | ||