Skip to content

Instantly share code, notes, and snippets.

@zitot
Forked from ebrensi/README.md
Last active December 21, 2023 08:20
Show Gist options
  • Save zitot/5c0e5f1ec42a376f5b3713cacdf6baed to your computer and use it in GitHub Desktop.
Save zitot/5c0e5f1ec42a376f5b3713cacdf6baed to your computer and use it in GitHub Desktop.
Sublime Text 3 plugin to select a color scheme for the current tab only

Installation

Put change_tab_color_scheme.py, change_window_color_scheme.py, and window_color_scheme_event_listener.py in the folder that opens up when you select Preferences > Browse Packages...

Now you have a command called change_tab_color_scheme that you can access from the command window. You can set a key binding by going to Preferences > Key Bindings

I personally like the "ctrl+k", "ctrl+c" sequence. In the {blah}.sublime-keymap file, add the key binding like this...

[
	{
	    "keys": ["ctrl+k", "ctrl+c"],
	    "command": "change_tab_color_scheme"
	}
]

Now you can quickly set the color scheme to whatever you want in each tab.

These color changes are not persisistent.

zitot:

  • This handles windows too. The original author is below, but my version uses an eventlistener, so if you open a new tab, it will propagate the window color scheme. Additionally, new windows will use the default color scheme, and you can have multiple windows with different color schemes active at the same time.x

For changing the window color scheme, I like C-k-c-k

[
	{
	    "keys": ["ctrl+k", "ctrl+c", "ctrl+k"],
	    "command": "change_window_color_scheme"
	}
]

Original Author: https://stackoverflow.com/a/26317770/5039075

Issues

  1. open a folder using File->Open folder.., then click an unopened file from the sidebar to opens a new tab whose name is in italics. Do not make changes to the file, or you lose italics. Run the change_tab_color_scheme command on that tab. Click another file to replace the current file in the tab. You lose the color. I can't figure out how to propagate the previous italics tab color to the new italics tab. (because the buffer id is different, the sheet id is different, and the view id is different). I don't yet understand what is so special about italics tabs. It's arguable that this is the expected behavior, but if you go back to the original file you chagned the color on, it's still gone - whether the color of a tab should propagate to a new file is one thing, but the first file loses its color, too.

  2. When you press escape on the quick panel to cancel making a selection, the selected scheme is still applied to the window except for the active_view. The solution to this involves saving the state of all views and associated color schemes and iterating through those and applying each (as we may have tab color scheme applied to certain tabs)

import sublime
import sublime_plugin
import os
class ChangeTabColorScheme(sublime_plugin.WindowCommand):
def run(self):
window = sublime.active_window()
view = window.active_view()
settings = view.settings()
current_scheme = settings.get('color_scheme', '')
themes = self.installed_themes()
names = sorted(themes)
def change_scheme_window(window, scheme):
for view in window.views():
view.settings().set("color_scheme", scheme)
def make_selection(index):
name = names[index]
fname = themes[name]
settings.set("color_scheme", fname)
#change_scheme_window(window, current_scheme)
def on_done(index):
if index == -1:
#change_scheme_window(window, current_scheme)
settings.set("color_scheme", current_scheme)
return
make_selection(index)
window.show_quick_panel(
names,
on_done,
on_highlight=make_selection
)
def installed_themes(self):
scheme_paths = sublime.find_resources('*.tmTheme')
scheme_paths.extend(
sublime.find_resources('*.sublime-color-scheme')
)
themes = {os.path.basename(path).split(".")[0]: path for path in scheme_paths}
return themes
import sublime
import sublime_plugin
import os
global_data = {}
def setWindowColorScheme(window, scheme):
global_data [window.id()] = scheme
#'window_id': -1, 'current_scheme': -1}
class ChangeWindowColorSchemeCommand(sublime_plugin.WindowCommand):
def change_scheme(self, scheme):
for view in self.window.views():
view.settings().set("color_scheme", scheme)
# def run(self):
# message = 'Enter path to color scheme:'
# path = 'Packages/Color Scheme - Default/Monokai.tmTheme'
# self.window.show_input_panel(message, path, self.change_scheme, None, None)
def run(self):
window = sublime.active_window()
# global_data['window_id'] = window.id()
# print("New window id:", global_data['window_id'])
view = window.active_view()
settings = view.settings()
# print("self.window.id: ",window.id())
current_scheme = settings.get('color_scheme', '')
# global_data['current_scheme'] = current_scheme
# print("current_scheme:", current_scheme)
themes = self.installed_themes()
names = sorted(themes)
def make_selection(index):
name = names[index]
fname = themes[name]
for view in self.window.views():
view.settings().set("color_scheme", fname)
# global_data['current_scheme'] = fname
setWindowColorScheme(window, fname)
# print("globaldata=",global_data)
# window.settings().set("color_scheme", fname)
#change_scheme_window(window, current_scheme)
def on_done(index):
if index == -1:
#change_scheme_window(window, current_scheme)
settings.set("color_scheme", current_scheme)
return
make_selection(index)
window.show_quick_panel(
names,
on_done,
on_highlight=make_selection
)
def installed_themes(self):
scheme_paths = sublime.find_resources('*.tmTheme')
scheme_paths.extend(
sublime.find_resources('*.sublime-color-scheme')
)
themes = {os.path.basename(path).split(".")[0]: path for path in scheme_paths}
return themes
import sublime
import sublime_plugin
# This module must be paired with change_window_color_scheme.py as it imports global_data, a dict, from that module
# on_new/on_load both:
# get the window scheme value from global_data[window().id()] and apply it to the new tab/window
# apply default color scheme if the window id is not found in global_data
# TODO: i'd like to make a special exception for loading a file into an existing view/buffer
# 1. open a folder
# 2. open a file from the sidebar. do not make any changes. its name will appear in italics.
# 3. click another file from the sidebar. it will replace the current file.
# e.g. i open foo.txt in a new tab, apply change_tab_color_scheme.py to give it cobalt instead of monokai
# then i open bar.txt in the same tab
# right now this ends up calling on_load and overwriting it
# because the new tab has a new buffer/sheet/view
# e.g. sometimes i want a specific view to have its own color scheme independent of other tabs
# what even are buffers and views
#
#
# warning: inside sublime.ui_info['color_scheme'] are keys called 'resolved_value' and 'value'
# as far as i can tell they are the same, but if they differ this is a problem
class WindowSchemeEventListener(sublime_plugin.EventListener):
def on_new(self, view):
print("on_new")
from change_window_color_scheme import global_data
default_color_scheme = sublime.ui_info()['color_scheme']['value']
vwid = view.window().id()
scheme = global_data.get(vwid, default_color_scheme)
view.settings().set('color_scheme', scheme)
def on_load(self, view):
print("on_load")
print("view id:",view.id())
print("buffer id:",view.buffer_id())
print("sheet id:",view.sheet_id())
#global data is a dict using window ids as the key and color scheme as value
from change_window_color_scheme import global_data
#if a window does not have its own key, use the default value
vwid = view.window().id()
default_color_scheme = sublime.ui_info()['color_scheme']['value']
scheme = global_data.get(vwid, default_color_scheme)
view.settings().set('color_scheme', scheme)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment