From 3e2162d366d00412983e71a83cf32cb8914d8f70 Mon Sep 17 00:00:00 2001 From: Leroy Hopson Date: Sun, 18 Jul 2021 23:11:31 +0700 Subject: [PATCH] Add basic .xrdb/.Xresources import plugin Adds basic support for importing .Xresources and .xrdb files as Theme resources. Examples of terminal color schemes in .xrdb format can be found here: https://github.com/mbadolato/iTerm2-Color-Schemes/tree/master/xrdb Examples of terminal themes in .Xresources format can be found here: https://github.com/mbadolato/iTerm2-Color-Schemes/tree/master/Xresources https://terminal.sexy also supports exporting themes is Xresources format. --- .github/workflows/main.yml | 6 +- .../import_plugins/xrdb_import_plugin.gd | 122 ++++++++++++++++++ addons/godot_xterm/plugin.gd | 7 + addons/godot_xterm/resources/xrdb_theme.gd | 9 ++ test/import_plugins/xrdb/Test1.xrdb | 20 +++ test/import_plugins/xrdb/Test1.xrdb.import | 13 ++ test/import_plugins/xrdb/Test2.Xresources | 36 ++++++ .../xrdb/Test2.Xresources.import | 13 ++ test/import_plugins/xrdb/Test3.xresources | 36 ++++++ .../xrdb/Test3.xresources.import | 13 ++ .../xrdb/xrdb_import_plugin.test.gd | 95 ++++++++++++++ 11 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 addons/godot_xterm/import_plugins/xrdb_import_plugin.gd create mode 100644 addons/godot_xterm/resources/xrdb_theme.gd create mode 100644 test/import_plugins/xrdb/Test1.xrdb create mode 100644 test/import_plugins/xrdb/Test1.xrdb.import create mode 100644 test/import_plugins/xrdb/Test2.Xresources create mode 100644 test/import_plugins/xrdb/Test2.Xresources.import create mode 100644 test/import_plugins/xrdb/Test3.xresources create mode 100644 test/import_plugins/xrdb/Test3.xresources.import create mode 100644 test/import_plugins/xrdb/xrdb_import_plugin.test.gd diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3e6cd0a..9ee46ab 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -219,10 +219,14 @@ jobs: with: run: godot_executable/${{ env.GODOT }} --no-window -s plug.gd install + # Use export to force re-import of files, even though it will fail if we + # don't have any export templates installed it should still import the + # files first. - name: Import files uses: GabrielBB/xvfb-action@v1 with: - run: ./godot_executable/${{ env.GODOT }} --editor --quit + run: ./godot_executable/${{ env.GODOT }} --export HTML5 + continue-on-error: true - name: Run tests uses: GabrielBB/xvfb-action@v1 diff --git a/addons/godot_xterm/import_plugins/xrdb_import_plugin.gd b/addons/godot_xterm/import_plugins/xrdb_import_plugin.gd new file mode 100644 index 0000000..0db8dfe --- /dev/null +++ b/addons/godot_xterm/import_plugins/xrdb_import_plugin.gd @@ -0,0 +1,122 @@ +tool +extends EditorImportPlugin + +const XrdbTheme := preload("../resources/xrdb_theme.gd") + + +func get_importer_name(): + return "godot_xterm_xrdb_importer" + + +func get_visible_name(): + return "xrdb_theme" + + +func get_recognized_extensions(): + return ["xrdb", "Xresources", "xresources"] + + +func get_save_extension(): + return "res" + + +func get_resource_type(): + return "Theme" + + +func get_import_options(preset): + return [] + + +func get_preset_count(): + return 0 + + +func import(source_file, save_path, options, r_platform_variant, r_gen_files): + var file = File.new() + var err = file.open(source_file, File.READ) + if err != OK: + return err + + var theme: Theme = XrdbTheme.new() + theme.default_font = preload("../themes/fonts/regular.tres") + + var word_regex = RegEx.new() + word_regex.compile("\\S+") + + var color_regex = RegEx.new() + color_regex.compile(".*(?cursor|foreground|background|color\\d+):") + + while not file.eof_reached(): + var line = file.get_line().strip_edges() + var words = word_regex.search_all(line) + if words.size() < 2: + continue + + var name: String + var color: Color + + if words.size() == 2: + if "cursorColor" in words[0].get_string(): + name = "cursorcolor" + color = Color(words[1].get_string()) + else: + var c = color_regex.search_all(words[0].get_string().to_lower()) + if c.size() > 0: + name = c[0].get_string("name").to_lower() + color = Color(words[1].get_string()) + + if words.size() == 3 and words[0].get_string() == "#define": + name = words[1].get_string().to_lower() + color = Color(words[2].get_string()) + + if not name or not color: + continue + + match name: + "color0", "ansi_0_color": + theme.set_color("Black", "Terminal", color) + "color1", "ansi_1_color": + theme.set_color("Red", "Terminal", color) + "color2", "ansi_2_color": + theme.set_color("Green", "Terminal", color) + "color3", "ansi_3_color": + theme.set_color("Yellow", "Terminal", color) + "color4", "ansi_4_color": + theme.set_color("Blue", "Terminal", color) + "color5", "ansi_5_color": + theme.set_color("Magenta", "Terminal", color) + "color6", "ansi_6_color": + theme.set_color("Cyan", "Terminal", color) + "color7", "ansi_7_color": + theme.set_color("Light Grey", "Terminal", color) + "color8", "ansi_8_color": + theme.set_color("Dark Grey", "Terminal", color) + "color9", "ansi_9_color": + theme.set_color("Light Red", "Terminal", color) + "color10", "ansi_10_color": + theme.set_color("Light Green", "Terminal", color) + "color11", "ansi_11_color": + theme.set_color("Light Yellow", "Terminal", color) + "color12", "ansi_12_color": + theme.set_color("Light Blue", "Terminal", color) + "color13", "ansi_13_color": + theme.set_color("Light Magenta", "Terminal", color) + "color14", "ansi_14_color": + theme.set_color("Light Cyan", "Terminal", color) + "color15", "ansi_15_color": + theme.set_color("White", "Terminal", color) + "foreground", "foreground_color": + theme.set_color("Foreground", "Terminal", color) + "background", "background_color": + theme.set_color("Background", "Terminal", color) + "selection_color": + theme.set_color("Selection", "Terminal", color) + "selected_text_color": + theme.set_color("Selected Text", "Terminal", color) + "cursorcolor", "cursor_color": + theme.set_color("Cursor", "Terminal", color) + "cursor_text_color": + theme.set_color("Cursor Text", "Terminal", color) + + return ResourceSaver.save("%s.%s" % [save_path, get_save_extension()], theme) diff --git a/addons/godot_xterm/plugin.gd b/addons/godot_xterm/plugin.gd index 309ad64..4ddc1f0 100644 --- a/addons/godot_xterm/plugin.gd +++ b/addons/godot_xterm/plugin.gd @@ -3,6 +3,7 @@ extends EditorPlugin var pty_supported := OS.get_name() in ["X11", "Server", "OSX"] var asciicast_import_plugin +var xrdb_import_plugin var terminal_panel: Control @@ -10,6 +11,9 @@ func _enter_tree(): asciicast_import_plugin = preload("./import_plugins/asciicast_import_plugin.gd").new() add_import_plugin(asciicast_import_plugin) + xrdb_import_plugin = preload("./import_plugins/xrdb_import_plugin.gd").new() + add_import_plugin(xrdb_import_plugin) + var asciicast_script = preload("./resources/asciicast.gd") add_custom_type("Asciicast", "Animation", asciicast_script, null) @@ -37,6 +41,9 @@ func _exit_tree(): remove_import_plugin(asciicast_import_plugin) asciicast_import_plugin = null + remove_import_plugin(xrdb_import_plugin) + xrdb_import_plugin = null + remove_custom_type("Asciicast") remove_custom_type("Terminal") diff --git a/addons/godot_xterm/resources/xrdb_theme.gd b/addons/godot_xterm/resources/xrdb_theme.gd new file mode 100644 index 0000000..9ae830b --- /dev/null +++ b/addons/godot_xterm/resources/xrdb_theme.gd @@ -0,0 +1,9 @@ +extends Theme + + +func get_class() -> String: + return "XrdbTheme" + + +func is_class(name) -> bool: + return name == get_class() or .is_class(name) diff --git a/test/import_plugins/xrdb/Test1.xrdb b/test/import_plugins/xrdb/Test1.xrdb new file mode 100644 index 0000000..621c3a6 --- /dev/null +++ b/test/import_plugins/xrdb/Test1.xrdb @@ -0,0 +1,20 @@ +#define Background_Color #100000 +#define Foreground_Color #200000 +#define Cursor_Color #300000 +#define Cursor_Text_Color #400000 +#define Ansi_0_Color #000000 +#define Ansi_8_Color #000008 +#define Ansi_1_Color #000001 +#define Ansi_9_Color #000009 +#define Ansi_2_Color #000002 +#define Ansi_10_Color #000010 +#define Ansi_3_Color #000003 +#define Ansi_11_Color #000011 +#define Ansi_4_Color #000004 +#define Ansi_12_Color #000012 +#define Ansi_5_Color #000005 +#define Ansi_13_Color #000013 +#define Ansi_6_Color #000006 +#define Ansi_14_Color #000014 +#define Ansi_7_Color #000007 +#define Ansi_15_Color #000015 diff --git a/test/import_plugins/xrdb/Test1.xrdb.import b/test/import_plugins/xrdb/Test1.xrdb.import new file mode 100644 index 0000000..3856e81 --- /dev/null +++ b/test/import_plugins/xrdb/Test1.xrdb.import @@ -0,0 +1,13 @@ +[remap] + +importer="godot_xterm_xrdb_importer" +type="Theme" +path="res://.import/Test1.xrdb-754efb4c644076f3ce42897c010bc001.res" + +[deps] + +source_file="res://test/import_plugins/xrdb/Test1.xrdb" +dest_files=[ "res://.import/Test1.xrdb-754efb4c644076f3ce42897c010bc001.res" ] + +[params] + diff --git a/test/import_plugins/xrdb/Test2.Xresources b/test/import_plugins/xrdb/Test2.Xresources new file mode 100644 index 0000000..eb23ac9 --- /dev/null +++ b/test/import_plugins/xrdb/Test2.Xresources @@ -0,0 +1,36 @@ +! special +*.foreground: #c5c8c6 +*.background: #1d1f21 +*.cursorColor: #c5c8c6 + +! black +*.color0: #282a2e +*.color8: #373b41 + +! red +*.color1: #a54242 +*.color9: #cc6666 + +! green +*.color2: #8c9440 +*.color10: #b5bd68 + +! yellow +*.color3: #de935f +*.color11: #f0c674 + +! blue +*.color4: #5f819d +*.color12: #81a2be + +! magenta +*.color5: #85678f +*.color13: #b294bb + +! cyan +*.color6: #5e8d87 +*.color14: #8abeb7 + +! white +*.color7: #707880 +*.color15: #c5c8c6 diff --git a/test/import_plugins/xrdb/Test2.Xresources.import b/test/import_plugins/xrdb/Test2.Xresources.import new file mode 100644 index 0000000..e162a90 --- /dev/null +++ b/test/import_plugins/xrdb/Test2.Xresources.import @@ -0,0 +1,13 @@ +[remap] + +importer="godot_xterm_xrdb_importer" +type="Theme" +path="res://.import/Test2.Xresources-2344fb3eca84b06f68214bc0cdb6b0ab.res" + +[deps] + +source_file="res://test/import_plugins/xrdb/Test2.Xresources" +dest_files=[ "res://.import/Test2.Xresources-2344fb3eca84b06f68214bc0cdb6b0ab.res" ] + +[params] + diff --git a/test/import_plugins/xrdb/Test3.xresources b/test/import_plugins/xrdb/Test3.xresources new file mode 100644 index 0000000..9184025 --- /dev/null +++ b/test/import_plugins/xrdb/Test3.xresources @@ -0,0 +1,36 @@ +! special +*.foreground: #eddfe4 +*.background: #000000 +*.cursorColor: #eddfe4 + +! black +*.color0: #000000 +*.color8: #6da3b8 + +! red +*.color1: #1b0c13 +*.color9: #ca956c + +! green +*.color2: #351b27 +*.color10: #7ca7b9 + +! yellow +*.color3: #563042 +*.color11: #a2c9bc + +! blue +*.color4: #814b64 +*.color12: #9aad72 + +! magenta +*.color5: #b56b8d +*.color13: #82d0b7 + +! cyan +*.color6: #d0a2b6 +*.color14: #ae96d0 + +! white +*.color7: #eddfe4 +*.color15: #e6bfcf diff --git a/test/import_plugins/xrdb/Test3.xresources.import b/test/import_plugins/xrdb/Test3.xresources.import new file mode 100644 index 0000000..b3102ae --- /dev/null +++ b/test/import_plugins/xrdb/Test3.xresources.import @@ -0,0 +1,13 @@ +[remap] + +importer="godot_xterm_xrdb_importer" +type="Theme" +path="res://.import/Test3.xresources-bec998d839dd0fca9b82fa130c7bada8.res" + +[deps] + +source_file="res://test/import_plugins/xrdb/Test3.xresources" +dest_files=[ "res://.import/Test3.xresources-bec998d839dd0fca9b82fa130c7bada8.res" ] + +[params] + diff --git a/test/import_plugins/xrdb/xrdb_import_plugin.test.gd b/test/import_plugins/xrdb/xrdb_import_plugin.test.gd new file mode 100644 index 0000000..d38e33c --- /dev/null +++ b/test/import_plugins/xrdb/xrdb_import_plugin.test.gd @@ -0,0 +1,95 @@ +extends "res://addons/gut/test.gd" +# Many themes in a similar format to Test1.xrdb can be found here: +# https://github.com/mbadolato/iTerm2-Color-Schemes/tree/master/xrdb +# Test2.Xresources and Test3.xresources randomly generated at https://terminal.sexy +# and downloaded in Xresources format. + + +func test_xrdb(): + var theme = preload("./Test1.xrdb") + assert_true(theme is Theme) + + var map := { + "Black": "#000000", + "Red": "#000001", + "Green": "#000002", + "Yellow": "#000003", + "Blue": "#000004", + "Magenta": "#000005", + "Cyan": "#000006", + "Light Grey": "#000007", + "Dark Grey": "#000008", + "Light Red": "#000009", + "Light Green": "#000010", + "Light Yellow": "#000011", + "Light Blue": "#000012", + "Light Magenta": "#000013", + "Light Cyan": "#000014", + "White": "#000015", + "Background": "#100000", + "Foreground": "#200000", + "Cursor": "#300000", + } + + for key in map.keys(): + assert_eq(theme.get_color(key, "Terminal"), Color(map[key]), key) + + +func test_Xresources(): + var theme = preload("./Test2.Xresources") + assert_true(theme is Theme) + + var map := { + "Black": "#282A2E", + "Red": "#A54242", + "Green": "#8C9440", + "Yellow": "#DE935F", + "Blue": "#5F819D", + "Magenta": "#85678F", + "Cyan": "#5E8D87", + "Light Grey": "#707880", + "Dark Grey": "#373B41", + "Light Red": "#CC6666", + "Light Green": "#B5BD68", + "Light Yellow": "#F0C674", + "Light Blue": "#81A2BE", + "Light Magenta": "#B294BB", + "Light Cyan": "#8ABEB7", + "White": "#C5C8C6", + "Background": "#1D1F21", + "Foreground": "#C5C8C6", + "Cursor": "#C5C8C6", + } + + for key in map.keys(): + assert_eq(theme.get_color(key, "Terminal"), Color(map[key]), key) + + +func test_xresources(): + var theme = preload("./Test3.xresources") + assert_true(theme is Theme) + + var map := { + "Black": "#000000", + "Red": "#1B0C13", + "Green": "#351B27", + "Yellow": "#563042", + "Blue": "#814B64", + "Magenta": "#B56B8D", + "Cyan": "#D0A2B6", + "Light Grey": "#EDDFE4", + "Dark Grey": "#6DA3B8", + "Light Red": "#CA956C", + "Light Green": "#7CA7B9", + "Light Yellow": "#A2C9BC", + "Light Blue": "#9AAD72", + "Light Magenta": "#82D0B7", + "Light Cyan": "#AE96D0", + "White": "#E6BFCF", + "Background": "#000000", + "Foreground": "#EDDFE4", + "Cursor": "#EDDFE4", + } + + for key in map.keys(): + assert_eq(theme.get_color(key, "Terminal"), Color(map[key]), key)