-
Notifications
You must be signed in to change notification settings - Fork 44
/
gutter_color.py
164 lines (138 loc) · 5.87 KB
/
gutter_color.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
from .file import File
from sublime_plugin import EventListener, WindowCommand, TextCommand
from sublime import load_settings, save_settings, load_resource, packages_path
def clear_cache(force = False):
"""
If the folder exists, and has more than 5MB of icons in the cache, delete
it to clear all the icons then recreate it.
"""
from os.path import getsize, join, isfile, exists
from os import makedirs, listdir
from sublime import cache_path
from shutil import rmtree
# The icon cache path
icon_path = join(cache_path(), "GutterColor")
# The maximum amount of space to take up
limit = 5242880 # 5 MB
if exists(icon_path):
size = sum(getsize(join(icon_path, f)) for f in listdir(icon_path) if isfile(join(icon_path, f)))
if force or (size > limit): rmtree(icon_path)
if not exists(icon_path): makedirs(icon_path)
def plugin_loaded():
clear_cache()
fix_schemes_in_windows()
class GutterColorClearCacheCommand(WindowCommand):
def run(self):
clear_cache(True)
class GutterColorEventListener(EventListener):
"""Scan the view when it gains focus, and when it is saved."""
def on_activated_async(self, view):
"""Scan file when it gets focus"""
if syntax(view) in settings().get('supported_syntax'):
fix_scheme_in_view(view)
File(view)
def on_modified(self, view):
"""Scan file when it is modified"""
if syntax(view) in settings().get('supported_syntax'):
File(view, 'update')
def on_pre_save_async(self, view):
"""Scan file before it is saved"""
if syntax(view) in settings().get('supported_syntax'):
File(view, 'update')
def settings():
"""Shortcut to the settings"""
return load_settings("GutterColor.sublime-settings")
def syntax(view):
"""Return the view syntax"""
syntax = view.settings().get('syntax')
return syntax.split('/')[-1].split('.')[0].lower() if syntax is not None else "plain text"
def current_directory(full=False):
"""Return the name of the directory containing this plugin"""
from os.path import dirname, realpath, split
if full:
return dirname(realpath(__file__))
else:
return split(dirname(realpath(__file__)))[1]
def fix_schemes_in_windows():
"""Change color schemes for all current views in the supported syntax list"""
from sublime import windows
for window in windows():
for view in window.views():
if syntax(view) in settings().get('supported_syntax'):
fix_scheme_in_view(view)
def fix_scheme_in_view(view, regenerate=False, ignore_flags=False):
"""Change color scheme in settings relevant to current view"""
fix_flag = settings().get("fix_color_schemes", False)
(fix_syntax, fix_global, fix_custom) = (False, False, False)
custom_files = []
if fix_flag == True:
(fix_syntax, fix_global) = (True, True)
elif isinstance(fix_flag, list):
for label in fix_flag:
if label in ("syntax", "syntax-specific"):
fix_syntax = True
if label in ("user", "global", "preferences"):
fix_global = True
if ".sublime-settings" in label:
fix_custom = True
custom_files.append(label)
elif ignore_flags:
pass # otherwise we might quit when we want to force a check contrary to user prefs
else:
return # setting is false, nonexistant, or malformed, so exit
current_scheme = view.settings().get("color_scheme")
modified_marker = ".gcfix."
if modified_marker in current_scheme:
if regenerate:
new_scheme = current_scheme
else:
return # this view already has a fixed scheme and we aren't regenerating, so exit
else:
new_scheme = "Packages/"+current_directory()+"/"+current_scheme.split("/")[-1].split(".")[0]+\
modified_marker + current_scheme.split(".")[-1]
if fix_custom:
for custom_filename in custom_files:
if fix_scheme_in_settings(custom_filename, current_scheme, new_scheme):
return
if fix_syntax or ignore_flags:
syntax_filename = view.settings().get('syntax').split('/')[-1].split('.')[0] + ".sublime-settings"
if fix_scheme_in_settings(syntax_filename, current_scheme, new_scheme):
return
if fix_global or ignore_flags:
if fix_scheme_in_settings("Preferences.sublime-settings", current_scheme, new_scheme):
return
print("Could not find or access the settings file where current color_scheme ("+current_scheme+") is set.")
def fix_scheme_in_settings(settings_file,current_scheme, new_scheme, regenerate=False):
"""Change the color scheme in the given Settings to a background-corrected one"""
from os.path import join, normpath, isfile
settings = load_settings(settings_file)
settings_scheme = settings.get("color_scheme")
if current_scheme == settings_scheme:
new_scheme_path = join(packages_path(), normpath(new_scheme[len("Packages/"):]))
if isfile(new_scheme_path) and not regenerate:
settings.set("color_scheme", new_scheme)
else:
generate_scheme_fix(current_scheme, new_scheme_path)
settings.set("color_scheme", new_scheme)
save_settings(settings_file)
return True
return False
def generate_scheme_fix(old_scheme, new_scheme_path):
"""Appends background-correction XML to a color scheme file"""
from os.path import join
from re import sub
UUID_REGEX = '[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}'
with open(join(packages_path(),current_directory(),'background_fix.xml')) as f:
xml = f.read()
scheme_data = load_resource(old_scheme) # only valid for ST3 API!
insertion_point = scheme_data.rfind("</array>")
new_scheme_data = scheme_data[:insertion_point] + xml + scheme_data[insertion_point:]
def uuid_gen(args):
from uuid import uuid4
return str(uuid4())
new_scheme_data = sub(UUID_REGEX, uuid_gen, new_scheme_data)
with open(new_scheme_path, "wb") as f:
f.write(new_scheme_data.encode("utf-8"))
class GutterColorFixCurrentScheme(TextCommand):
def run(self, args):
fix_scheme_in_view(self.view, True, True)