-
Notifications
You must be signed in to change notification settings - Fork 644
/
Copy pathConfig.zig
6883 lines (6124 loc) · 255 KB
/
Config.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/// Config is the main config struct. These fields map directly to the
/// CLI flag names hence we use a lot of `@""` syntax to support hyphens.
// Pandoc is used to automatically generate manual pages and other forms of
// documentation, so documentation comments on fields in the Config struct
// should use Pandoc's flavor of Markdown.
//
// For a reference to Pandoc's Markdown see their [online
// manual.](https://pandoc.org/MANUAL.html#pandocs-markdown)
const Config = @This();
const std = @import("std");
const builtin = @import("builtin");
const build_config = @import("../build_config.zig");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
const global_state = &@import("../global.zig").state;
const fontpkg = @import("../font/main.zig");
const inputpkg = @import("../input.zig");
const terminal = @import("../terminal/main.zig");
const internal_os = @import("../os/main.zig");
const cli = @import("../cli.zig");
const Command = @import("../Command.zig");
const conditional = @import("conditional.zig");
const Conditional = conditional.Conditional;
const formatterpkg = @import("formatter.zig");
const themepkg = @import("theme.zig");
const url = @import("url.zig");
const Key = @import("key.zig").Key;
const KeyValue = @import("key.zig").Value;
const ErrorList = @import("ErrorList.zig");
const MetricModifier = fontpkg.Metrics.Modifier;
const help_strings = @import("help_strings");
const log = std.log.scoped(.config);
/// Used on Unixes for some defaults.
const c = @cImport({
@cInclude("unistd.h");
});
/// Renamed fields, used by cli.parse
pub const renamed = std.StaticStringMap([]const u8).initComptime(&.{
// Ghostty 1.1 introduced background-blur support for Linux which
// doesn't support a specific radius value. The renaming is to let
// one field be used for both platforms (macOS retained the ability
// to set a radius).
.{ "background-blur-radius", "background-blur" },
});
/// The font families to use.
///
/// You can generate the list of valid values using the CLI:
///
/// ghostty +list-fonts
///
/// This configuration can be repeated multiple times to specify preferred
/// fallback fonts when the requested codepoint is not available in the primary
/// font. This is particularly useful for multiple languages, symbolic fonts,
/// etc.
///
/// Notes on emoji specifically: On macOS, Ghostty by default will always use
/// Apple Color Emoji and on Linux will always use Noto Emoji. You can
/// override this behavior by specifying a font family here that contains
/// emoji glyphs.
///
/// The specific styles (bold, italic, bold italic) do not need to be
/// explicitly set. If a style is not set, then the regular style (font-family)
/// will be searched for stylistic variants. If a stylistic variant is not
/// found, Ghostty will use the regular style. This prevents falling back to a
/// different font family just to get a style such as bold. This also applies
/// if you explicitly specify a font family for a style. For example, if you
/// set `font-family-bold = FooBar` and "FooBar" cannot be found, Ghostty will
/// use whatever font is set for `font-family` for the bold style.
///
/// Finally, some styles may be synthesized if they are not supported.
/// For example, if a font does not have an italic style and no alternative
/// italic font is specified, Ghostty will synthesize an italic style by
/// applying a slant to the regular style. If you want to disable these
/// synthesized styles then you can use the `font-style` configurations
/// as documented below.
///
/// You can disable styles completely by using the `font-style` set of
/// configurations. See the documentation for `font-style` for more information.
///
/// If you want to overwrite a previous set value rather than append a fallback,
/// specify the value as `""` (empty string) to reset the list and then set the
/// new values. For example:
///
/// font-family = ""
/// font-family = "My Favorite Font"
///
/// Setting any of these as CLI arguments will automatically clear the
/// values set in configuration files so you don't need to specify
/// `--font-family=""` before setting a new value. You only need to specify
/// this within config files if you want to clear previously set values in
/// configuration files or on the CLI if you want to clear values set on the
/// CLI.
///
/// Changing this configuration at runtime will only affect new terminals, i.e.
/// new windows, tabs, etc.
@"font-family": RepeatableString = .{},
@"font-family-bold": RepeatableString = .{},
@"font-family-italic": RepeatableString = .{},
@"font-family-bold-italic": RepeatableString = .{},
/// The named font style to use for each of the requested terminal font styles.
/// This looks up the style based on the font style string advertised by the
/// font itself. For example, "Iosevka Heavy" has a style of "Heavy".
///
/// You can also use these fields to completely disable a font style. If you set
/// the value of the configuration below to literal `false` then that font style
/// will be disabled. If the running program in the terminal requests a disabled
/// font style, the regular font style will be used instead.
///
/// These are only valid if its corresponding font-family is also specified. If
/// no font-family is specified, then the font-style is ignored unless you're
/// disabling the font style.
@"font-style": FontStyle = .{ .default = {} },
@"font-style-bold": FontStyle = .{ .default = {} },
@"font-style-italic": FontStyle = .{ .default = {} },
@"font-style-bold-italic": FontStyle = .{ .default = {} },
/// Control whether Ghostty should synthesize a style if the requested style is
/// not available in the specified font-family.
///
/// Ghostty can synthesize bold, italic, and bold italic styles if the font
/// does not have a specific style. For bold, this is done by drawing an
/// outline around the glyph of varying thickness. For italic, this is done by
/// applying a slant to the glyph. For bold italic, both of these are applied.
///
/// Synthetic styles are not perfect and will generally not look as good
/// as a font that has the style natively. However, they are useful to
/// provide styled text when the font does not have the style.
///
/// Set this to "false" or "true" to disable or enable synthetic styles
/// completely. You can disable specific styles using "no-bold", "no-italic",
/// and "no-bold-italic". You can disable multiple styles by separating them
/// with a comma. For example, "no-bold,no-italic".
///
/// Available style keys are: `bold`, `italic`, `bold-italic`.
///
/// If synthetic styles are disabled, then the regular style will be used
/// instead if the requested style is not available. If the font has the
/// requested style, then the font will be used as-is since the style is
/// not synthetic.
///
/// Warning: An easy mistake is to disable `bold` or `italic` but not
/// `bold-italic`. Disabling only `bold` or `italic` will NOT disable either
/// in the `bold-italic` style. If you want to disable `bold-italic`, you must
/// explicitly disable it. You cannot partially disable `bold-italic`.
///
/// By default, synthetic styles are enabled.
@"font-synthetic-style": FontSyntheticStyle = .{},
/// Apply a font feature. To enable multiple font features you can repeat
/// this multiple times or use a comma-separated list of feature settings.
///
/// The syntax for feature settings is as follows, where `feat` is a feature:
///
/// * Enable features with e.g. `feat`, `+feat`, `feat on`, `feat=1`.
/// * Disabled features with e.g. `-feat`, `feat off`, `feat=0`.
/// * Set a feature value with e.g. `feat=2`, `feat = 3`, `feat 4`.
/// * Feature names may be wrapped in quotes, meaning this config should be
/// syntactically compatible with the `font-feature-settings` CSS property.
///
/// The syntax is fairly loose, but invalid settings will be silently ignored.
///
/// The font feature will apply to all fonts rendered by Ghostty. A future
/// enhancement will allow targeting specific faces.
///
/// To disable programming ligatures, use `-calt` since this is the typical
/// feature name for programming ligatures. To look into what font features
/// your font has and what they do, use a font inspection tool such as
/// [fontdrop.info](https://fontdrop.info).
///
/// To generally disable most ligatures, use `-calt, -liga, -dlig`.
@"font-feature": RepeatableString = .{},
/// Font size in points. This value can be a non-integer and the nearest integer
/// pixel size will be selected. If you have a high dpi display where 1pt = 2px
/// then you can get an odd numbered pixel size by specifying a half point.
///
/// For example, 13.5pt @ 2px/pt = 27px
///
/// Changing this configuration at runtime will only affect new terminals,
/// i.e. new windows, tabs, etc. Note that you may still not see the change
/// depending on your `window-inherit-font-size` setting. If that setting is
/// true, only the first window will be affected by this change since all
/// subsequent windows will inherit the font size of the previous window.
///
/// On Linux with GTK, font size is scaled according to both display-wide and
/// text-specific scaling factors, which are often managed by your desktop
/// environment (e.g. the GNOME display scale and large text settings).
@"font-size": f32 = switch (builtin.os.tag) {
// On macOS we default a little bigger since this tends to look better. This
// is purely subjective but this is easy to modify.
.macos => 13,
else => 12,
},
/// A repeatable configuration to set one or more font variations values for
/// a variable font. A variable font is a single font, usually with a filename
/// ending in `-VF.ttf` or `-VF.otf` that contains one or more configurable axes
/// for things such as weight, slant, etc. Not all fonts support variations;
/// only fonts that explicitly state they are variable fonts will work.
///
/// The format of this is `id=value` where `id` is the axis identifier. An axis
/// identifier is always a 4 character string, such as `wght`. To get the list
/// of supported axes, look at your font documentation or use a font inspection
/// tool.
///
/// Invalid ids and values are usually ignored. For example, if a font only
/// supports weights from 100 to 700, setting `wght=800` will do nothing (it
/// will not be clamped to 700). You must consult your font's documentation to
/// see what values are supported.
///
/// Common axes are: `wght` (weight), `slnt` (slant), `ital` (italic), `opsz`
/// (optical size), `wdth` (width), `GRAD` (gradient), etc.
@"font-variation": RepeatableFontVariation = .{},
@"font-variation-bold": RepeatableFontVariation = .{},
@"font-variation-italic": RepeatableFontVariation = .{},
@"font-variation-bold-italic": RepeatableFontVariation = .{},
/// Force one or a range of Unicode codepoints to map to a specific named font.
/// This is useful if you want to support special symbols or if you want to use
/// specific glyphs that render better for your specific font.
///
/// The syntax is `codepoint=fontname` where `codepoint` is either a single
/// codepoint or a range. Codepoints must be specified as full Unicode
/// hex values, such as `U+ABCD`. Codepoints ranges are specified as
/// `U+ABCD-U+DEFG`. You can specify multiple ranges for the same font separated
/// by commas, such as `U+ABCD-U+DEFG,U+1234-U+5678=fontname`. The font name is
/// the same value as you would use for `font-family`.
///
/// This configuration can be repeated multiple times to specify multiple
/// codepoint mappings.
///
/// Changing this configuration at runtime will only affect new terminals,
/// i.e. new windows, tabs, etc.
@"font-codepoint-map": RepeatableCodepointMap = .{},
/// Draw fonts with a thicker stroke, if supported.
/// This is currently only supported on macOS.
@"font-thicken": bool = false,
/// Strength of thickening when `font-thicken` is enabled.
///
/// Valid values are integers between `0` and `255`. `0` does not correspond to
/// *no* thickening, rather it corresponds to the lightest available thickening.
///
/// Has no effect when `font-thicken` is set to `false`.
///
/// This is currently only supported on macOS.
@"font-thicken-strength": u8 = 255,
/// What color space to use when performing alpha blending.
///
/// This affects the appearance of text and of any images with transparency.
/// Additionally, custom shaders will receive colors in the configured space.
///
/// Valid values:
///
/// * `native` - Perform alpha blending in the native color space for the OS.
/// On macOS this corresponds to Display P3, and on Linux it's sRGB.
///
/// * `linear` - Perform alpha blending in linear space. This will eliminate
/// the darkening artifacts around the edges of text that are very visible
/// when certain color combinations are used (e.g. red / green), but makes
/// dark text look much thinner than normal and light text much thicker.
/// This is also sometimes known as "gamma correction".
/// (Currently only supported on macOS. Has no effect on Linux.)
///
/// * `linear-corrected` - Same as `linear`, but with a correction step applied
/// for text that makes it look nearly or completely identical to `native`,
/// but without any of the darkening artifacts.
@"alpha-blending": AlphaBlending = .native,
/// All of the configurations behavior adjust various metrics determined by the
/// font. The values can be integers (1, -1, etc.) or a percentage (20%, -15%,
/// etc.). In each case, the values represent the amount to change the original
/// value.
///
/// For example, a value of `1` increases the value by 1; it does not set it to
/// literally 1. A value of `20%` increases the value by 20%. And so on.
///
/// There is little to no validation on these values so the wrong values (e.g.
/// `-100%`) can cause the terminal to be unusable. Use with caution and reason.
///
/// Some values are clamped to minimum or maximum values. This can make it
/// appear that certain values are ignored. For example, many `*-thickness`
/// adjustments cannot go below 1px.
///
/// `adjust-cell-height` has some additional behaviors to describe:
///
/// * The font will be centered vertically in the cell.
///
/// * The cursor will remain the same size as the font, but may be
/// adjusted separately with `adjust-cursor-height`.
///
/// * Powerline glyphs will be adjusted along with the cell height so
/// that things like status lines continue to look aligned.
@"adjust-cell-width": ?MetricModifier = null,
@"adjust-cell-height": ?MetricModifier = null,
/// Distance in pixels or percentage adjustment from the bottom of the cell to the text baseline.
/// Increase to move baseline UP, decrease to move baseline DOWN.
/// See the notes about adjustments in `adjust-cell-width`.
@"adjust-font-baseline": ?MetricModifier = null,
/// Distance in pixels or percentage adjustment from the top of the cell to the top of the underline.
/// Increase to move underline DOWN, decrease to move underline UP.
/// See the notes about adjustments in `adjust-cell-width`.
@"adjust-underline-position": ?MetricModifier = null,
/// Thickness in pixels of the underline.
/// See the notes about adjustments in `adjust-cell-width`.
@"adjust-underline-thickness": ?MetricModifier = null,
/// Distance in pixels or percentage adjustment from the top of the cell to the top of the strikethrough.
/// Increase to move strikethrough DOWN, decrease to move strikethrough UP.
/// See the notes about adjustments in `adjust-cell-width`.
@"adjust-strikethrough-position": ?MetricModifier = null,
/// Thickness in pixels or percentage adjustment of the strikethrough.
/// See the notes about adjustments in `adjust-cell-width`.
@"adjust-strikethrough-thickness": ?MetricModifier = null,
/// Distance in pixels or percentage adjustment from the top of the cell to the top of the overline.
/// Increase to move overline DOWN, decrease to move overline UP.
/// See the notes about adjustments in `adjust-cell-width`.
@"adjust-overline-position": ?MetricModifier = null,
/// Thickness in pixels or percentage adjustment of the overline.
/// See the notes about adjustments in `adjust-cell-width`.
@"adjust-overline-thickness": ?MetricModifier = null,
/// Thickness in pixels or percentage adjustment of the bar cursor and outlined rect cursor.
/// See the notes about adjustments in `adjust-cell-width`.
@"adjust-cursor-thickness": ?MetricModifier = null,
/// Height in pixels or percentage adjustment of the cursor. Currently applies to all cursor types:
/// bar, rect, and outlined rect.
/// See the notes about adjustments in `adjust-cell-width`.
@"adjust-cursor-height": ?MetricModifier = null,
/// Thickness in pixels or percentage adjustment of box drawing characters.
/// See the notes about adjustments in `adjust-cell-width`.
@"adjust-box-thickness": ?MetricModifier = null,
/// The method to use for calculating the cell width of a grapheme cluster.
/// The default value is `unicode` which uses the Unicode standard to determine
/// grapheme width. This results in correct grapheme width but may result in
/// cursor-desync issues with some programs (such as shells) that may use a
/// legacy method such as `wcswidth`.
///
/// Valid values are:
///
/// * `legacy` - Use a legacy method to determine grapheme width, such as
/// wcswidth This maximizes compatibility with legacy programs but may result
/// in incorrect grapheme width for certain graphemes such as skin-tone
/// emoji, non-English characters, etc.
///
/// This is called "legacy" and not something more specific because the
/// behavior is undefined and we want to retain the ability to modify it.
/// For example, we may or may not use libc `wcswidth` now or in the future.
///
/// * `unicode` - Use the Unicode standard to determine grapheme width.
///
/// If a running program explicitly enables terminal mode 2027, then `unicode`
/// width will be forced regardless of this configuration. When mode 2027 is
/// reset, this configuration will be used again.
///
/// This configuration can be changed at runtime but will not affect existing
/// terminals. Only new terminals will use the new configuration.
@"grapheme-width-method": GraphemeWidthMethod = .unicode,
/// FreeType load flags to enable. The format of this is a list of flags to
/// enable separated by commas. If you prefix a flag with `no-` then it is
/// disabled. If you omit a flag, its default value is used, so you must
/// explicitly disable flags you don't want. You can also use `true` or `false`
/// to turn all flags on or off.
///
/// This configuration only applies to Ghostty builds that use FreeType.
/// This is usually the case only for Linux builds. macOS uses CoreText
/// and does not have an equivalent configuration.
///
/// Available flags:
///
/// * `hinting` - Enable or disable hinting, enabled by default.
/// * `force-autohint` - Use the freetype auto-hinter rather than the
/// font's native hinter. Enabled by default.
/// * `monochrome` - Instructs renderer to use 1-bit monochrome
/// rendering. This option doesn't impact the hinter.
/// Enabled by default.
/// * `autohint` - Use the freetype auto-hinter. Enabled by default.
///
/// Example: `hinting`, `no-hinting`, `force-autohint`, `no-force-autohint`
@"freetype-load-flags": FreetypeLoadFlags = .{},
/// A theme to use. This can be a built-in theme name, a custom theme
/// name, or an absolute path to a custom theme file. Ghostty also supports
/// specifying a different theme to use for light and dark mode. Each
/// option is documented below.
///
/// If the theme is an absolute pathname, Ghostty will attempt to load that
/// file as a theme. If that file does not exist or is inaccessible, an error
/// will be logged and no other directories will be searched.
///
/// If the theme is not an absolute pathname, two different directories will be
/// searched for a file name that matches the theme. This is case sensitive on
/// systems with case-sensitive filesystems. It is an error for a theme name to
/// include path separators unless it is an absolute pathname.
///
/// The first directory is the `themes` subdirectory of your Ghostty
/// configuration directory. This is `$XDG_CONFIG_DIR/ghostty/themes` or
/// `~/.config/ghostty/themes`.
///
/// The second directory is the `themes` subdirectory of the Ghostty resources
/// directory. Ghostty ships with a multitude of themes that will be installed
/// into this directory. On macOS, this list is in the
/// `Ghostty.app/Contents/Resources/ghostty/themes` directory. On Linux, this
/// list is in the `share/ghostty/themes` directory (wherever you installed the
/// Ghostty "share" directory.
///
/// To see a list of available themes, run `ghostty +list-themes`.
///
/// A theme file is simply another Ghostty configuration file. They share
/// the same syntax and same configuration options. A theme can set any valid
/// configuration option so please do not use a theme file from an untrusted
/// source. The built-in themes are audited to only set safe configuration
/// options.
///
/// Some options cannot be set within theme files. The reason these are not
/// supported should be self-evident. A theme file cannot set `theme` or
/// `config-file`. At the time of writing this, Ghostty will not show any
/// warnings or errors if you set these options in a theme file but they will
/// be silently ignored.
///
/// Any additional colors specified via background, foreground, palette, etc.
/// will override the colors specified in the theme.
///
/// To specify a different theme for light and dark mode, use the following
/// syntax: `light:theme-name,dark:theme-name`. For example:
/// `light:rose-pine-dawn,dark:rose-pine`. Whitespace around all values are
/// trimmed and order of light and dark does not matter. Both light and dark
/// must be specified in this form. In this form, the theme used will be
/// based on the current desktop environment theme.
///
/// There are some known bugs with light/dark mode theming. These will
/// be fixed in a future update:
///
/// - macOS: titlebar tabs style is not updated when switching themes.
///
theme: ?Theme = null,
/// Background color for the window.
/// Specified as either hex (`#RRGGBB` or `RRGGBB`) or a named X11 color.
background: Color = .{ .r = 0x28, .g = 0x2C, .b = 0x34 },
/// Foreground color for the window.
/// Specified as either hex (`#RRGGBB` or `RRGGBB`) or a named X11 color.
foreground: Color = .{ .r = 0xFF, .g = 0xFF, .b = 0xFF },
/// The foreground and background color for selection. If this is not set, then
/// the selection color is just the inverted window background and foreground
/// (note: not to be confused with the cell bg/fg).
/// Specified as either hex (`#RRGGBB` or `RRGGBB`) or a named X11 color.
@"selection-foreground": ?Color = null,
@"selection-background": ?Color = null,
/// Swap the foreground and background colors of cells for selection. This
/// option overrides the `selection-foreground` and `selection-background`
/// options.
///
/// If you select across cells with differing foregrounds and backgrounds, the
/// selection color will vary across the selection.
@"selection-invert-fg-bg": bool = false,
/// The minimum contrast ratio between the foreground and background colors.
/// The contrast ratio is a value between 1 and 21. A value of 1 allows for no
/// contrast (e.g. black on black). This value is the contrast ratio as defined
/// by the [WCAG 2.0 specification](https://www.w3.org/TR/WCAG20/).
///
/// If you want to avoid invisible text (same color as background), a value of
/// 1.1 is a good value. If you want to avoid text that is difficult to read, a
/// value of 3 or higher is a good value. The higher the value, the more likely
/// that text will become black or white.
///
/// This value does not apply to Emoji or images.
@"minimum-contrast": f64 = 1,
/// Color palette for the 256 color form that many terminal applications use.
/// The syntax of this configuration is `N=COLOR` where `N` is 0 to 255 (for
/// the 256 colors in the terminal color table) and `COLOR` is a typical RGB
/// color code such as `#AABBCC` or `AABBCC`, or a named X11 color.
///
/// The palette index can be in decimal, binary, octal, or hexadecimal.
/// Decimal is assumed unless a prefix is used: `0b` for binary, `0o` for octal,
/// and `0x` for hexadecimal.
///
/// For definitions on the color indices and what they canonically map to,
/// [see this cheat sheet](https://www.ditig.com/256-colors-cheat-sheet).
palette: Palette = .{},
/// The color of the cursor. If this is not set, a default will be chosen.
/// Specified as either hex (`#RRGGBB` or `RRGGBB`) or a named X11 color.
@"cursor-color": ?Color = null,
/// Swap the foreground and background colors of the cell under the cursor. This
/// option overrides the `cursor-color` and `cursor-text` options.
@"cursor-invert-fg-bg": bool = false,
/// The opacity level (opposite of transparency) of the cursor. A value of 1
/// is fully opaque and a value of 0 is fully transparent. A value less than 0
/// or greater than 1 will be clamped to the nearest valid value. Note that a
/// sufficiently small value such as 0.3 may be effectively invisible and may
/// make it difficult to find the cursor.
@"cursor-opacity": f64 = 1.0,
/// The style of the cursor. This sets the default style. A running program can
/// still request an explicit cursor style using escape sequences (such as `CSI
/// q`). Shell configurations will often request specific cursor styles.
///
/// Note that shell integration will automatically set the cursor to a bar at
/// a prompt, regardless of this configuration. You can disable that behavior
/// by specifying `shell-integration-features = no-cursor` or disabling shell
/// integration entirely.
///
/// Valid values are:
///
/// * `block`
/// * `bar`
/// * `underline`
/// * `block_hollow`
///
@"cursor-style": terminal.CursorStyle = .block,
/// Sets the default blinking state of the cursor. This is just the default
/// state; running programs may override the cursor style using `DECSCUSR` (`CSI
/// q`).
///
/// If this is not set, the cursor blinks by default. Note that this is not the
/// same as a "true" value, as noted below.
///
/// If this is not set at all (`null`), then Ghostty will respect DEC Mode 12
/// (AT&T cursor blink) as an alternate approach to turning blinking on/off. If
/// this is set to any value other than null, DEC mode 12 will be ignored but
/// `DECSCUSR` will still be respected.
///
/// Valid values are:
///
/// * ` ` (blank)
/// * `true`
/// * `false`
///
@"cursor-style-blink": ?bool = null,
/// The color of the text under the cursor. If this is not set, a default will
/// be chosen.
/// Specified as either hex (`#RRGGBB` or `RRGGBB`) or a named X11 color.
@"cursor-text": ?Color = null,
/// Enables the ability to move the cursor at prompts by using `alt+click` on
/// Linux and `option+click` on macOS.
///
/// This feature requires shell integration (specifically prompt marking
/// via `OSC 133`) and only works in primary screen mode. Alternate screen
/// applications like vim usually have their own version of this feature but
/// this configuration doesn't control that.
///
/// It should be noted that this feature works by translating your desired
/// position into a series of synthetic arrow key movements, so some weird
/// behavior around edge cases are to be expected. This is unfortunately how
/// this feature is implemented across terminals because there isn't any other
/// way to implement it.
@"cursor-click-to-move": bool = true,
/// Hide the mouse immediately when typing. The mouse becomes visible again
/// when the mouse is used (button, movement, etc.). Platform-specific behavior
/// may dictate other scenarios where the mouse is shown. For example on macOS,
/// the mouse is shown again when a new window, tab, or split is created.
@"mouse-hide-while-typing": bool = false,
/// Determines whether running programs can detect the shift key pressed with a
/// mouse click. Typically, the shift key is used to extend mouse selection.
///
/// The default value of `false` means that the shift key is not sent with
/// the mouse protocol and will extend the selection. This value can be
/// conditionally overridden by the running program with the `XTSHIFTESCAPE`
/// sequence.
///
/// The value `true` means that the shift key is sent with the mouse protocol
/// but the running program can override this behavior with `XTSHIFTESCAPE`.
///
/// The value `never` is the same as `false` but the running program cannot
/// override this behavior with `XTSHIFTESCAPE`. The value `always` is the
/// same as `true` but the running program cannot override this behavior with
/// `XTSHIFTESCAPE`.
///
/// If you always want shift to extend mouse selection even if the program
/// requests otherwise, set this to `never`.
///
/// Valid values are:
///
/// * `true`
/// * `false`
/// * `always`
/// * `never`
///
@"mouse-shift-capture": MouseShiftCapture = .false,
/// Multiplier for scrolling distance with the mouse wheel. Any value less
/// than 0.01 or greater than 10,000 will be clamped to the nearest valid
/// value.
///
/// A value of "1" (default) scrolls the default amount. A value of "2" scrolls
/// double the default amount. A value of "0.5" scrolls half the default amount.
/// Et cetera.
@"mouse-scroll-multiplier": f64 = 1.0,
/// The opacity level (opposite of transparency) of the background. A value of
/// 1 is fully opaque and a value of 0 is fully transparent. A value less than 0
/// or greater than 1 will be clamped to the nearest valid value.
///
/// On macOS, background opacity is disabled when the terminal enters native
/// fullscreen. This is because the background becomes gray and it can cause
/// widgets to show through which isn't generally desirable.
///
/// On macOS, changing this configuration requires restarting Ghostty completely.
@"background-opacity": f64 = 1.0,
/// Whether to blur the background when `background-opacity` is less than 1.
///
/// Valid values are:
///
/// * a nonnegative integer specifying the *blur intensity*
/// * `false`, equivalent to a blur intensity of 0
/// * `true`, equivalent to the default blur intensity of 20, which is
/// reasonable for a good looking blur. Higher blur intensities may
/// cause strange rendering and performance issues.
///
/// Supported on macOS and on some Linux desktop environments, including:
///
/// * KDE Plasma (Wayland and X11)
///
/// Warning: the exact blur intensity is _ignored_ under KDE Plasma, and setting
/// this setting to either `true` or any positive blur intensity value would
/// achieve the same effect. The reason is that KWin, the window compositor
/// powering Plasma, only has one global blur setting and does not allow
/// applications to specify individual blur settings.
///
/// To configure KWin's global blur setting, open System Settings and go to
/// "Apps & Windows" > "Window Management" > "Desktop Effects" and select the
/// "Blur" plugin. If disabled, enable it by ticking the checkbox to the left.
/// Then click on the "Configure" button and there will be two sliders that
/// allow you to set background blur and noise intensities for all apps,
/// including Ghostty.
///
/// All other Linux desktop environments are as of now unsupported. Users may
/// need to set environment-specific settings and/or install third-party plugins
/// in order to support background blur, as there isn't a unified interface for
/// doing so.
@"background-blur": BackgroundBlur = .false,
/// The opacity level (opposite of transparency) of an unfocused split.
/// Unfocused splits by default are slightly faded out to make it easier to see
/// which split is focused. To disable this feature, set this value to 1.
///
/// A value of 1 is fully opaque and a value of 0 is fully transparent. Because
/// "0" is not useful (it makes the window look very weird), the minimum value
/// is 0.15. This value still looks weird but you can at least see what's going
/// on. A value outside of the range 0.15 to 1 will be clamped to the nearest
/// valid value.
@"unfocused-split-opacity": f64 = 0.7,
/// The color to dim the unfocused split. Unfocused splits are dimmed by
/// rendering a semi-transparent rectangle over the split. This sets the color of
/// that rectangle and can be used to carefully control the dimming effect.
///
/// This will default to the background color.
///
/// Specified as either hex (`#RRGGBB` or `RRGGBB`) or a named X11 color.
@"unfocused-split-fill": ?Color = null,
/// The color of the split divider. If this is not set, a default will be chosen.
/// Specified as either hex (`#RRGGBB` or `RRGGBB`) or a named X11 color.
@"split-divider-color": ?Color = null,
/// The command to run, usually a shell. If this is not an absolute path, it'll
/// be looked up in the `PATH`. If this is not set, a default will be looked up
/// from your system. The rules for the default lookup are:
///
/// * `SHELL` environment variable
///
/// * `passwd` entry (user information)
///
/// This can contain additional arguments to run the command with. If additional
/// arguments are provided, the command will be executed using `/bin/sh -c`.
/// Ghostty does not do any shell command parsing.
///
/// This command will be used for all new terminal surfaces, i.e. new windows,
/// tabs, etc. If you want to run a command only for the first terminal surface
/// created when Ghostty starts, use the `initial-command` configuration.
///
/// Ghostty supports the common `-e` flag for executing a command with
/// arguments. For example, `ghostty -e fish --with --custom --args`.
/// This flag sets the `initial-command` configuration, see that for more
/// information.
command: ?[]const u8 = null,
/// This is the same as "command", but only applies to the first terminal
/// surface created when Ghostty starts. Subsequent terminal surfaces will use
/// the `command` configuration.
///
/// After the first terminal surface is created (or closed), there is no
/// way to run this initial command again automatically. As such, setting
/// this at runtime works but will only affect the next terminal surface
/// if it is the first one ever created.
///
/// If you're using the `ghostty` CLI there is also a shortcut to set this
/// with arguments directly: you can use the `-e` flag. For example: `ghostty -e
/// fish --with --custom --args`. The `-e` flag automatically forces some
/// other behaviors as well:
///
/// * `gtk-single-instance=false` - This ensures that a new instance is
/// launched and the CLI args are respected.
///
/// * `quit-after-last-window-closed=true` - This ensures that the Ghostty
/// process will exit when the command exits. Additionally, the
/// `quit-after-last-window-closed-delay` is unset.
///
/// * `shell-integration=detect` (if not `none`) - This prevents forcibly
/// injecting any configured shell integration into the command's
/// environment. With `-e` its highly unlikely that you're executing a
/// shell and forced shell integration is likely to cause problems
/// (e.g. by wrapping your command in a shell, setting env vars, etc.).
/// This is a safety measure to prevent unexpected behavior. If you want
/// shell integration with a `-e`-executed command, you must either
/// name your binary appropriately or source the shell integration script
/// manually.
///
@"initial-command": ?[]const u8 = null,
/// If true, keep the terminal open after the command exits. Normally, the
/// terminal window closes when the running command (such as a shell) exits.
/// With this true, the terminal window will stay open until any keypress is
/// received.
///
/// This is primarily useful for scripts or debugging.
@"wait-after-command": bool = false,
/// The number of milliseconds of runtime below which we consider a process exit
/// to be abnormal. This is used to show an error message when the process exits
/// too quickly.
///
/// On Linux, this must be paired with a non-zero exit code. On macOS, we allow
/// any exit code because of the way shell processes are launched via the login
/// command.
@"abnormal-command-exit-runtime": u32 = 250,
/// The size of the scrollback buffer in bytes. This also includes the active
/// screen. No matter what this is set to, enough memory will always be
/// allocated for the visible screen and anything leftover is the limit for
/// the scrollback.
///
/// When this limit is reached, the oldest lines are removed from the
/// scrollback.
///
/// Scrollback currently exists completely in memory. This means that the
/// larger this value, the larger potential memory usage. Scrollback is
/// allocated lazily up to this limit, so if you set this to a very large
/// value, it will not immediately consume a lot of memory.
///
/// This size is per terminal surface, not for the entire application.
///
/// It is not currently possible to set an unlimited scrollback buffer.
/// This is a future planned feature.
///
/// This can be changed at runtime but will only affect new terminal surfaces.
@"scrollback-limit": usize = 10_000_000, // 10MB
/// Match a regular expression against the terminal text and associate clicking
/// it with an action. This can be used to match URLs, file paths, etc. Actions
/// can be opening using the system opener (e.g. `open` or `xdg-open`) or
/// executing any arbitrary binding action.
///
/// Links that are configured earlier take precedence over links that are
/// configured later.
///
/// A default link that matches a URL and opens it in the system opener always
/// exists. This can be disabled using `link-url`.
///
/// TODO: This can't currently be set!
link: RepeatableLink = .{},
/// Enable URL matching. URLs are matched on hover with control (Linux) or
/// super (macOS) pressed and open using the default system application for
/// the linked URL.
///
/// The URL matcher is always lowest priority of any configured links (see
/// `link`). If you want to customize URL matching, use `link` and disable this.
@"link-url": bool = true,
/// Whether to start the window in a maximized state. This setting applies
/// to new windows and does not apply to tabs, splits, etc. However, this setting
/// will apply to all new windows, not just the first one.
maximize: bool = false,
/// Start new windows in fullscreen. This setting applies to new windows and
/// does not apply to tabs, splits, etc. However, this setting will apply to all
/// new windows, not just the first one.
///
/// On macOS, this setting does not work if window-decoration is set to
/// "false", because native fullscreen on macOS requires window decorations
/// to be set.
fullscreen: bool = false,
/// The title Ghostty will use for the window. This will force the title of the
/// window to be this title at all times and Ghostty will ignore any set title
/// escape sequences programs (such as Neovim) may send.
///
/// If you want a blank title, set this to one or more spaces by quoting
/// the value. For example, `title = " "`. This effectively hides the title.
/// This is necessary because setting a blank value resets the title to the
/// default value of the running program.
///
/// This configuration can be reloaded at runtime. If it is set, the title
/// will update for all windows. If it is unset, the next title change escape
/// sequence will be honored but previous changes will not retroactively
/// be set. This latter case may require you to restart programs such as Neovim
/// to get the new title.
title: ?[:0]const u8 = null,
/// The setting that will change the application class value.
///
/// This controls the class field of the `WM_CLASS` X11 property (when running
/// under X11), and the Wayland application ID (when running under Wayland).
///
/// Note that changing this value between invocations will create new, separate
/// instances, of Ghostty when running with `gtk-single-instance=true`. See that
/// option for more details.
///
/// The class name must follow the requirements defined [in the GTK
/// documentation](https://docs.gtk.org/gio/type_func.Application.id_is_valid.html).
///
/// The default is `com.mitchellh.ghostty`.
///
/// This only affects GTK builds.
class: ?[:0]const u8 = null,
/// This controls the instance name field of the `WM_CLASS` X11 property when
/// running under X11. It has no effect otherwise.
///
/// The default is `ghostty`.
///
/// This only affects GTK builds.
@"x11-instance-name": ?[:0]const u8 = null,
/// The directory to change to after starting the command.
///
/// This setting is secondary to the `window-inherit-working-directory`
/// setting. If a previous Ghostty terminal exists in the same process,
/// `window-inherit-working-directory` will take precedence. Otherwise, this
/// setting will be used. Typically, this setting is used only for the first
/// window.
///
/// The default is `inherit` except in special scenarios listed next. On macOS,
/// if Ghostty can detect it is launched from launchd (double-clicked) or
/// `open`, then it defaults to `home`. On Linux with GTK, if Ghostty can detect
/// it was launched from a desktop launcher, then it defaults to `home`.
///
/// The value of this must be an absolute value or one of the special values
/// below:
///
/// * `home` - The home directory of the executing user.
///
/// * `inherit` - The working directory of the launching process.
@"working-directory": ?[]const u8 = null,
/// Key bindings. The format is `trigger=action`. Duplicate triggers will
/// overwrite previously set values. The list of actions is available in
/// the documentation or using the `ghostty +list-actions` command.
///
/// Trigger: `+`-separated list of keys and modifiers. Example: `ctrl+a`,
/// `ctrl+shift+b`, `up`.
///
/// Valid keys are currently only listed in the
/// [Ghostty source code](https://github.com/ghostty-org/ghostty/blob/d6e76858164d52cff460fedc61ddf2e560912d71/src/input/key.zig#L255).
/// This is a documentation limitation and we will improve this in the future.
/// A common gotcha is that numeric keys are written as words: e.g. `one`,
/// `two`, `three`, etc. and not `1`, `2`, `3`. This will also be improved in
/// the future.
///
/// Valid modifiers are `shift`, `ctrl` (alias: `control`), `alt` (alias: `opt`,
/// `option`), and `super` (alias: `cmd`, `command`). You may use the modifier
/// or the alias. When debugging keybinds, the non-aliased modifier will always
/// be used in output.
///
/// Note: The fn or "globe" key on keyboards are not supported as a
/// modifier. This is a limitation of the operating systems and GUI toolkits
/// that Ghostty uses.
///
/// Some additional notes for triggers:
///
/// * modifiers cannot repeat, `ctrl+ctrl+a` is invalid.
///
/// * modifiers and keys can be in any order, `shift+a+ctrl` is *weird*,
/// but valid.
///
/// * only a single key input is allowed, `ctrl+a+b` is invalid.
///
/// * the key input can be prefixed with `physical:` to specify a
/// physical key mapping rather than a logical one. A physical key
/// mapping responds to the hardware keycode and not the keycode
/// translated by any system keyboard layouts. Example: "ctrl+physical:a"
///
/// You may also specify multiple triggers separated by `>` to require a
/// sequence of triggers to activate the action. For example,
/// `ctrl+a>n=new_window` will only trigger the `new_window` action if the
/// user presses `ctrl+a` followed separately by `n`. In other software, this
/// is sometimes called a leader key, a key chord, a key table, etc. There
/// is no hardcoded limit on the number of parts in a sequence.
///
/// Warning: If you define a sequence as a CLI argument to `ghostty`,
/// you probably have to quote the keybind since `>` is a special character
/// in most shells. Example: ghostty --keybind='ctrl+a>n=new_window'
///
/// A trigger sequence has some special handling:
///
/// * Ghostty will wait an indefinite amount of time for the next key in
/// the sequence. There is no way to specify a timeout. The only way to
/// force the output of a prefix key is to assign another keybind to
/// specifically output that key (e.g. `ctrl+a>ctrl+a=text:foo`) or
/// press an unbound key which will send both keys to the program.
///
/// * If a prefix in a sequence is previously bound, the sequence will
/// override the previous binding. For example, if `ctrl+a` is bound to
/// `new_window` and `ctrl+a>n` is bound to `new_tab`, pressing `ctrl+a`
/// will do nothing.
///
/// * Adding to the above, if a previously bound sequence prefix is
/// used in a new, non-sequence binding, the entire previously bound
/// sequence will be unbound. For example, if you bind `ctrl+a>n` and
/// `ctrl+a>t`, and then bind `ctrl+a` directly, both `ctrl+a>n` and
/// `ctrl+a>t` will become unbound.
///
/// * Trigger sequences are not allowed for `global:` or `all:`-prefixed
/// triggers. This is a limitation we could remove in the future.
///
/// Action is the action to take when the trigger is satisfied. It takes the
/// format `action` or `action:param`. The latter form is only valid if the
/// action requires a parameter.
///
/// * `ignore` - Do nothing, ignore the key input. This can be used to
/// black hole certain inputs to have no effect.
///
/// * `unbind` - Remove the binding. This makes it so the previous action
/// is removed, and the key will be sent through to the child command
/// if it is printable. Unbind will remove any matching trigger,
/// including `physical:`-prefixed triggers without specifying the
/// prefix.
///
/// * `csi:text` - Send a CSI sequence. e.g. `csi:A` sends "cursor up".
///
/// * `esc:text` - Send an escape sequence. e.g. `esc:d` deletes to the
/// end of the word to the right.
///
/// * `text:text` - Send a string. Uses Zig string literal syntax.
/// e.g. `text:\x15` sends Ctrl-U.
///
/// * All other actions can be found in the documentation or by using the
/// `ghostty +list-actions` command.
///
/// Some notes for the action:
///
/// * The parameter is taken as-is after the `:`. Double quotes or
/// other mechanisms are included and NOT parsed. If you want to
/// send a string value that includes spaces, wrap the entire
/// trigger/action in double quotes. Example: `--keybind="up=csi:A B"`
///
/// There are some additional special values that can be specified for
/// keybind:
///
/// * `keybind=clear` will clear all set keybindings. Warning: this
/// removes ALL keybindings up to this point, including the default
/// keybindings.
///
/// The keybind trigger can be prefixed with some special values to change
/// the behavior of the keybind. These are:
///
/// * `all:` - Make the keybind apply to all terminal surfaces. By default,
/// keybinds only apply to the focused terminal surface. If this is true,
/// then the keybind will be sent to all terminal surfaces. This only
/// applies to actions that are surface-specific. For actions that
/// are already global (e.g. `quit`), this prefix has no effect.
///
/// * `global:` - Make the keybind global. By default, keybinds only work
/// within Ghostty and under the right conditions (application focused,
/// sometimes terminal focused, etc.). If you want a keybind to work
/// globally across your system (e.g. even when Ghostty is not focused),
/// specify this prefix. This prefix implies `all:`. Note: this does not
/// work in all environments; see the additional notes below for more
/// information.
///
/// * `unconsumed:` - Do not consume the input. By default, a keybind
/// will consume the input, meaning that the associated encoding (if