Sublime Forum

Different color schemes in different windows?

#1

I’ve seen somewhere a statement that different windows (obtained with New Window)
may have different color schemes? Is this true? So far I haven’t been able to make this work.
When I change the color scheme in one window, it changes in the entire sequence of windows that I have open.

0 Likes

#2

Color Schemes can set via project specific settings would apply to all views of a window.

0 Likes

#3

If you’re not using projects, you can also accomplish this with a simple plugin as well because all windows carry project data even if it’s not persisted to disk.

For example if you create a new window, then run this in the console:

window.set_project_data({"settings": {"color_scheme": "Monokai.sublime-color-scheme"}})

All files open in that window will use the Monokai color scheme, unless there is a file-type specific setting that overrides it (like if you want all your Python files to be purple or something).

A plugin would need to be smart enough to pull the project data out first and add this in, since the above will clobber away any open folders, other settings that might be applied by a project, etc.

I’m not sure if there’s a package for that already but such a plugin would be fairly easy to create.

1 Like

#4

I’m aware of this. However, from time to time I would like to open a new window
and make it a different color from the other windows that I have already opened.
Without having a project for it.

I am not quite happy with the solutions above. I think my problem would be solved
if I could start two or more totally independent instances of the editor. How do I do it?

0 Likes

#5

Color scheme can’t be set as “window setting”. So there’s no other solution than using project data, atm.

To run independend installations you’d need multiple portable installations, which don’t share any datal. It would involve to set them up independendly including plugins, settings, … . Doubt it’s a sane solution.

0 Likes

#6

Works for me. Thanks.

0 Likes

#7

As outlined in the Discord conversation from this morning (and also alluded to above) it’s possible to do this sort of thing with a little plugin magic.

An example of such a thing is the below; this provides a select_window_color_scheme command which will adjust the color scheme in use for the current window.

The plugin below includes an input handler that is based on the one in Default/ui.py that allows you to interactively select a color scheme from the list, but with the ability to preview removed and commented to provide more details on what it’s actually doing.

To use this, you first want to create a Default.sublime-commands file in your User package with the following contents (or, if you already have such a file, just add the entry); adjust the caption as desired:

[
    { "caption": "UI: Select Window Color Scheme", 
      "command": "select_window_color_scheme" },
]

Then, add the following plugin to your User package (see How to use Plugins on my YouTube channel if you’re not sure how to do that):

import sublime
import sublime_plugin

import os


# The KIND attached to whatever the default color scheme is when the browser
# open.
CURRENT_KIND = (sublime.KIND_ID_COLOR_GREENISH, "✓", "Current")


class SelectWindowColorSchemeCommand(sublime_plugin.WindowCommand):
    """
    Set the color scheme to be used by all views in the current window to the
    one that is provided. If one is not given, prompt the user in the command
    palette to pick one.

    This will work in any window, wether it has a sublime-project associated
    with it or not. For any window that is associated with a project, this
    will adjust the settings for the project itself on disk.
    """
    def run(self, color_scheme):
        # Get the project data for this window, then get the settings key out
        # of it, creating an empty key if it is not present.
        data = self.window.project_data() or {}
        settings = data.get('settings', {})

        # Set in the setting, the put the settings back into the data and the
        # data back into the window.
        settings["color_scheme"] = color_scheme
        data["settings"] = settings

        self.window.set_project_data(data)

    def input(self, args):
        if "color_scheme" not in args:
            return ColorSchemeInputHandler(self.window)


class ColorSchemeInputHandler(sublime_plugin.ListInputHandler):
    """
    Gather a list of all of the potential color schemes and use them to display
    a list in the command palette to allow the user to pick a color scheme.

    This respects the show_legacy_color_schemes setting, and will show you the
    what color scheme is currently active for this window.

    This is a modified and cut down version of the same input handler from
    Default/ui.py, which is used to prompt for the color scheme to choose when
    you use "UI: Select Color Scheme" in the command palette; this version
    lacks the preview part that lets you see what the color scheme is goign to
    look like.
    """
    def __init__(self, window):
        self.window = window

    def placeholder(self):
        return "Color scheme for the current window"

    def get_files(self):
        """
        Gather a list of all of the tmTheme and sublime-color-scheme files that
        are present, returning a list of tuple that provides the name of the
        file that contains the resource and the value to use as the value of
        the color_scheme setting.
        """
        files = []
        nameset = set()

        # For tmTheme files, the value to use for the setting and the name of
        # the file that they come from are the same, so for each one found
        # add it in.
        #
        # Along the way, track the name of the color scheme, which is based
        # on the name of the file, without path or extension.
        for f in sublime.find_resources('*.tmTheme'):
            files.append((f, f))
            nameset.add(os.path.splitext(os.path.basename(f))[0])

        # Do the same for sublime-color-scheme files too. Here the value to
        # use for the value of color_scheme is the name of the file without
        # the path (unlike for tmTheme) files).
        #
        # This also tracks and does not add this file as a known file if there
        # is a color scheme already known by this name that was contributed
        # from a tmTheme file.
        for f in sublime.find_resources('*.sublime-color-scheme'):
            basename = os.path.basename(f)
            name = os.path.splitext(basename)[0]
            if name not in nameset:
                nameset.add(name)
                files.append((f, basename))

        return files

    def list_items(self):
        # Get the global preferences and wether or not we should be showing
        # the legacy color schemes.
        settings = sublime.load_settings('Preferences.sublime-settings')
        show_legacy = settings.get("show_legacy_color_schemes", False)

        # Grab the current color scheme out of the preferences as a potential
        # default.
        default = settings.get("color_scheme", 'Mariana.sublime-color-scheme')

        # If there is project data in the window, and that project data has
        # settings, and the settings contains a color_scheme setting, then
        # the value of that setting is what the current color scheme should
        # be. Otherwise, use the value from the preferences as a default.
        data = self.window.project_data() or {}
        current_scheme = data.get("settings", {}).get("color_scheme", default)

        # sublime-color-scheme files are unique based on their name, and so the
        # setting can just be the name of the file. For a tmTheme file, they're
        # unique based on the resource path they're loaded from.
        #
        # That is how we gather the list of color schemes below, so here we
        # need to make sure that the color scheme we grabbed out of the
        # settings is as expected.
        if current_scheme.endswith(".sublime-color-scheme"):
            current_scheme = os.path.basename(current_scheme)

        # Gather the list of list entries.
        files = self.get_files()

        items = []
        selected = -1

        # Iterate over the entire list of items that were found and generate
        # list items for display.
        for cs, unique_path in files:
            # Get the name of the package that this color scheme is from, and
            # the name of the scheme itself.
            pkg, basename = os.path.split(cs)
            name = os.path.splitext(basename)[0]

            # If this is a legacy color scheme and the user doesn't want to
            # see those, don't do anything with this one.
            if pkg == "Packages/Color Scheme - Legacy" and not show_legacy:
                continue

            # Apply specific kind information to the currently select color
            # scheme if this is the one; then flag it as the item to select
            # by default.
            kind_info = sublime.KIND_AMBIGUOUS
            if current_scheme and current_scheme == unique_path:
                kind_info = CURRENT_KIND
                selected = len(items)

            # Remove the common prefix on the files.
            if pkg.startswith("Packages/"):
                pkg = pkg[len("Packages/"):]

            # Add in a new item.
            items.append(sublime.ListInputItem(name, unique_path,
                details=pkg,
                kind=kind_info))

        return (items, selected)

With these in place, the command palette will have a new item in it with the caption you specified in the sublime-commands file, and picking it will allow you to select a color scheme and apply it to the current window.

if your window has a sublime-project file attached to it, using this command will modify the project on disk to include the color scheme that you pick here.

3 Likes

#8

I indeed got this running by using different ST versions, but it’d be great if there was a setting for this within Preferences, including the option to set the scheme on a per area basis rather than having to use different windows, especially when using different languages that are better highlighted using different schemes, for example: C# for scripting and .md next to it, for a todo-list.

0 Likes

#9

Open up a C# file, choose Preferences > Settings - Syntax Specific and in the right hand pane include "color_scheme": "Breakers.sublime-color-scheme", as a setting. As soon as you save the file, all C# files will use that color scheme while other file types still use the global settings.

0 Likes