Skip to content

Instantly share code, notes, and snippets.

@cdalvaro
Last active March 4, 2025 05:42
Show Gist options
  • Save cdalvaro/baaf834c705b5b9e073fc092de1e8520 to your computer and use it in GitHub Desktop.
Save cdalvaro/baaf834c705b5b9e073fc092de1e8520 to your computer and use it in GitHub Desktop.
This code transforms an iTerm2 color theme to a Ghostty color theme.
#!/usr/bin/env ruby
# frozen_string_literal: true
require "erb"
require "optparse"
require "rexml/document"
GHOSTTY_TEMPLATE = '
palette = 0=<%= ansi0 %>
palette = 1=<%= ansi1 %>
palette = 2=<%= ansi2 %>
palette = 3=<%= ansi3 %>
palette = 4=<%= ansi4 %>
palette = 5=<%= ansi5 %>
palette = 6=<%= ansi6 %>
palette = 7=<%= ansi7 %>
palette = 8=<%= ansi8 %>
palette = 9=<%= ansi9 %>
palette = 10=<%= ansi10 %>
palette = 11=<%= ansi11 %>
palette = 12=<%= ansi12 %>
palette = 13=<%= ansi13 %>
palette = 14=<%= ansi14 %>
palette = 15=<%= ansi15 %>
background = <%= background %>
foreground = <%= foreground %>
cursor-color = <%= cursor %>
selection-background = <%= selection_bg %>
selection-foreground = <%= selection_fg %>
'
##
# Converts a float value between 0 and 1 to a hexadecimal string
# @param value [Float] The value to convert
# @return [String] The hexadecimal string
def float_to_hex(value)
(value * 255).round.to_s(16).rjust(2, "0")
end
##
# Converts a color hash to a hexadecimal string
# @param color [Hash] The color hash
# @return [String] The hexadecimal string
def rgb_to_hex(color)
red = color[:red]
green = color[:green]
blue = color[:blue]
"##{float_to_hex(red)}#{float_to_hex(green)}#{float_to_hex(blue)}"
end
##
# Converts iTerm2 colors to Ghostty colors
# @param colors [Hash] The iTerm2 colors
# @return [Hash] The Ghostty colors
def iterm2ghostty_colors(colors)
{
ansi0: rgb_to_hex(colors["Ansi 0 Color"]),
ansi1: rgb_to_hex(colors["Ansi 1 Color"]),
ansi2: rgb_to_hex(colors["Ansi 2 Color"]),
ansi3: rgb_to_hex(colors["Ansi 3 Color"]),
ansi4: rgb_to_hex(colors["Ansi 4 Color"]),
ansi5: rgb_to_hex(colors["Ansi 5 Color"]),
ansi6: rgb_to_hex(colors["Ansi 6 Color"]),
ansi7: rgb_to_hex(colors["Ansi 7 Color"]),
ansi8: rgb_to_hex(colors["Ansi 8 Color"]),
ansi9: rgb_to_hex(colors["Ansi 9 Color"]),
ansi10: rgb_to_hex(colors["Ansi 10 Color"]),
ansi11: rgb_to_hex(colors["Ansi 11 Color"]),
ansi12: rgb_to_hex(colors["Ansi 12 Color"]),
ansi13: rgb_to_hex(colors["Ansi 13 Color"]),
ansi14: rgb_to_hex(colors["Ansi 14 Color"]),
ansi15: rgb_to_hex(colors["Ansi 15 Color"]),
background: rgb_to_hex(colors["Background Color"]),
foreground: rgb_to_hex(colors["Foreground Color"]),
cursor: rgb_to_hex(colors["Cursor Color"]),
selection_bg: rgb_to_hex(colors["Selection Color"]),
selection_fg: rgb_to_hex(colors["Selected Text Color"])
}
end
## Main
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: iterm2ghostty.rb --file iterm2theme.itermcolors"
opts.on("-f", "--file FILE", String, "The iTerm2 theme file path") do |file|
options[:file] = file
end
end.parse!
iterm_data = REXML::Document.new(File.read(options[:file]))
source_colors = iterm_data.elements["plist/dict"]
iterm2_colors = {}
source_colors.elements.each do |color|
name = color.text
next unless %r{Color$}.match?(name)
value = color.next_element
red = value.elements["key[text()='Red Component']"].next_element.text.to_f
green = value.elements["key[text()='Green Component']"].next_element.text.to_f
blue = value.elements["key[text()='Blue Component']"].next_element.text.to_f
iterm2_colors[name] = { red:, green:, blue: }
end
ghostty_colors = iterm2ghostty_colors(iterm2_colors)
template = ERB.new(GHOSTTY_TEMPLATE)
puts template.result_with_hash(ghostty_colors)
@cdalvaro
Copy link
Author

Usage:

curl -L -o iterm2ghostty.rb https://gist.github.com/cdalvaro/baaf834c705b5b9e073fc092de1e8520/raw/iterm2ghostty.rb
chmod +x iterm2ghostty.rb
./iterm2ghostty.rb --file github-vscode-theme-iterm-main/GitHub\ Dark\ Dimmed.itermcolors

@farhaduneci
Copy link

@moshen
Copy link

moshen commented Mar 4, 2025

I've created a browser-based iTerm2 to Ghostty config converter that supports profile files:
https://moshen.github.io/iTerm2-to-Ghostty-Config-Converter/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment