Last active
March 4, 2025 05:42
-
-
Save cdalvaro/baaf834c705b5b9e073fc092de1e8520 to your computer and use it in GitHub Desktop.
This code transforms an iTerm2 color theme to a Ghostty color theme.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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) |
Python version → https://gist.github.com/farhaduneci/cdcac037bbc8315d817866808b022911
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
Usage: