@@ -82,65 +82,152 @@ export class KittyParserService {
8282 }
8383
8484 private parseKeyValue ( config : KittyConfigAST , key : string , value : string ) : void {
85- if ( key === 'map' ) {
86- const parts = value . split ( / \s + / ) ;
87- if ( parts . length >= 2 && parts [ 0 ] ) {
88- config . keyboard_shortcuts . push ( {
89- chord : parts [ 0 ] ,
90- action : parts . slice ( 1 ) . join ( ' ' )
91- } ) ;
92- }
85+ if ( this . handleSpecialKeys ( config , key , value ) ) {
9386 return ;
9487 }
88+
89+ this . routeToConfigSection ( config , key , value ) ;
90+ }
91+
92+ private handleSpecialKeys ( config : KittyConfigAST , key : string , value : string ) : boolean {
93+ if ( key === 'map' ) {
94+ this . parseKeyboardShortcut ( config , value ) ;
95+ return true ;
96+ }
9597
9698 if ( key === 'mouse_map' ) {
97- const parts = value . split ( / \s + / ) ;
98- if ( parts . length >= 4 && parts [ 0 ] && parts [ 1 ] && parts [ 2 ] ) {
99- config . mouse_mappings . push ( {
100- button : parts [ 0 ] ,
101- event : parts [ 1 ] ,
102- modes : parts [ 2 ] ,
103- action : parts . slice ( 3 ) . join ( ' ' )
104- } ) ;
105- }
106- return ;
99+ this . parseMouseMapping ( config , value ) ;
100+ return true ;
107101 }
108102
109103 if ( key === 'env' ) {
110- const eqIdx = value . indexOf ( '=' ) ;
111- if ( eqIdx > 0 ) {
112- const envKey = value . slice ( 0 , eqIdx ) . trim ( ) ;
113- const envVal = value . slice ( eqIdx + 1 ) ;
114- config . advanced . env [ envKey ] = envVal ;
115- }
116- return ;
104+ this . parseEnvironmentVariable ( config , value ) ;
105+ return true ;
117106 }
118107
119- if ( key . startsWith ( 'font_' ) || key === 'symbol_map' || key === 'narrow_symbols' || key === 'disable_ligatures' || key === 'force_ltr' || key === 'box_drawing_scale' || key === 'undercurl_style' || key === 'underline_exclusion' || key === 'text_composition_strategy' || key === 'text_fg_override_threshold' || key === 'modify_font' || key === 'bold_font' || key === 'italic_font' || key === 'bold_italic_font' ) {
108+ return false ;
109+ }
110+
111+ private parseKeyboardShortcut ( config : KittyConfigAST , value : string ) : void {
112+ const parts = value . split ( / \s + / ) ;
113+ if ( parts . length >= 2 && parts [ 0 ] ) {
114+ config . keyboard_shortcuts . push ( {
115+ chord : parts [ 0 ] ,
116+ action : parts . slice ( 1 ) . join ( ' ' )
117+ } ) ;
118+ }
119+ }
120+
121+ private parseMouseMapping ( config : KittyConfigAST , value : string ) : void {
122+ const parts = value . split ( / \s + / ) ;
123+ if ( parts . length >= 4 && parts [ 0 ] && parts [ 1 ] && parts [ 2 ] ) {
124+ config . mouse_mappings . push ( {
125+ button : parts [ 0 ] ,
126+ event : parts [ 1 ] ,
127+ modes : parts [ 2 ] ,
128+ action : parts . slice ( 3 ) . join ( ' ' )
129+ } ) ;
130+ }
131+ }
132+
133+ private parseEnvironmentVariable ( config : KittyConfigAST , value : string ) : void {
134+ const eqIdx = value . indexOf ( '=' ) ;
135+ if ( eqIdx > 0 ) {
136+ const envKey = value . slice ( 0 , eqIdx ) . trim ( ) ;
137+ const envVal = value . slice ( eqIdx + 1 ) ;
138+ config . advanced . env [ envKey ] = envVal ;
139+ }
140+ }
141+
142+ private routeToConfigSection ( config : KittyConfigAST , key : string , value : string ) : void {
143+ if ( this . isFontKey ( key ) ) {
120144 this . parseFontConfig ( config , key , value ) ;
121- } else if ( key . startsWith ( 'cursor_' ) || key === 'cursor' ) {
145+ } else if ( this . isCursorKey ( key ) ) {
122146 this . parseCursorConfig ( config , key , value ) ;
123- } else if ( key . startsWith ( 'scrollback_' ) || key === 'wheel_scroll_multiplier' || key === 'wheel_scroll_min_lines' || key === 'touch_scroll_multiplier' ) {
147+ } else if ( this . isScrollbackKey ( key ) ) {
124148 this . parseScrollbackConfig ( config , key , value ) ;
125- } else if ( key === 'mouse_hide_wait' || key === 'url_color' || key === 'url_style' || key === 'url_prefixes' || key === 'open_url_with' || key === 'detect_urls' || key === 'show_hyperlink_targets' || key === 'underline_hyperlinks' || key === 'copy_on_select' || key === 'paste_actions' || key === 'strip_trailing_spaces' || key === 'select_by_word_characters' || key === 'select_by_word_characters_forward' || key === 'click_interval' || key === 'focus_follows_mouse' || key . startsWith ( 'pointer_shape' ) || key === 'default_pointer_shape' ) {
149+ } else if ( this . isMouseKey ( key ) ) {
126150 this . parseMouseConfig ( config , key , value ) ;
127- } else if ( key === 'repaint_delay' || key === 'input_delay' || key === 'sync_to_monitor' ) {
151+ } else if ( this . isPerformanceKey ( key ) ) {
128152 this . parsePerformanceConfig ( config , key , value ) ;
129- } else if ( key === 'enable_audio_bell' || key === 'visual_bell_duration' || key === 'visual_bell_color' || key === 'window_alert_on_bell' || key === 'bell_on_tab' || key === 'command_on_bell' || key === 'bell_path' || key === 'linux_bell_theme' ) {
153+ } else if ( this . isBellKey ( key ) ) {
130154 this . parseBellConfig ( config , key , value ) ;
131- } else if ( key === 'remember_window_size' || key === 'initial_window_width' || key === 'initial_window_height' || key === 'enabled_layouts' || key === 'placement_strategy' || key === 'hide_window_decorations' || key === 'window_border_width' || key === 'window_margin_width' || key === 'single_window_margin_width' || key === 'window_padding_width' || key === 'active_border_color' || key === 'inactive_border_color' || key === 'bell_border_color' || key === 'inactive_text_alpha' || key === 'draw_minimal_borders' || key === 'window_resize_step_cells' || key === 'window_resize_step_lines' || key === 'confirm_os_window_close' || key === 'window_logo_path' || key === 'window_logo_position' || key === 'window_logo_alpha' || key === 'resize_debounce_time' || key === 'resize_in_steps' || key === 'visual_window_select_characters' ) {
155+ } else if ( this . isWindowLayoutKey ( key ) ) {
132156 this . parseWindowLayoutConfig ( config , key , value ) ;
133- } else if ( key . startsWith ( 'tab_' ) || key === 'active_tab_foreground' || key === 'active_tab_background' || key === 'active_tab_font_style' || key === 'inactive_tab_foreground' || key === 'inactive_tab_background' || key === 'inactive_tab_font_style' ) {
157+ } else if ( this . isTabBarKey ( key ) ) {
134158 this . parseTabBarConfig ( config , key , value ) ;
135- } else if ( key . startsWith ( 'color' ) || key === 'foreground' || key === 'background' || key === 'background_opacity' || key === 'background_blur' || key === 'background_image' || key === 'background_image_layout' || key === 'background_image_linear' || key === 'background_tint' || key === 'background_tint_gaps' || key === 'dim_opacity' || key === 'selection_foreground' || key === 'selection_background' || key . startsWith ( 'mark' ) ) {
159+ } else if ( this . isColorKey ( key ) ) {
136160 this . parseColorConfig ( config , key , value ) ;
137- } else if ( key . startsWith ( 'macos_' ) || key . startsWith ( 'wayland_' ) || key . startsWith ( 'linux_' ) ) {
161+ } else if ( this . isOSSpecificKey ( key ) ) {
138162 this . parseOSSpecificConfig ( config , key , value ) ;
139163 } else {
140164 this . parseAdvancedConfig ( config , key , value ) ;
141165 }
142166 }
143167
168+ private isFontKey ( key : string ) : boolean {
169+ return key . startsWith ( 'font_' ) || [ 'symbol_map' , 'narrow_symbols' , 'disable_ligatures' ,
170+ 'force_ltr' , 'box_drawing_scale' , 'undercurl_style' , 'underline_exclusion' ,
171+ 'text_composition_strategy' , 'text_fg_override_threshold' , 'modify_font' ,
172+ 'bold_font' , 'italic_font' , 'bold_italic_font' ] . includes ( key ) ;
173+ }
174+
175+ private isCursorKey ( key : string ) : boolean {
176+ return key . startsWith ( 'cursor_' ) || key === 'cursor' ;
177+ }
178+
179+ private isScrollbackKey ( key : string ) : boolean {
180+ return key . startsWith ( 'scrollback_' ) || [ 'wheel_scroll_multiplier' ,
181+ 'wheel_scroll_min_lines' , 'touch_scroll_multiplier' ] . includes ( key ) ;
182+ }
183+
184+ private isMouseKey ( key : string ) : boolean {
185+ return [ 'mouse_hide_wait' , 'url_color' , 'url_style' , 'url_prefixes' , 'open_url_with' ,
186+ 'detect_urls' , 'show_hyperlink_targets' , 'underline_hyperlinks' , 'copy_on_select' ,
187+ 'paste_actions' , 'strip_trailing_spaces' , 'select_by_word_characters' ,
188+ 'select_by_word_characters_forward' , 'click_interval' , 'focus_follows_mouse' ,
189+ 'default_pointer_shape' ] . includes ( key ) || key . startsWith ( 'pointer_shape' ) ;
190+ }
191+
192+ private isPerformanceKey ( key : string ) : boolean {
193+ return [ 'repaint_delay' , 'input_delay' , 'sync_to_monitor' ] . includes ( key ) ;
194+ }
195+
196+ private isBellKey ( key : string ) : boolean {
197+ return [ 'enable_audio_bell' , 'visual_bell_duration' , 'visual_bell_color' ,
198+ 'window_alert_on_bell' , 'bell_on_tab' , 'command_on_bell' , 'bell_path' ,
199+ 'linux_bell_theme' ] . includes ( key ) ;
200+ }
201+
202+ private isWindowLayoutKey ( key : string ) : boolean {
203+ return [ 'remember_window_size' , 'initial_window_width' , 'initial_window_height' ,
204+ 'enabled_layouts' , 'placement_strategy' , 'hide_window_decorations' ,
205+ 'window_border_width' , 'window_margin_width' , 'single_window_margin_width' ,
206+ 'window_padding_width' , 'active_border_color' , 'inactive_border_color' ,
207+ 'bell_border_color' , 'inactive_text_alpha' , 'draw_minimal_borders' ,
208+ 'window_resize_step_cells' , 'window_resize_step_lines' , 'confirm_os_window_close' ,
209+ 'window_logo_path' , 'window_logo_position' , 'window_logo_alpha' ,
210+ 'resize_debounce_time' , 'resize_in_steps' , 'visual_window_select_characters' ] . includes ( key ) ;
211+ }
212+
213+ private isTabBarKey ( key : string ) : boolean {
214+ return key . startsWith ( 'tab_' ) || [ 'active_tab_foreground' , 'active_tab_background' ,
215+ 'active_tab_font_style' , 'inactive_tab_foreground' , 'inactive_tab_background' ,
216+ 'inactive_tab_font_style' ] . includes ( key ) ;
217+ }
218+
219+ private isColorKey ( key : string ) : boolean {
220+ return key . startsWith ( 'color' ) || key . startsWith ( 'mark' ) ||
221+ [ 'foreground' , 'background' , 'background_opacity' , 'background_blur' ,
222+ 'background_image' , 'background_image_layout' , 'background_image_linear' ,
223+ 'background_tint' , 'background_tint_gaps' , 'dim_opacity' ,
224+ 'selection_foreground' , 'selection_background' ] . includes ( key ) ;
225+ }
226+
227+ private isOSSpecificKey ( key : string ) : boolean {
228+ return key . startsWith ( 'macos_' ) || key . startsWith ( 'wayland_' ) || key . startsWith ( 'linux_' ) ;
229+ }
230+
144231 private parseFontConfig ( config : KittyConfigAST , key : string , value : string ) : void {
145232 switch ( key ) {
146233 case 'font_family' :
0 commit comments