How do you change color scheme in Sublime Text 3 ? Maybe select from Menu, but if you change color scheme many times a day, it will be very cumbersome. Today I want to change the Color Theme of Sublime Text editor, but the mouse is unavailable, I find there are no way to do this in the GUI purely by keyboard. You can Press Alt + n to open Preferences Menu Item, but can not locate Color Theme Menu Item with keyboard (my keyboard has no arrow keys).

sublime color theme switch menu item

One important thing about Color Theme is we need different Color Theme at different times, anyone need to use computer for serious stuff need at least two Color Theme, one for day light and one for dark environment. We also need to switch them very fast, like one click or a command. This especially important to editor and browser which we takes a lot of time looking at.

Whenever I install Google Chrome I always install the dark theme extension like Hacker Vision or accessibility extension like High Contrast. For Firefox there is a eyeguard plugin.

The thing I want from many software is the ability to change theme automatically according to the environment for example by the time, but seems no one provide it, if its not providing it, there should be manual way to do it.

This is easy if you are using Emacs, you have ELISP at your disposal, you can write some simple ELISP code to do the theme changing action and bind them to whatever keyboard shortcut you like, here is two functions represent two themes:

 
(defun day ()
  (interactive)
  (load-theme 'leuven)
  (font-set)
)
 
(defun dark ()
  (interactive)
  (load-theme 'wombat)
  (font-set)
)
 
 

Change color theme in Emacs is easy, load the script when Emacs started and press M-x:day or M-x:dark. This is exactly what I want to do in Sublime. But there seems no way to load Python script directly in Sublime, but you can write your Python code in Sublime package and call the code through command palette.

Changes Color Scheme by editing preferences settings

If you don't want to use the cumbersome way of selecting in Menu items, you can directly edit the preferences setting. First press Ctrl + Shift + p open the command palette and input "user", Sublime is very smart the Preferences: Settings - User is present in the first position of the drop down result list. Open the file and prepare two configuration line for color_scheme

 
    "color_scheme": "Packages/Color Scheme - Default/Mac Classic.tmTheme",
    //"color_scheme": "Packages/Color Scheme - Default/Solarized (Dark).tmTheme",
 

Use one of the schemes and comment out the other one then save the file, the changes immediately applied when saving.

Sublime don't support comment in configuration JSON file

There is a big disadvantage of the way above, that Sublime will overwrite configuration files and delete all comments whenever you change the settings from the Menu system, for example, select a Color Scheme from the Menu. I was a little surprised when I found that content of file Preferences.sublime-settings were restored and all comments were lost.

So you better first backup your file and always editing the backup file and copy to Sublime folder.

This problem actually is about JSON itself, writing comments in JSON is not natively supported, both the syntax and parsing engine, JSON is not a programming language, when parser read it and parsed it, all comments are lost, and when it being dumped back to string, its impossible to restore their original text layout. Not only comments will lost, if you add space tab when editing, they will becomes real tab after dumping.

Using ColorScheme Selector

If you don't want to edit Preferences.sublime-settings each time when you want to switch Color Scheme, you can use the package ColorScheme Selector.

You should have installed Package Control, press ctrl + shift + p and select Package Control: Install Package, intput "colorschemeselector" you will see the package, press Enter to install it.

Now you can fuzzy matching switch the Color Scheme by execute the command ColorSchemeSelector: Select Color Scheme.

As you can see, we still need quite a lot of keystrokes to switch the Color Scheme. And we also need to remember the part of the ColorScheme name. Its better to use some kind of abstraction names like day and dark. The best solution is we can input "day" in command palette and press enter it will switch to bright ColorScheme.

Add customized command to Sublime Command Palette

To add command to command palette, we need to write our own Sublime package. To learn how to create my own package, I checked the content of the ColorSchemeSelector and find its very easy to understand, we don't have to create a brand new package, but simply modify the existing package, the package contains all the source code and configuration files that we can change.

You can check the code on github, here is a very simple introduction. Lets see the ColorSchemeSelector.py. To get all available Color Schemes installed:

 
        if int(sublime.version()) > 3000:
            color_schemes = sublime.find_resources("*.tmTheme")
        else:
            color_schemes = [
                "All Hallow's Eve",
                "Amy",
                "Blackboard",
                "Cobalt",
                "Dawn",
                "Eiffel",
                "Espresso Libre",
                "IDLE",
                "LAZY",
                "Mac Classic",
                "MagicWB (Amiga)",
                "Monokai Bright",
                "Monokai",
                "Pastels on Dark",
                "Slush & Poppies",
                "Solarized (Dark)",
                "Solarized (Light)",
                "SpaceCadet",
                "Sunburst",
                "Twilight",
                "Zenburnesque",
                "iPlastic"
            ]
 
 

This is just an array of string, element is the name of Color Scheme. To switch to a Color Scheme,

 
self.set_color_scheme(color_schemes[index])
 

The command is defined in Default.sublime-commands

 
[
    {
            "caption": "ColorSchemeSelector: Select Color Scheme",
            "command": "select_color_scheme"
    },
    {
        "caption": "ColorSchemeSelector: Random Color Scheme",
        "command": "select_color_scheme",
        "args": {"random": true}
    },
    {
        "caption": "ColorSchemeSelector: Previous Color Scheme",
        "command": "select_color_scheme",
        "args": {"direction": "previous"}
    },
    {
        "caption": "ColorSchemeSelector: Next Color Scheme",
        "command": "select_color_scheme",
        "args": {"direction": "next"}
    }
]
 

All commands are handled by run method of the plugin class. It behaves differently by the parameters. We can add more values to the direction parameter and handle them with extra if statements

 
    {
        "caption": "day",
        "command": "select_color_scheme",
        "args": {"direction": "day"}
    },
    {
        "caption": "dark",
        "command": "select_color_scheme",
        "args": {"direction": "dark"}
    }    
 

The changes to move_color_scheme method:

 
    def move_color_scheme(self, color_schemes, direction):        
        def index_containing_substring(the_list, substring):
            for i, s in enumerate(the_list):
                if substring in s:
                    return i
            return -1
 
        current_index = self.current_scheme_index(color_schemes)
        if direction == 'previous':
            index = current_index - 1
        elif direction == 'next':
            index = current_index + 1 if current_index < len(color_schemes) else 0
        elif direction == 'day':
            index = index_containing_substring(color_schemes, 'Mac Classic')
        elif direction == 'dark':
            index = index_containing_substring(color_schemes, 'Pastels on Dark')
        else:
            raise ValueError
        self.set_color_scheme(color_schemes[index])
 

When the day command is executed, we looking for 'Mac Classic' scheme in Color Scheme array and call set_color_scheme method with the index it returns. Now you will see them in command palette:

The sublime package files are just zip package, you should open it with a zip viewer and extract out the files, after changing the files, put them back to the zip package and restart Sublime.