Sublime Forum

Is there an API for getting theme/scheme colors?

#1

The title says it all I think. I want to programatically create an image based off of some colors in either the theme or the view’s color scheme. Is this possible?

0 Likes

#2
  1. Find out the currently used theme or scheme:
scheme_path = view.settings().get("color_scheme") # resource path
theme_name = sublime.load_settings("Preferences.sublime-settings").get("theme") # file name
  1. Get the files
scheme_content = sublime.load_binary_resource(scheme_path)
theme_paths = sublime.find_resources(theme_name)
theme_contents = [sublime.load_resource(x) for x in theme_paths]
  1. Parse files
scheme_data = plistlib.parsePlistFromBytes(scheme_content)
theme_data = [sublime.decode_value(x) for x in theme_contents]

All theme files of the same name are joined and apply their styles in an overriding fashion, similar to how Settings get overridden. That means: The Default package comes first, then other packages (in lexicographical order; archived first, then unarchived) and finally the User package. In most circumstances that doesn’t matter, but it will for the “boxy theme addons”, for example. Fortunately, sublime.find_resources follows that order already.

See also this section for a detailed overview on package (and resource) load order.

5 Likes

#3

Thanks, this looks pretty complex but workable.

0 Likes

#4

Do you know if there are any python libraries in the default sublime text install that can reliably parse popupCss to extract background and foreground colors?

0 Likes

#5

No, since they are CSS. For https://github.com/FichteFoll/CSScheme I embedded a small package named “tinycss” which was easy to extend and should work for you too, but requires some digging.

0 Likes

#6

I think this doesn’t gives when it is .sublime-color-scheme

0 Likes

#7

It does for me at least.

Python 3.3>>> view.settings().get("color_scheme")
'Material (Dark HC).sublime-color-scheme'
0 Likes

#8

But it doesn’t the path.
Anyways, I found a way in some plugin’s source code

DEFAULT_CS = 'Packages/Color Scheme - Default/Mariana.sublime-color-scheme'

...
    def get_scheme_path(view, setting_name):
        # Be lazy here and don't consider invalid values
        scheme_setting = view.settings().get(setting_name, DEFAULT_CS)
        if scheme_setting == 'auto':
            return 'auto'
        elif "/" not in scheme_setting:
            return ResourcePath.glob_resources(scheme_setting)[0]
        else:
            return ResourcePath(scheme_setting)

Btw is there a normal way to find those things? The API reference doesn’t provide much information.

0 Likes

#9
>>> sublime.find_resources('Mariana.sublime-color-scheme')
['Packages/Color Scheme - Default/Mariana.sublime-color-scheme', 'Packages/LSP/ColorSchemes/Mariana.sublime-color-scheme']
1 Like

#10

I’m not sure what anyone is trying to accomplish here, but it’s probably worth pointing out that since build 3150 view.style() will return you the current global style information for whatever the color scheme in the view is set to, and view.style_for_scope() will tell you the colors and styles applied to various scopes.

Taken together, for a large variety of purposes it’s no longer required to try and chase down all of the color scheme files and overrides and merge them yourself.

Note also that when you do that, sublime-color-scheme and tmTheme files of the same name are also combined together when loaded. So, doing this correctly manually is also more complicated than it was back when this thread was initially created.

2 Likes