Repository: ansible/ansible-navigator (language: python)

Issue:
Pare/remove `share` dir
As we've already encountered, the `share` dir can cause problems during development and packaging. It seems like most of the items there should just be under various datafile subpackages in the main project tree, and the couple of items that we really want to be user-configurable/augmentable should just be loadable from config dirs (which can be located using something akin to what's there now). At first blush, it seems like themes are the only item that currently falls into that category, or am I wrong?

My primary concern is that we don't repeat the mistakes of `/etc/ansible.cfg` and never being able to effectively change or augment defaults by laying down a live all-encompassing config file.


Discussion / hints:
Related to https://github.com/ansible/ansible-navigator/issues/550?
This PR demonstrates how to write the image instrospection script to a temp directory and mount that https://github.com/ansible/ansible-navigator/pull/1153

Fix patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index d59426b93..3d9c7f533 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -50,11 +50,6 @@ repos:
     rev: v1.3.1
     hooks:
       - id: remove-tabs
-        exclude: |
-          (?x)
-          ^
-            share/ansible_navigator/themes/dark_vs\.json
-          $
 
   - repo: https://github.com/pre-commit/pre-commit-hooks.git
     rev: v4.4.0
diff --git a/cspell.config.yaml b/cspell.config.yaml
index 08f86ef2f..4a6ec7cf3 100644
--- a/cspell.config.yaml
+++ b/cspell.config.yaml
@@ -29,7 +29,7 @@ ignorePaths:
   # All grammar (text-mate) tokenization files
   - share/ansible_navigator/grammar/*.json
   # Theme files
-  - share/ansible_navigator/themes/*.json
+  - src/ansible_navigator/data/themes/*.json
   # Anything in the vendored tokenization directory
   - src/ansible_navigator/tm_tokenize/*
   # requirements.txt is generated
diff --git a/share/ansible_navigator/themes/dark_vs.json b/share/ansible_navigator/themes/dark_vs.json
deleted file mode 100644
index 84a656d75..000000000
--- a/share/ansible_navigator/themes/dark_vs.json
+++ /dev/null
@@ -1,373 +0,0 @@
-
-
-{
-	"$schema": "vscode://schemas/color-theme",
-	"name": "Dark (Visual Studio)",
-	"include": "./dark_defaults.json",
-	"tokenColors": [
-		{
-			"scope": [
-				"meta.embedded",
-				"source.groovy.embedded"
-			],
-			"settings": {
-				"foreground": "#D4D4D4"
-			}
-		},
-		{
-			"scope": "emphasis",
-			"settings": {
-				"fontStyle": "italic"
-			}
-		},
-		{
-			"scope": "strong",
-			"settings": {
-				"fontStyle": "bold"
-			}
-		},
-		{
-			"scope": "header",
-			"settings": {
-				"foreground": "#000080"
-			}
-		},
-		{
-			"scope": "comment",
-			"settings": {
-				"foreground": "#6A9955"
-			}
-		},
-		{
-			"scope": "constant.language",
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": [
-				"constant.numeric",
-				"variable.other.enummember",
-				"keyword.operator.plus.exponent",
-				"keyword.operator.minus.exponent"
-			],
-			"settings": {
-				"foreground": "#b5cea8"
-			}
-		},
-		{
-			"scope": "constant.regexp",
-			"settings": {
-				"foreground": "#646695"
-			}
-		},
-		{
-			"scope": "entity.name.tag",
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "entity.name.tag.css",
-			"settings": {
-				"foreground": "#d7ba7d"
-			}
-		},
-		{
-			"scope": "entity.other.attribute-name",
-			"settings": {
-				"foreground": "#9cdcfe"
-			}
-		},
-		{
-			"scope": [
-				"entity.other.attribute-name.class.css",
-				"entity.other.attribute-name.class.mixin.css",
-				"entity.other.attribute-name.id.css",
-				"entity.other.attribute-name.parent-selector.css",
-				"entity.other.attribute-name.pseudo-class.css",
-				"entity.other.attribute-name.pseudo-element.css",
-				"source.css.less entity.other.attribute-name.id",
-				"entity.other.attribute-name.scss"
-			],
-			"settings": {
-				"foreground": "#d7ba7d"
-			}
-		},
-		{
-			"scope": "invalid",
-			"settings": {
-				"foreground": "#f44747"
-			}
-		},
-		{
-			"scope": "markup.underline",
-			"settings": {
-				"fontStyle": "underline"
-			}
-		},
-		{
-			"scope": "markup.bold",
-			"settings": {
-				"fontStyle": "bold",
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "markup.heading",
-			"settings": {
-				"fontStyle": "bold",
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "markup.italic",
-			"settings": {
-				"fontStyle": "italic"
-			}
-		},
-		{
-			"scope": "markup.inserted",
-			"settings": {
-				"foreground": "#b5cea8"
-			}
-		},
-		{
-			"scope": "markup.deleted",
-			"settings": {
-				"foreground": "#ce9178"
-			}
-		},
-		{
-			"scope": "markup.changed",
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "punctuation.definition.quote.begin.markdown",
-			"settings": {
-				"foreground": "#6A9955"
-			}
-		},
-		{
-			"scope": "punctuation.definition.list.begin.markdown",
-			"settings": {
-				"foreground": "#6796e6"
-			}
-		},
-		{
-			"scope": "markup.inline.raw",
-			"settings": {
-				"foreground": "#ce9178"
-			}
-		},
-		{
-			"name": "brackets of XML/HTML tags",
-			"scope": "punctuation.definition.tag",
-			"settings": {
-				"foreground": "#808080"
-			}
-		},
-		{
-			"scope": [
-				"meta.preprocessor",
-				"entity.name.function.preprocessor"
-			],
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "meta.preprocessor.string",
-			"settings": {
-				"foreground": "#ce9178"
-			}
-		},
-		{
-			"scope": "meta.preprocessor.numeric",
-			"settings": {
-				"foreground": "#b5cea8"
-			}
-		},
-		{
-			"scope": "meta.structure.dictionary.key.python",
-			"settings": {
-				"foreground": "#9cdcfe"
-			}
-		},
-		{
-			"scope": "meta.diff.header",
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "storage",
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "storage.type",
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": [
-				"storage.modifier",
-				"keyword.operator.noexcept"
-			],
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": [
-				"string",
-				"meta.embedded.assembly"
-			],
-			"settings": {
-				"foreground": "#ce9178"
-			}
-		},
-		{
-			"scope": "string.tag",
-			"settings": {
-				"foreground": "#ce9178"
-			}
-		},
-		{
-			"scope": "string.value",
-			"settings": {
-				"foreground": "#ce9178"
-			}
-		},
-		{
-			"scope": "string.regexp",
-			"settings": {
-				"foreground": "#d16969"
-			}
-		},
-		{
-			"name": "String interpolation",
-			"scope": [
-				"punctuation.definition.template-expression.begin",
-				"punctuation.definition.template-expression.end",
-				"punctuation.section.embedded"
-			],
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"name": "Reset JavaScript string interpolation expression",
-			"scope": [
-				"meta.template.expression"
-			],
-			"settings": {
-				"foreground": "#d4d4d4"
-			}
-		},
-		{
-			"scope": [
-				"support.type.vendored.property-name",
-				"support.type.property-name",
-				"variable.css",
-				"variable.scss",
-				"variable.other.less",
-				"source.coffee.embedded"
-			],
-			"settings": {
-				"foreground": "#9cdcfe"
-			}
-		},
-		{
-			"scope": "keyword",
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "keyword.control",
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "keyword.operator",
-			"settings": {
-				"foreground": "#d4d4d4"
-			}
-		},
-		{
-			"scope": [
-				"keyword.operator.new",
-				"keyword.operator.expression",
-				"keyword.operator.cast",
-				"keyword.operator.sizeof",
-				"keyword.operator.alignof",
-				"keyword.operator.typeid",
-				"keyword.operator.alignas",
-				"keyword.operator.instanceof",
-				"keyword.operator.logical.python",
-				"keyword.operator.wordlike"
-			],
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "keyword.other.unit",
-			"settings": {
-				"foreground": "#b5cea8"
-			}
-		},
-		{
-			"scope": [
-				"punctuation.section.embedded.begin.php",
-				"punctuation.section.embedded.end.php"
-			],
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		},
-		{
-			"scope": "support.function.git-rebase",
-			"settings": {
-				"foreground": "#9cdcfe"
-			}
-		},
-		{
-			"scope": "constant.sha.git-rebase",
-			"settings": {
-				"foreground": "#b5cea8"
-			}
-		},
-		{
-			"name": "coloring of the Java import and package identifiers",
-			"scope": [
-				"storage.modifier.import.java",
-				"variable.language.wildcard.java",
-				"storage.modifier.package.java"
-			],
-			"settings": {
-				"foreground": "#d4d4d4"
-			}
-		},
-		{
-			"name": "this.self",
-			"scope": "variable.language",
-			"settings": {
-				"foreground": "#569cd6"
-			}
-		}
-	],
-	"semanticTokenColors": {
-		"newOperator": "#d4d4d4",
-		"stringLiteral": "#ce9178",
-		"customLiteral": "#D4D4D4",
-		"numberLiteral": "#b5cea8"
-	}
-}
diff --git a/share/ansible_navigator/themes/terminal_colors.json b/share/ansible_navigator/themes/terminal_colors.json
deleted file mode 100644
index 35472c326..000000000
--- a/share/ansible_navigator/themes/terminal_colors.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-    "terminal.ansiBlack": "#000000",
-    "terminal.ansiRed": "#cd3131",
-    "terminal.ansiGreen": "#0DBC79",
-    "terminal.ansiYellow": "#e5e510",
-    "terminal.ansiBlue": "#2472c8",
-    "terminal.ansiMagenta": "#bc3fbc",
-    "terminal.ansiCyan": "#11a8cd",
-    "terminal.ansiWhite": "#e5e5e5",
-    "terminal.ansiBrightBlack": "#666666",
-    "terminal.ansiBrightRed": "#f14c4c",
-    "terminal.ansiBrightGreen": "#23d18b",
-    "terminal.ansiBrightYellow": "#f5f543",
-    "terminal.ansiBrightBlue": "#d670d6",
-    "terminal.ansiBrightMagenta": "#d670d6",
-    "terminal.ansiBrightCyan": "#29b8db",
-    "terminal.ansiBrightWhite": "#e5e5e5"
-}
diff --git a/src/ansible_navigator/action_runner.py b/src/ansible_navigator/action_runner.py
index a5a437332..e9878a54d 100644
--- a/src/ansible_navigator/action_runner.py
+++ b/src/ansible_navigator/action_runner.py
@@ -20,6 +20,8 @@
 from ansible_navigator.actions import run_action
 from .action_base import ActionBase
 from .configuration_subsystem.definitions import ApplicationConfiguration
+from .constants import TERMINAL_COLORS_PATH
+from .constants import THEME_PATH
 from .steps import Steps
 from .ui_framework import Interaction
 from .ui_framework import UIConfig
@@ -36,8 +38,6 @@
     Window = Any
 
 DEFAULT_REFRESH = 100
-DEFAULT_COLORS = "terminal_colors.json"
-THEME = "dark_vs.json"
 
 
 class ActionRunner(ActionBase):
@@ -59,16 +59,17 @@ def initialize_ui(self, refresh: int) -> None:
         :type refresh: int
         """
         share_directory = self._args.internals.share_directory
-        theme_dir = os.path.join(share_directory, "themes")
 
         config = UIConfig(
             color=self._args.display_color,
             colors_initialized=False,
             grammar_dir=os.path.join(share_directory, "grammar"),
             osc4=self._args.osc4,
-            terminal_colors_path=os.path.join(theme_dir, DEFAULT_COLORS),
-            theme_path=os.path.join(theme_dir, THEME),
+            terminal_colors_path=TERMINAL_COLORS_PATH,
+            theme_path=THEME_PATH,
         )
+        self._logger.debug("theme path = %s", config.theme_path)
+        self._logger.debug("terminal colors path = %s", config.terminal_colors_path)
 
         self._ui = UserInterface(
             screen_min_height=3,
diff --git a/src/ansible_navigator/constants.py b/src/ansible_navigator/constants.py
new file mode 100644
index 000000000..46f31219a
--- /dev/null
+++ b/src/ansible_navigator/constants.py
@@ -0,0 +1,15 @@
+"""Constants for ansible-navigator."""
+
+from .utils.compatibility import Traversable
+from .utils.compatibility import importlib_resources
+
+
+PKG_NAME: str = "ansible_navigator"
+DATA_DIR: Traversable = importlib_resources.files(PKG_NAME).joinpath("data")
+
+THEME_DIR: Traversable = DATA_DIR.joinpath("themes")
+THEME_NAME: str = "dark_vs.json"
+THEME_PATH: Traversable = THEME_DIR.joinpath(THEME_NAME)
+
+TERMINAL_COLORS: str = "terminal_colors.json"
+TERMINAL_COLORS_PATH: Traversable = THEME_DIR.joinpath(TERMINAL_COLORS)
diff --git a/src/ansible_navigator/data/themes/dark_vs.json b/src/ansible_navigator/data/themes/dark_vs.json
new file mode 100644
index 000000000..8e5c9cb0e
--- /dev/null
+++ b/src/ansible_navigator/data/themes/dark_vs.json
@@ -0,0 +1,357 @@
+{
+  "$schema": "vscode://schemas/color-theme",
+  "name": "Dark (Visual Studio)",
+  "include": "./dark_defaults.json",
+  "tokenColors": [
+    {
+      "scope": ["meta.embedded", "source.groovy.embedded"],
+      "settings": {
+        "foreground": "#D4D4D4"
+      }
+    },
+    {
+      "scope": "emphasis",
+      "settings": {
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": "strong",
+      "settings": {
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "scope": "header",
+      "settings": {
+        "foreground": "#000080"
+      }
+    },
+    {
+      "scope": "comment",
+      "settings": {
+        "foreground": "#6A9955"
+      }
+    },
+    {
+      "scope": "constant.language",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": [
+        "constant.numeric",
+        "variable.other.enummember",
+        "keyword.operator.plus.exponent",
+        "keyword.operator.minus.exponent"
+      ],
+      "settings": {
+        "foreground": "#b5cea8"
+      }
+    },
+    {
+      "scope": "constant.regexp",
+      "settings": {
+        "foreground": "#646695"
+      }
+    },
+    {
+      "scope": "entity.name.tag",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "entity.name.tag.css",
+      "settings": {
+        "foreground": "#d7ba7d"
+      }
+    },
+    {
+      "scope": "entity.other.attribute-name",
+      "settings": {
+        "foreground": "#9cdcfe"
+      }
+    },
+    {
+      "scope": [
+        "entity.other.attribute-name.class.css",
+        "entity.other.attribute-name.class.mixin.css",
+        "entity.other.attribute-name.id.css",
+        "entity.other.attribute-name.parent-selector.css",
+        "entity.other.attribute-name.pseudo-class.css",
+        "entity.other.attribute-name.pseudo-element.css",
+        "source.css.less entity.other.attribute-name.id",
+        "entity.other.attribute-name.scss"
+      ],
+      "settings": {
+        "foreground": "#d7ba7d"
+      }
+    },
+    {
+      "scope": "invalid",
+      "settings": {
+        "foreground": "#f44747"
+      }
+    },
+    {
+      "scope": "markup.underline",
+      "settings": {
+        "fontStyle": "underline"
+      }
+    },
+    {
+      "scope": "markup.bold",
+      "settings": {
+        "fontStyle": "bold",
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "markup.heading",
+      "settings": {
+        "fontStyle": "bold",
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "markup.italic",
+      "settings": {
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": "markup.inserted",
+      "settings": {
+        "foreground": "#b5cea8"
+      }
+    },
+    {
+      "scope": "markup.deleted",
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "scope": "markup.changed",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "punctuation.definition.quote.begin.markdown",
+      "settings": {
+        "foreground": "#6A9955"
+      }
+    },
+    {
+      "scope": "punctuation.definition.list.begin.markdown",
+      "settings": {
+        "foreground": "#6796e6"
+      }
+    },
+    {
+      "scope": "markup.inline.raw",
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "name": "brackets of XML/HTML tags",
+      "scope": "punctuation.definition.tag",
+      "settings": {
+        "foreground": "#808080"
+      }
+    },
+    {
+      "scope": ["meta.preprocessor", "entity.name.function.preprocessor"],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "meta.preprocessor.string",
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "scope": "meta.preprocessor.numeric",
+      "settings": {
+        "foreground": "#b5cea8"
+      }
+    },
+    {
+      "scope": "meta.structure.dictionary.key.python",
+      "settings": {
+        "foreground": "#9cdcfe"
+      }
+    },
+    {
+      "scope": "meta.diff.header",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "storage",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "storage.type",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": ["storage.modifier", "keyword.operator.noexcept"],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": ["string", "meta.embedded.assembly"],
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "scope": "string.tag",
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "scope": "string.value",
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "scope": "string.regexp",
+      "settings": {
+        "foreground": "#d16969"
+      }
+    },
+    {
+      "name": "String interpolation",
+      "scope": [
+        "punctuation.definition.template-expression.begin",
+        "punctuation.definition.template-expression.end",
+        "punctuation.section.embedded"
+      ],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "name": "Reset JavaScript string interpolation expression",
+      "scope": ["meta.template.expression"],
+      "settings": {
+        "foreground": "#d4d4d4"
+      }
+    },
+    {
+      "scope": [
+        "support.type.vendored.property-name",
+        "support.type.property-name",
+        "variable.css",
+        "variable.scss",
+        "variable.other.less",
+        "source.coffee.embedded"
+      ],
+      "settings": {
+        "foreground": "#9cdcfe"
+      }
+    },
+    {
+      "scope": "keyword",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "keyword.control",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "keyword.operator",
+      "settings": {
+        "foreground": "#d4d4d4"
+      }
+    },
+    {
+      "scope": [
+        "keyword.operator.new",
+        "keyword.operator.expression",
+        "keyword.operator.cast",
+        "keyword.operator.sizeof",
+        "keyword.operator.alignof",
+        "keyword.operator.typeid",
+        "keyword.operator.alignas",
+        "keyword.operator.instanceof",
+        "keyword.operator.logical.python",
+        "keyword.operator.wordlike"
+      ],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "keyword.other.unit",
+      "settings": {
+        "foreground": "#b5cea8"
+      }
+    },
+    {
+      "scope": [
+        "punctuation.section.embedded.begin.php",
+        "punctuation.section.embedded.end.php"
+      ],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "support.function.git-rebase",
+      "settings": {
+        "foreground": "#9cdcfe"
+      }
+    },
+    {
+      "scope": "constant.sha.git-rebase",
+      "settings": {
+        "foreground": "#b5cea8"
+      }
+    },
+    {
+      "name": "coloring of the Java import and package identifiers",
+      "scope": [
+        "storage.modifier.import.java",
+        "variable.language.wildcard.java",
+        "storage.modifier.package.java"
+      ],
+      "settings": {
+        "foreground": "#d4d4d4"
+      }
+    },
+    {
+      "name": "this.self",
+      "scope": "variable.language",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    }
+  ],
+  "semanticTokenColors": {
+    "newOperator": "#d4d4d4",
+    "stringLiteral": "#ce9178",
+    "customLiteral": "#D4D4D4",
+    "numberLiteral": "#b5cea8"
+  }
+}
diff --git a/src/ansible_navigator/data/themes/terminal_colors.json b/src/ansible_navigator/data/themes/terminal_colors.json
new file mode 100644
index 000000000..7ab354532
--- /dev/null
+++ b/src/ansible_navigator/data/themes/terminal_colors.json
@@ -0,0 +1,18 @@
+{
+  "terminal.ansiBlack": "#000000",
+  "terminal.ansiRed": "#cd3131",
+  "terminal.ansiGreen": "#0DBC79",
+  "terminal.ansiYellow": "#e5e510",
+  "terminal.ansiBlue": "#2472c8",
+  "terminal.ansiMagenta": "#bc3fbc",
+  "terminal.ansiCyan": "#11a8cd",
+  "terminal.ansiWhite": "#e5e5e5",
+  "terminal.ansiBrightBlack": "#666666",
+  "terminal.ansiBrightRed": "#f14c4c",
+  "terminal.ansiBrightGreen": "#23d18b",
+  "terminal.ansiBrightYellow": "#f5f543",
+  "terminal.ansiBrightBlue": "#d670d6",
+  "terminal.ansiBrightMagenta": "#d670d6",
+  "terminal.ansiBrightCyan": "#29b8db",
+  "terminal.ansiBrightWhite": "#e5e5e5"
+}
diff --git a/src/ansible_navigator/ui_framework/colorize.py b/src/ansible_navigator/ui_framework/colorize.py
index ec1ed71ac..0cc721a72 100644
--- a/src/ansible_navigator/ui_framework/colorize.py
+++ b/src/ansible_navigator/ui_framework/colorize.py
@@ -9,7 +9,6 @@
 import functools
 import json
 import logging
-import os
 import re
 
 from itertools import chain
@@ -17,6 +16,7 @@
 from ..tm_tokenize.grammars import Grammars
 from ..tm_tokenize.region import Regions
 from ..tm_tokenize.tokenize import tokenize
+from ..utils.compatibility import Traversable
 from .curses_defs import CursesLine
 from .curses_defs import CursesLinePart
 from .curses_defs import CursesLines
@@ -84,7 +84,7 @@ def get_color_and_style(self, scope: str) -> tuple[RgbTuple | None, str | None]:
 class Colorize:
     """Functionality for coloring."""
 
-    def __init__(self, grammar_dir: str, theme_path: str):
+    def __init__(self, grammar_dir: str, theme_path: Traversable):
         """Initialize the colorizer.
 
         :param grammar_dir: The directory in which the grammars reside
@@ -98,7 +98,7 @@ def __init__(self, grammar_dir: str, theme_path: str):
 
     def _load(self):
         """Load the color scheme from the file system."""
-        with open(os.path.join(self._theme_path), encoding="utf-8") as fh:
+        with self._theme_path.open(mode="r", encoding="utf-8") as fh:
             self._schema = ColorSchema(json.load(fh))
 
     @staticmethod
diff --git a/src/ansible_navigator/ui_framework/curses_window.py b/src/ansible_navigator/ui_framework/curses_window.py
index 14194a8b9..0dbc988af 100644
--- a/src/ansible_navigator/ui_framework/curses_window.py
+++ b/src/ansible_navigator/ui_framework/curses_window.py
@@ -195,7 +195,7 @@ def _set_colors(self) -> None:
         self._logger.debug("term_osc4_support: %s", self._term_osc4_support)
 
         if self._term_osc4_support:
-            with open(self._ui_config.terminal_colors_path, encoding="utf-8") as fh:
+            with self._ui_config.terminal_colors_path.open(mode="r", encoding="utf-8") as fh:
                 colors = json.load(fh)
 
             for color_name, color_hex in colors.items():
diff --git a/src/ansible_navigator/ui_framework/ui_config.py b/src/ansible_navigator/ui_framework/ui_config.py
index 7c9cf1726..2a6785ea5 100644
--- a/src/ansible_navigator/ui_framework/ui_config.py
+++ b/src/ansible_navigator/ui_framework/ui_config.py
@@ -2,6 +2,8 @@
 
 from dataclasses import dataclass
 
+from ..utils.compatibility import Traversable
+
 
 @dataclass
 class UIConfig:
@@ -21,6 +23,6 @@ class gets threaded throughout most of the UI system, so it can be used for
     #: Indicates if terminal support for OSC4 is enabled
     osc4: bool
     #: The path to the 16 terminal color map
-    terminal_colors_path: str
+    terminal_colors_path: Traversable
     #: The path to the theme file
-    theme_path: str
+    theme_path: Traversable
diff --git a/src/ansible_navigator/utils/compatibility.py b/src/ansible_navigator/utils/compatibility.py
index bca661324..3b1a6b6a7 100644
--- a/src/ansible_navigator/utils/compatibility.py
+++ b/src/ansible_navigator/utils/compatibility.py
@@ -20,7 +20,12 @@
 else:
     import zoneinfo
 
+
 if sys.version_info < (3, 9):
     import importlib_resources
+
+    from importlib_resources.abc import Traversable
 else:
     import importlib.resources as importlib_resources
+
+    from importlib.abc import Traversable
diff --git a/src/ansible_navigator/utils/print.py b/src/ansible_navigator/utils/print.py
index 9200e69cf..14d277e9f 100644
--- a/src/ansible_navigator/utils/print.py
+++ b/src/ansible_navigator/utils/print.py
@@ -7,6 +7,7 @@
 
 from sys import stdout
 
+from ansible_navigator.constants import THEME_PATH
 from ansible_navigator.content_defs import ContentFormat
 from ansible_navigator.content_defs import ContentType
 from ansible_navigator.content_defs import ContentView
@@ -81,7 +82,7 @@ def tokenize(
     """
     colorizer = Colorize(
         grammar_dir=os.path.join(share_directory, "grammar"),
-        theme_path=os.path.join(share_directory, "themes", "dark_vs.json"),
+        theme_path=THEME_PATH,
     )
 
     tokenized = colorizer.render(doc=serialized, scope=content_format.value.scope)


Test patch:
diff --git a/tests/unit/ui_framework/test_colorize.py b/tests/unit/ui_framework/test_colorize.py
index a190fedb1..64a69948c 100644
--- a/tests/unit/ui_framework/test_colorize.py
+++ b/tests/unit/ui_framework/test_colorize.py
@@ -6,6 +6,7 @@
 from typing import NamedTuple
 from unittest.mock import patch  # pylint: disable=preferred-module  # FIXME: GH-872
 
+from ansible_navigator.constants import THEME_PATH
 from ansible_navigator.content_defs import ContentFormat
 from ansible_navigator.content_defs import ContentView
 from ansible_navigator.ui_framework.colorize import Colorize
@@ -17,7 +18,6 @@
 SHARE_DIR = os.path.abspath(
     os.path.join(os.path.basename(__file__), "..", "share", "ansible_navigator"),
 )
-THEME_PATH = os.path.join(SHARE_DIR, "themes", "dark_vs.json")
 GRAMMAR_DIR = os.path.join(SHARE_DIR, "grammar")