Documentation Index Fetch the complete documentation index at: https://mintlify.com/zerebos/ghostty-config/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Utility modules provide core functionality for config parsing, color operations, and keybind validation.
settings.ts
Location : src/lib/data/settings.ts
Settings schema and metadata for the Ghostty Config editor.
Exports
export type KeybindString = ` ${ string } = ${ string } ` ;
export interface ColorScheme {
palette : HexColor [];
background ?: HexColor ;
foreground ?: HexColor ;
cursor ?: HexColor ;
selection ?: HexColor ;
// ... additional color properties
}
export const fetchColorScheme = async ( theme : string ) : Promise < ColorScheme >
export default settings ; // Array of Panel objects
Settings Structure
The default export is an array of Panel objects, each containing Groups , which contain individual Settings :
interface Panel {
id : string ;
name : string ;
groups : Group [];
}
interface Group {
id : string ;
name : string ;
settings : Array < Switch | Number | Dropdown | Color | Palette | Keybinds | Theme >;
}
Setting Types
switch — Boolean toggle
number — Numeric input with optional range
dropdown — Select from options
text — Text input
color — Color picker
palette — 256-color array
keybinds — Keybinding array
theme — Theme selector (special dropdown)
fetchColorScheme()
Fetches color schemes from the iTerm2-Color-Schemes repository.
const response = await fetchColorScheme ( "Dracula" );
// Returns: { background: "#282a36", foreground: "#f8f8f2", palette: [...], ... }
Features :
Loads themes from GitHub API
Parses iTerm2 XML format
Converts to Ghostty color format
Used by the Theme component
parse.ts
Location : src/lib/utils/parse.ts
Parses Ghostty config file format into JavaScript objects.
Default Export
export default function ( configString : string ) : ParsedConfig
Return Type
type ParsedConfig = {
palette : Array < HexColor | "" >;
keybind : KeybindString [];
[ key : string ] : string | string [];
}
Parsing Rules
Line format : key = value
const re = / ^ \s * ( [ a-z- ] + ) [ \s ] * = \s * ( . * ) \s * $ / ;
Key conversion : Kebab-case → camelCase
const split = key . split ( "-" );
let newKey = split [ 0 ]. trim ();
for ( let s = 1 ; s < split . length ; s ++ ) {
newKey += split [ s ]. charAt ( 0 ). toUpperCase ();
newKey += split [ s ]. substring ( 1 );
}
// "font-size" → "fontSize"
Special Handling
Format: palette = N=color if ( key === "palette" ) {
const split = value . split ( "=" );
const num = parseInt ( split [ 0 ]. trim ());
const color = split [ 1 ]. trim () as HexColor ;
if ( num < 0 || num > 255 ) continue ;
results . palette [ num ] = color ;
}
Example :palette = 0=#000000
palette = 15=#ffffff
Accumulated into an array. if ( key === "keybind" ) {
results . keybind . push ( value as KeybindString );
}
Example :keybind = ctrl+t=new_tab
keybind = ctrl+shift+v=paste_from_clipboard
Auto-prefixes # for 6-character hex values. const colors = [
"background" , "foreground" , "cursor-color" ,
"selection-background" , "selection-foreground"
];
if ( colors . includes ( key ) && value . length === 6 && ! value . startsWith ( "#" )) {
results [ newKey ] = `# ${ value } ` ;
}
Example :background = 1e1e1e → { background: "#1e1e1e" }
background = #1e1e1e → { background: "#1e1e1e" }
Usage Example
import parse from "$lib/utils/parse" ;
const configText = `
font-size = 14
background = 1e1e1e
palette = 0=000000
keybind = ctrl+t=new_tab
` ;
const config = parse ( configText );
// {
// fontSize: "14",
// background: "#1e1e1e",
// palette: ["#000000", "", "", ...],
// keybind: ["ctrl+t=new_tab"]
// }
colors.ts
Location : src/lib/utils/colors.ts
Color conversion and manipulation utilities.
Types
export type HexColor = `# ${ string } ` ;
export type RgbArray = [ number , number , number ];
export type HsvArray = [ number , number , number ];
export type HsvObj = { hue : number , saturation : number , value : number };
Functions
Calculates relative luminance of a color. export function luminosity ( color : HexColor ) : number
Formula : ITU-R BT.709 weighted RGBconst red = int >> 16 & 0xFF ;
const green = int >> 8 & 0xFF ;
const blue = int >> 0 & 0xFF ;
return ( 0.2126 * red ) + ( 0.7152 * green ) + ( 0.0722 * blue );
Returns : Value from 0 (black) to 255 (white)Usage luminosity ( "#000000" ) // 0
luminosity ( "#ffffff" ) // 255
luminosity ( "#808080" ) // ~128
Tests if a color is dark. export function isDark ( color : HexColor ) : boolean
Returns true if luminosity < 128. Usage const textColor = isDark ( bgColor ) ? "white" : "black" ;
Converts HSV to RGB. export function hsvToRgb (
hue : number , // 0-1
saturation : number , // 0-1
value : number // 0-1
) : RgbArray // [0-255, 0-255, 0-255]
Algorithm : Standard HSV to RGB conversion from Wikipedia.Example hsvToRgb ( 0 , 1 , 1 ) // [255, 0, 0] - red
hsvToRgb ( 0.33 , 1 , 1 ) // [0, 255, 0] - green
hsvToRgb ( 0 , 0 , 1 ) // [255, 255, 255] - white
Converts RGB to HSV. export function rgbToHsv (
red : number , // 0-255
green : number , // 0-255
blue : number // 0-255
) : HsvObj // {hue: 0-1, saturation: 0-1, value: 0-1}
Example rgbToHsv ( 255 , 0 , 0 )
// {hue: 0, saturation: 1, value: 1}
rgbToHsv ( 128 , 128 , 128 )
// {hue: 0, saturation: 0, value: 0.502}
Converts RGB values to hex color. export function rgbToHex (
red : number , // 0-255
green : number , // 0-255
blue : number // 0-255
) : HexColor
Implementation const get = ( color : number ) =>
color . toString ( 16 ). padStart ( 2 , "0" ). toUpperCase ();
return `# ${ get ( red ) }${ get ( green ) }${ get ( blue ) } ` ;
Example rgbToHex ( 255 , 0 , 0 ) // "#FF0000"
rgbToHex ( 64 , 128 , 128 ) // "#408080"
Converts hex color to RGB array. export function hexToRgb ( string : HexColor ) : RgbArray
Example hexToRgb ( "#FF0000" ) // [255, 0, 0]
hexToRgb ( "#408080" ) // [64, 128, 128]
keybinds.ts
Location : src/lib/utils/keybinds.ts
Keybind parsing, validation, and formatting.
Constants
Array of 177 valid key names. const KEY_NAMES = [
"backquote" , "backslash" , "bracket_left" , "bracket_right" ,
"key_a" , "key_b" , ... , "key_z" ,
"f1" , "f2" , ... , "f24" ,
"arrow_up" , "arrow_down" , "arrow_left" , "arrow_right" ,
"numpad_0" , ... , "numpad_9" ,
"copy" , "paste" , "cut" ,
// ... many more
] as const ;
export type KeyName = ( typeof KEY_NAMES )[ number ];
const VALID_MODIFIERS = [ "shift" , "ctrl" , "alt" , "super" ];
Aliases (normalized to standard form):
control → ctrl
cmd, command → super
opt, option → alt
const VALID_PREFIXES = [ "all" , "global" , "unconsumed" , "performable" ];
Array of 80+ action definitions. export interface ActionDefinition {
name : string ;
type : "none" | "number" | "integer" | "free" | "enum" | "text" | "resize" ;
options ?: string [];
allowEmpty ?: boolean ;
}
const ACTION_DEFINITIONS : ActionDefinition [] = [
{ name: "ignore" , type: "none" },
{ name: "new_tab" , type: "none" },
{ name: "goto_tab" , type: "integer" },
{
name: "copy_to_clipboard" ,
type: "enum" ,
options: [ "plain" , "vt" , "html" , "mixed" ],
allowEmpty: true
},
{ name: "resize_split" , type: "resize" },
// ...
];
Types
export type ParsedTriggerStep = {
key : string ;
modifiers : string [];
};
export type ParsedTrigger = {
prefixes : string [];
steps : ParsedTriggerStep [];
};
export type ParsedKeybind = {
trigger ?: ParsedTrigger ;
action ?: string ;
args ?: string ;
error ?: string [];
};
Functions
Parses and validates a complete keybind string. export function parseKeybind ( value : string ) : ParsedKeybind
[prefixes:]key[+modifier][>key[+modifier]]=action[:arg]
Examples parseKeybind ( "ctrl+t=new_tab" )
// {
// trigger: {
// prefixes: [],
// steps: [{key: "t", modifiers: ["ctrl"]}]
// },
// action: "new_tab",
// args: undefined,
// error: []
// }
parseKeybind ( "global:ctrl+q=quit" )
parseKeybind ( "ctrl+k>ctrl+v=new_split:down" )
parseKeybind ( "shift+alt+super+key_a=ignore" )
Validation Returns errors for:
Invalid key names
Invalid modifiers
Invalid action names
Wrong argument types
Global/all keybinds with sequences
More than 4 modifiers
Parses just the trigger portion (before =). export function parseTrigger ( triggerString : string ) : ParsedTrigger | null
Process
Normalize whitespace
Extract prefixes (global:, all:, etc.)
Split on > for sequences
Parse each step’s modifiers and key
Example parseTrigger ( "global:ctrl+shift+t" )
// {
// prefixes: ["global"],
// steps: [{key: "t", modifiers: ["ctrl", "shift"]}]
// }
parseTrigger ( "ctrl+k>v" )
// {
// prefixes: [],
// steps: [
// {key: "k", modifiers: ["ctrl"]},
// {key: "v", modifiers: []}
// ]
// }
Validates an array of keybinds and detects duplicates. export function getDiagnostics ( keybinds : string []) : Diagnostic []
Returns :type Diagnostic = {
status : "ok" | "invalid" ;
duplicate : boolean ;
errors : string [];
canonical : string ;
}
Usage const diagnostics = getDiagnostics ([
"ctrl+t=new_tab" ,
"ctrl+t=new_window" , // duplicate trigger!
"invalid syntax"
]);
// [
// {status: "ok", duplicate: true, errors: [], canonical: "ctrl+t"},
// {status: "ok", duplicate: true, errors: [], canonical: "ctrl+t"},
// {status: "invalid", duplicate: false, errors: [...], canonical: ""}
// ]
Normalizes trigger to canonical form for comparison. export function canonicalTrigger ( parsed : ParsedTrigger ) : string
Normalizations :
Sorts modifiers alphabetically
Lowercases everything
Removes whitespace
Example // These all produce "alt+ctrl+t":
canonicalTrigger ( parseTrigger ( "ctrl+alt+t" ));
canonicalTrigger ( parseTrigger ( "alt+ctrl+t" ));
canonicalTrigger ( parseTrigger ( "Ctrl + Alt + T" ));
Action Type Validation
function validateAction ( action : string , args : string | undefined ) : string []
Type-specific validation :
none: No arguments allowed
free: Any argument or none (if allowEmpty)
text: Requires Zig string literal
number: Must be numeric
integer: Must be whole number
enum: Must be in options list
resize: Format direction,offset where direction ∈
Key Normalization
Accepts multiple formats:
"KeyA" → "key_a"
"ArrowUp" → "arrow_up"
"PageDown" → "page_down"
"F1" → "f1"
"a" → "a" ( single character )
"physical:q" → "physical:q" ( physical layout )