-
Notifications
You must be signed in to change notification settings - Fork 1
/
ColorSchemeEditor-ST2.py
225 lines (184 loc) · 6.01 KB
/
ColorSchemeEditor-ST2.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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
import sublime, sublime_plugin, os.path
# globals suck, but don't know how to pass data between the classes
_schemeEditor = None
_skipOne = 0
_wasSingleLayout = None
_lastScope = None
_lastScopeIndex = 0
def find_matches ( scope, founds ):
global _schemeEditor
ret = []
maxscore = 0
# find the scope in the xml that matches the most
for found in founds:
foundstr = _schemeEditor.substr( found )
pos = foundstr.find( '<string>' ) + 8
foundstr = foundstr[ pos : -9 ]
foundstrs = foundstr.split( ',' )
fstrlen = 0
for fstr in foundstrs:
fstrlen = len( fstr )
fstr = fstr.lstrip( ' ' )
padleft = fstrlen - len( fstr )
fstr = fstr.rstrip( ' ' )
score = sublime.score_selector( scope, fstr )
if score > 0:
a = found.a + pos + padleft
ret.append( [ score, sublime.Region( a, a + len( fstr ) ) ] )
pos += fstrlen + 1
if len( ret ) == 0:
return None
else:
return ret
def display_scope ( region ):
global _schemeEditor
# doest change the selection if previous selection was on the same line
sel = _schemeEditor.sel()
sel.clear()
sel.add( region )
_schemeEditor.show_at_center( region )
def update_view_status ( view ):
global _lastScope, _lastScopeIndex
found = None
_lastScope = []
_lastScopeIndex = 0
# find the scope under the cursor
scope_name = view.scope_name( view.sel()[0].a )
pretty_scope = scope_name.strip( ' ' ).replace( ' ', ' > ' )
scopes = reversed( pretty_scope.split( ' > ' ) )
# convert to regex and look for the scope in the scheme editor
for scope in scopes:
if len( scope ) == 0:
continue
dots = scope.count( '.' )
regex = '<key>scope</key>\\s*<string>([a-z\\.\\-]* ?, ?)*([a-z\\.\\- ]*'
regex += scope.replace( '.', '(\\.' )
while dots > 0:
regex += ')?'
dots -= 1
regex += ')( ?, ?[a-z\\.\\-]*)*</string>'
found = _schemeEditor.find_all( regex, 0 )
found = find_matches( scope_name, found )
if found != None:
_lastScope += found
scopes = len( _lastScope )
sublime.status_message( 'matches ' + str( scopes ) + ': ' + pretty_scope )
if scopes == 0:
_lastScope = None
display_scope( sublime.Region( 0, 0 ) )
else:
_lastScope.sort( key = lambda f: f[1].a )
_lastScope.sort( key = lambda f: f[0], reverse = True )
display_scope( _lastScope[0][1] )
def kill_scheme_editor ():
global _schemeEditor, _skipOne, _wasSingleLayout, _lastScope, _lastScopeIndex
if int( sublime.version() ) > 3000 and _wasSingleLayout != None:
_wasSingleLayout.set_layout( {
'cols': [0.0, 1.0],
'rows': [0.0, 1.0],
'cells': [[0, 0, 1, 1]]
} )
_skipOne = 0
_wasSingleLayout = None
_schemeEditor = None
_lastScope = None
_lastScopeIndex = 0
# listeners to update our scheme editor
class NavigationListener ( sublime_plugin.EventListener ):
def on_close ( self, view ):
global _schemeEditor
if _schemeEditor != None:
if _schemeEditor.id() == view.id():
kill_scheme_editor()
def on_selection_modified ( self, view ):
global _schemeEditor, _skipOne
if _schemeEditor != None:
if _schemeEditor.id() != view.id() and not view.settings().get( 'is_widget' ):
# for some reason this callback is called twice - for mouse down and mouse up
if _skipOne == 1:
_skipOne = 0
else:
_skipOne = 1
update_view_status( view )
class EditColorSchemeNextScopeCommand ( sublime_plugin.TextCommand ):
def run ( self, edit ):
global _schemeEditor, _lastScope, _lastScopeIndex
if _schemeEditor != None and _lastScope != None:
scopes = len( _lastScope )
if scopes > 1:
_lastScopeIndex += 1
if _lastScopeIndex == scopes:
_lastScopeIndex = 0
display_scope( _lastScope[_lastScopeIndex][1] )
sublime.status_message( 'Scope ' + str( _lastScopeIndex + 1 ) + ' of ' + str( scopes ) )
class EditColorSchemePrevScopeCommand ( sublime_plugin.TextCommand ):
def run ( self, edit ):
global _schemeEditor, _lastScope, _lastScopeIndex
if _schemeEditor != None and _lastScope != None:
scopes = len( _lastScope )
if scopes > 1:
if _lastScopeIndex == 0:
_lastScopeIndex = scopes - 1
else:
_lastScopeIndex -= 1
display_scope( _lastScope[_lastScopeIndex][1] )
sublime.status_message( 'Scope ' + str( _lastScopeIndex + 1 ) + ' of ' + str( scopes ) )
class EditCurrentColorSchemeCommand ( sublime_plugin.TextCommand ):
def run ( self, edit ):
global _schemeEditor, _wasSingleLayout
view = self.view
viewid = view.id()
window = view.window()
if _schemeEditor == None:
# see if not trying to edit on the scheme file
path = os.path.abspath( sublime.packages_path() + '/../' + view.settings().get( 'color_scheme' ) )
if path == view.file_name():
sublime.status_message( 'Select different file from the scheme you want to edit' )
_schemeEditor = None
return
# see if we openeded a new view
views = len( window.views() )
_schemeEditor = window.open_file( path )
if _schemeEditor == None:
sublime.status_message( 'Could not open the scheme file' )
return
if views == len( window.views() ):
views = 0
else:
views = 1
# if we have only one splitter, open new one
groups = window.num_groups()
group = -1
index = 0
if groups == 1:
_wasSingleLayout = window
group = 1
window.set_layout( {
'cols': [0.0, 0.5, 1.0],
'rows': [0.0, 1.0],
'cells': [[0, 0, 1, 1], [1, 0, 2, 1]]
} )
elif views == 1:
activegrp = window.active_group() + 1
if activegrp == groups:
group = activegrp - 2
index = len( window.views_in_group( group ) )
else:
group = activegrp
if groups == 1 or views == 1:
# move the editor to another splitter
window.set_view_index( _schemeEditor, group, index )
else:
#if the editor is in different splitter already focus it
window.focus_view( _schemeEditor )
window.focus_view( view )
update_view_status( view )
else:
# if it was us who created the other splitter close it
if _wasSingleLayout != None:
_wasSingleLayout.set_layout( {
'cols': [0.0, 1.0],
'rows': [0.0, 1.0],
'cells': [[0, 0, 1, 1]]
} )
kill_scheme_editor()