|
1
|
|
|
"""Module for getting Rainmeter-specific paths""" |
|
2
|
|
|
|
|
3
|
|
|
import os |
|
4
|
|
|
import re |
|
5
|
|
|
import io |
|
6
|
|
|
import getpass |
|
7
|
|
|
import platform |
|
8
|
|
|
import winreg |
|
9
|
|
|
|
|
10
|
|
|
import sublime |
|
11
|
|
|
import sublime_plugin |
|
12
|
|
|
|
|
13
|
|
|
# own dependencies |
|
14
|
|
|
from . import logger |
|
15
|
|
|
|
|
16
|
|
|
from .path.program_path_provider import get_cached_program_path |
|
17
|
|
|
from .path.setting_path_provider import get_cached_setting_path |
|
18
|
|
|
from .path.program_drive_provider import get_cached_program_drive |
|
19
|
|
|
from .path.plugin_path_provider import get_cached_plugin_path |
|
20
|
|
|
from .path.addon_path_provider import get_cached_addon_path |
|
21
|
|
|
|
|
22
|
|
|
from .completion.completion import ContextSensAutoCompletion |
|
23
|
|
|
|
|
24
|
|
|
|
|
25
|
|
|
def skins_path(): |
|
26
|
|
|
"""Get the cached value of the #SKINSPATH# variable""" |
|
27
|
|
|
|
|
28
|
|
|
return _skins_path |
|
29
|
|
|
|
|
30
|
|
|
|
|
31
|
|
|
def get_skins_path(): |
|
32
|
|
|
"""Get the value of the #SKINSPATH# variable""" |
|
33
|
|
|
|
|
34
|
|
|
# First try to load the value from the "rainmeter_skins_path" setting |
|
35
|
|
|
loaded_settings = sublime.load_settings("Rainmeter.sublime-settings") |
|
36
|
|
|
skinspath = loaded_settings.get("rainmeter_skins_path", None) |
|
37
|
|
|
|
|
38
|
|
|
# if it's found, return it |
|
39
|
|
|
# We trust the user to enter something meaningful here |
|
40
|
|
|
# and don't check anything. |
|
41
|
|
|
if skinspath: |
|
42
|
|
|
logger.info(__file__, "get_skins_path", "Skins path found in sublime-settings file.") |
|
43
|
|
|
return os.path.normpath(skinspath) + "\\" |
|
44
|
|
|
|
|
45
|
|
|
# If it's not set, try to detect it automagically |
|
46
|
|
|
|
|
47
|
|
|
rainmeterpath = get_cached_program_path() |
|
48
|
|
|
if not rainmeterpath: |
|
49
|
|
|
return |
|
50
|
|
|
|
|
51
|
|
|
settingspath = get_cached_setting_path() |
|
52
|
|
|
if not settingspath: |
|
53
|
|
|
return |
|
54
|
|
|
|
|
55
|
|
|
# First, try to read the SkinPath setting from Rainmeter.ini |
|
56
|
|
|
fhnd = io.open(os.path.join(settingspath, "Rainmeter.ini")) |
|
57
|
|
|
lines = fhnd.read() |
|
58
|
|
|
fhnd.close() |
|
59
|
|
|
|
|
60
|
|
|
# Find the skinspath setting in the file |
|
61
|
|
|
match = re.search(r"""(?imsx) |
|
62
|
|
|
|
|
63
|
|
|
# Find the first [Rainmeter] section |
|
64
|
|
|
(^\s*\[\s*Rainmeter\s*\]\s*$) |
|
65
|
|
|
(.*? |
|
66
|
|
|
|
|
67
|
|
|
# Find the "SkinPath" and "=" |
|
68
|
|
|
(^\s*SkinPath\s*=\s* |
|
69
|
|
|
|
|
70
|
|
|
# Read until the next line ending and store |
|
71
|
|
|
# in named group |
|
72
|
|
|
(?P<skinpath>[^$]+?)\s*?$ |
|
73
|
|
|
) |
|
74
|
|
|
).*? |
|
75
|
|
|
|
|
76
|
|
|
# All of this needs to happen before the next section |
|
77
|
|
|
(?:^\s*\[\s*[^\[\]\s]+\s*\]\s*$) |
|
78
|
|
|
""", lines) |
|
79
|
|
|
|
|
80
|
|
|
# if skinspath setting was found, return it |
|
81
|
|
|
if match: |
|
82
|
|
|
logger.info(__file__, "get_skins_path", "Skins path found in Rainmeter.ini.") |
|
83
|
|
|
return match.group("skinpath").strip().replace("/", "\\") |
|
84
|
|
|
|
|
85
|
|
|
# if it's not found in the settings file, try to guess it |
|
86
|
|
|
|
|
87
|
|
|
# If program path and setting path are equal, we have a portable |
|
88
|
|
|
# installation. In this case, the Skins folder is inside the rainmeter |
|
89
|
|
|
# path |
|
90
|
|
|
if os.path.samefile(rainmeterpath, settingspath): |
|
91
|
|
|
logger.info(__file__, "get_skins_path", "Skin path found in #PROGRAMPATH#" + |
|
92
|
|
|
" because portable installation") |
|
93
|
|
|
return os.path.join(rainmeterpath, "Skins") + "\\" |
|
94
|
|
|
|
|
95
|
|
|
# If it's not a portable installation, we try looking into the "My |
|
96
|
|
|
# Documents" folder Since it could be relocated by the user, we have to |
|
97
|
|
|
# query its value from the registry |
|
98
|
|
|
try: |
|
99
|
|
|
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, |
|
100
|
|
|
r"Software\Microsoft\Windows" + |
|
101
|
|
|
r"\CurrentVersion\Explorer" + |
|
102
|
|
|
r"\User Shell Folders") |
|
103
|
|
|
keyval = winreg.QueryValueEx(regkey, "Personal") |
|
104
|
|
|
|
|
105
|
|
|
pathrep = keyval[0] |
|
106
|
|
|
|
|
107
|
|
|
# The path could (and most likely, will) contain environment |
|
108
|
|
|
# variables that have to be expanded first |
|
109
|
|
|
pathrep = os.path.expandvars(pathrep) |
|
110
|
|
|
|
|
111
|
|
|
logger.info(__file__, "get_skins_path", "Guessed Skin path from My Documents" + |
|
112
|
|
|
" location in registry") |
|
113
|
|
|
return os.path.join(pathrep, "Rainmeter\\Skins") + "\\" |
|
114
|
|
|
|
|
115
|
|
|
except OSError: |
|
116
|
|
|
pass |
|
117
|
|
|
|
|
118
|
|
|
# If the value could not be retrieved from the registry, |
|
119
|
|
|
# we try some educated guesses about default locations |
|
120
|
|
|
try: |
|
121
|
|
|
username = getpass.getuser() |
|
122
|
|
|
except Exception: |
|
123
|
|
|
logger.info(__file__, "get_skins_path", "Skins path could not be located." + |
|
124
|
|
|
" Please set the \"skins_path\" setting in your Rainmeter" + |
|
125
|
|
|
" settings file.") |
|
126
|
|
|
return |
|
127
|
|
|
else: |
|
128
|
|
|
# check if windows version is XP |
|
129
|
|
|
winversion = platform.version() |
|
130
|
|
|
if int(winversion[0]) < 6: |
|
131
|
|
|
mydocuments = os.path.join("C:\\Documents and Settings", |
|
132
|
|
|
username, |
|
133
|
|
|
"My Documents") + "\\" |
|
134
|
|
|
|
|
135
|
|
|
logger.info(__file__, "get_skins_path", "Found Windows XP or lower." + |
|
136
|
|
|
" Skins path assumed to be " + mydocuments + |
|
137
|
|
|
"Rainmeter\\Skins\\") |
|
138
|
|
|
else: |
|
139
|
|
|
mydocuments = os.path.join("C:\\Users", |
|
140
|
|
|
username, |
|
141
|
|
|
"Documents") + "\\" |
|
142
|
|
|
|
|
143
|
|
|
logger.info(__file__, "get_skins_path", "Found Windows Vista or higher." + |
|
144
|
|
|
" Skins path assumed to be " + mydocuments + |
|
145
|
|
|
"Rainmeter\\Skins\\") |
|
146
|
|
|
|
|
147
|
|
|
logger.info(__file__, "get_skins_path", "Skin path guessed from user name" + |
|
148
|
|
|
" and Windows version") |
|
149
|
|
|
return os.path.join(mydocuments, "Rainmeter\\Skins") + "\\" |
|
150
|
|
|
|
|
151
|
|
|
|
|
152
|
|
|
def get_current_path(filepath): |
|
153
|
|
|
"""Get the value of the #CURRENTPATH# variable for the specified path. |
|
154
|
|
|
|
|
155
|
|
|
Returns None if the file path is not in the skins folder |
|
156
|
|
|
|
|
157
|
|
|
""" |
|
158
|
|
|
|
|
159
|
|
|
filepath = os.path.normpath(filepath) |
|
160
|
|
|
|
|
161
|
|
|
skinspath = skins_path() |
|
162
|
|
|
if not skinspath or not filepath.startswith(skinspath): |
|
163
|
|
|
logger.info(__file__, "get_current_path", "current path could not be found because" + |
|
164
|
|
|
" either the skins path could not be found or the current file" + |
|
165
|
|
|
" is not located in the skins path.") |
|
166
|
|
|
return |
|
167
|
|
|
|
|
168
|
|
|
if os.path.isfile(filepath): |
|
169
|
|
|
return os.path.dirname(filepath) + "\\" |
|
170
|
|
|
else: |
|
171
|
|
|
return filepath + "\\" |
|
172
|
|
|
|
|
173
|
|
|
|
|
174
|
|
|
def get_root_config_path(filepath): |
|
175
|
|
|
"""Get the value of the #ROOTCONFIGPATH# variable for the specified path |
|
176
|
|
|
|
|
177
|
|
|
Returns None if the path is not in the skins folder |
|
178
|
|
|
|
|
179
|
|
|
""" |
|
180
|
|
|
|
|
181
|
|
|
filepath = os.path.normpath(filepath) |
|
182
|
|
|
|
|
183
|
|
|
skinspath = skins_path() |
|
184
|
|
|
if not skinspath or not filepath.startswith(skinspath): |
|
185
|
|
|
logger.info(__file__, "get_root_config_path", "root config path could not be found" + |
|
186
|
|
|
" because either the skins path could not be found or the" + |
|
187
|
|
|
" current file is not located in the skins path.") |
|
188
|
|
|
return |
|
189
|
|
|
|
|
190
|
|
|
relpath = os.path.relpath(filepath, skinspath) |
|
191
|
|
|
logger.info(__file__, "get_root_config_path", |
|
192
|
|
|
os.path.join(skinspath, relpath.split("\\")[0]) + "\\") |
|
193
|
|
|
|
|
194
|
|
|
return os.path.join(skinspath, relpath.split("\\")[0]) + "\\" |
|
195
|
|
|
|
|
196
|
|
|
|
|
197
|
|
|
def get_current_file(filepath): |
|
198
|
|
|
"""Get the value of the #CURRENTFILE# variable for the specified path |
|
199
|
|
|
|
|
200
|
|
|
Returns None if the path is not in the skins folder |
|
201
|
|
|
|
|
202
|
|
|
""" |
|
203
|
|
|
|
|
204
|
|
|
filepath = os.path.normpath(filepath) |
|
205
|
|
|
|
|
206
|
|
|
skinspath = skins_path() |
|
207
|
|
|
if not skinspath or not filepath.startswith(skinspath): |
|
208
|
|
|
logger.info(__file__, "get_current_file", "current file could not be found because" + |
|
209
|
|
|
" either the skins path could not be found or the current" + |
|
210
|
|
|
" file is not located in the skins path.") |
|
211
|
|
|
return |
|
212
|
|
|
|
|
213
|
|
|
if os.path.isfile(filepath): |
|
214
|
|
|
return os.path.basename(filepath) |
|
215
|
|
|
else: |
|
216
|
|
|
logger.info(__file__, "get_current_file", "specified path is not a file.") |
|
217
|
|
|
return |
|
218
|
|
|
|
|
219
|
|
|
|
|
220
|
|
|
def get_current_config(filepath): |
|
221
|
|
|
"""Get the value of the #CURRENTCONFIG# variable for the specified path |
|
222
|
|
|
|
|
223
|
|
|
Returns None if the path is not in the skins folder |
|
224
|
|
|
|
|
225
|
|
|
""" |
|
226
|
|
|
|
|
227
|
|
|
filepath = os.path.normpath(filepath) |
|
228
|
|
|
|
|
229
|
|
|
skinspath = skins_path() |
|
230
|
|
|
if not skinspath or not filepath.startswith(skinspath): |
|
231
|
|
|
logger.info(__file__, "get_current_config", "current config could not be found" + |
|
232
|
|
|
" because \either the skins path could not be found or the" + |
|
233
|
|
|
" current file is not located in the skins path.") |
|
234
|
|
|
return |
|
235
|
|
|
|
|
236
|
|
|
if os.path.isfile(filepath): |
|
237
|
|
|
filepath = os.path.dirname(filepath) |
|
238
|
|
|
|
|
239
|
|
|
return os.path.relpath(filepath, skinspath) |
|
240
|
|
|
|
|
241
|
|
|
|
|
242
|
|
|
def get_resources_path(filepath): |
|
243
|
|
|
"""Get the value of the #@# variable for the specified path |
|
244
|
|
|
|
|
245
|
|
|
Returns None if the path is not in the skins folder |
|
246
|
|
|
|
|
247
|
|
|
""" |
|
248
|
|
|
|
|
249
|
|
|
rfp = get_root_config_path(filepath) |
|
250
|
|
|
|
|
251
|
|
|
if not rfp: |
|
252
|
|
|
return |
|
253
|
|
|
logger.info(__file__, "get_resources_path", os.path.join(rfp, "@Resources") + "\\") |
|
254
|
|
|
return os.path.join(rfp, "@Resources") + "\\" |
|
255
|
|
|
|
|
256
|
|
|
|
|
257
|
|
|
def replace_variables(string, filepath): |
|
258
|
|
|
"""Replace Rainmeter built-in variables and Windows environment variables |
|
259
|
|
|
in string. |
|
260
|
|
|
|
|
261
|
|
|
Replaces occurrences of the following variables in the string: |
|
262
|
|
|
#CURRENTFILE# |
|
263
|
|
|
#CURRENTPATH# |
|
264
|
|
|
#ROOTCONFIGPATH# |
|
265
|
|
|
#CURRENTCONFIG# |
|
266
|
|
|
#@# |
|
267
|
|
|
#SKINSPATH# |
|
268
|
|
|
#SETTINGSPATH# |
|
269
|
|
|
#PROGRAMPATH# |
|
270
|
|
|
#PROGRAMDRIVE# |
|
271
|
|
|
#ADDONSPATH# |
|
272
|
|
|
#PLUGINSPATH# |
|
273
|
|
|
Any Windows environment variables (like %APPDATA%) |
|
274
|
|
|
filepath must be a skin file located in a subdirectory of the skins folder |
|
275
|
|
|
|
|
276
|
|
|
""" |
|
277
|
|
|
|
|
278
|
|
|
# lambdas for lazy evaluation |
|
279
|
|
|
variables = {"#CURRENTFILE#": lambda: get_current_file(filepath), |
|
280
|
|
|
"#CURRENTPATH#": lambda: get_current_path(filepath), |
|
281
|
|
|
"#ROOTCONFIGPATH#": lambda: get_root_config_path(filepath), |
|
282
|
|
|
"#CURRENTCONFIG#": lambda: get_current_config(filepath), |
|
283
|
|
|
"#@#": lambda: get_resources_path(filepath), |
|
284
|
|
|
"#SKINSPATH#": lambda: skins_path(), |
|
285
|
|
|
"#SETTINGSPATH#": lambda: get_cached_setting_path(), |
|
286
|
|
|
"#PROGRAMPATH#": lambda: get_cached_program_path(), |
|
287
|
|
|
"#PROGRAMDRIVE#": lambda: get_cached_program_drive(), |
|
288
|
|
|
"#ADDONSPATH#": lambda: get_cached_addon_path(), |
|
289
|
|
|
"#PLUGINSPATH#": lambda: get_cached_plugin_path()} |
|
290
|
|
|
|
|
291
|
|
|
pattern = re.compile("(?i)" + "|".join(list(variables.keys()))) |
|
292
|
|
|
# replace Rainmeter variables |
|
293
|
|
|
repl = pattern.sub(lambda x: variables[x.group().upper()](), |
|
294
|
|
|
string) |
|
295
|
|
|
# expand windows environment variables |
|
296
|
|
|
repl = os.path.expandvars(repl) |
|
297
|
|
|
return repl |
|
298
|
|
|
|
|
299
|
|
|
|
|
300
|
|
|
def make_path(string, filepath): |
|
301
|
|
|
"""Make the string into an absolute path of an existing file or folder, |
|
302
|
|
|
|
|
303
|
|
|
replacing Rainmeter built-in variables relative to the file specified in |
|
304
|
|
|
filepath (see replace_variables()) will return None if the file or folder |
|
305
|
|
|
doesn't exist, or if string is None or empty. |
|
306
|
|
|
|
|
307
|
|
|
""" |
|
308
|
|
|
|
|
309
|
|
|
if not string: |
|
310
|
|
|
return None |
|
311
|
|
|
|
|
312
|
|
|
repl = replace_variables(string, filepath) |
|
313
|
|
|
norm = os.path.normpath(repl) |
|
314
|
|
|
|
|
315
|
|
|
# For relative paths, try folder of current file first |
|
316
|
|
|
|
|
317
|
|
|
if not os.path.isabs(norm): |
|
318
|
|
|
curpath = get_current_path(filepath) |
|
319
|
|
|
if curpath: |
|
320
|
|
|
abso = os.path.join(curpath, norm) |
|
321
|
|
|
else: |
|
322
|
|
|
abso = os.path.join(os.path.dirname(filepath), norm) |
|
323
|
|
|
|
|
324
|
|
|
if os.path.exists(abso): |
|
325
|
|
|
return abso |
|
326
|
|
|
|
|
327
|
|
|
# if that doesn't work, try relative to skins path |
|
328
|
|
|
# (for #CURRENTCONFIG#) |
|
329
|
|
|
abso = os.path.join(skins_path(), norm) |
|
330
|
|
|
if os.path.exists(abso): |
|
331
|
|
|
return abso |
|
332
|
|
|
# for absolute paths, try opening containing folder if file does not exist |
|
333
|
|
|
else: |
|
334
|
|
|
if os.path.exists(norm): |
|
335
|
|
|
return norm |
|
336
|
|
|
|
|
337
|
|
|
if os.path.exists(os.path.dirname(norm)): |
|
338
|
|
|
return os.path.dirname(norm) |
|
339
|
|
|
|
|
340
|
|
|
return |
|
341
|
|
|
|
|
342
|
|
|
|
|
343
|
|
|
# Initialize Module |
|
344
|
|
|
# Global Variables |
|
345
|
|
|
settings = None |
|
346
|
|
|
|
|
347
|
|
|
_skins_path = None |
|
348
|
|
|
|
|
349
|
|
|
|
|
350
|
|
|
# Called automatically from ST3 if plugin is loaded |
|
351
|
|
|
# Is required now due to async call and ignoring sublime.* from main routine |
|
352
|
|
|
def plugin_loaded(): |
|
353
|
|
|
# define variables from the global scope |
|
354
|
|
|
global settings |
|
355
|
|
|
|
|
356
|
|
|
global _skins_path |
|
357
|
|
|
|
|
358
|
|
|
settings = sublime.load_settings("Rainmeter.sublime-settings") |
|
359
|
|
|
|
|
360
|
|
|
# Cache the paths |
|
361
|
|
|
_skins_path = get_skins_path() |
|
362
|
|
|
|
|
363
|
|
|
logger.info(__file__, "plugin_loaded()", "#PROGRAMPATH#:\t\t" + get_cached_program_path()) |
|
364
|
|
|
logger.info(__file__, "plugin_loaded()", "#PROGRAMDRIVE#:\t" + get_cached_program_drive()) |
|
365
|
|
|
logger.info(__file__, "plugin_loaded()", "#SETTINGSPATH#:\t" + get_cached_setting_path()) |
|
366
|
|
|
logger.info(__file__, "plugin_loaded()", "#SKINSPATH#:\t\t" + skins_path()) |
|
367
|
|
|
logger.info(__file__, "plugin_loaded()", "#PLUGINSPATH#:\t\t" + get_cached_plugin_path()) |
|
368
|
|
|
logger.info(__file__, "plugin_loaded()", "#ADDONSPATH#:\t\t" + get_cached_addon_path()) |
|
369
|
|
|
|
|
370
|
|
|
|
|
371
|
|
|
class MeterAutoComplete(sublime_plugin.EventListener): |
|
372
|
|
|
|
|
373
|
|
|
# only show our completion list because nothing else makes sense in this context |
|
374
|
|
|
flags = sublime.INHIBIT_EXPLICIT_COMPLETIONS | sublime.INHIBIT_WORD_COMPLETIONS |
|
375
|
|
|
scope = "source.rainmeter" |
|
376
|
|
|
|
|
377
|
|
|
comment_exp = re.compile(r'^\s*;.*') |
|
378
|
|
|
meter_exp = re.compile(r'^\s*') |
|
379
|
|
|
|
|
380
|
|
|
completions = [ |
|
381
|
|
|
# measures |
|
382
|
|
|
(re.compile(r'^\s*Measure\s*=\s*'), [ |
|
383
|
|
|
# key, value |
|
384
|
|
|
["Calc", "Calc"], |
|
385
|
|
|
["CPU", "CPU"], |
|
386
|
|
|
["FreeDiskSpace", "FreeDiskSpace"], |
|
387
|
|
|
["Loop", "Loop"], |
|
388
|
|
|
|
|
389
|
|
|
# memory measure |
|
390
|
|
|
["Memory", "Memory"], |
|
391
|
|
|
["PhysicalMemory", "PhysicalMemory"], |
|
392
|
|
|
["SwapMemory", "SwapMemory"], |
|
393
|
|
|
|
|
394
|
|
|
# net measure |
|
395
|
|
|
["NetIn", "NetIn"], |
|
396
|
|
|
["NetOut", "NetOut"], |
|
397
|
|
|
["NetTotal", "NetTotal"], |
|
398
|
|
|
|
|
399
|
|
|
["Plugin", "Plugin"], |
|
400
|
|
|
["Registry", "Registry"], |
|
401
|
|
|
["Script", "Script"], |
|
402
|
|
|
["String", "String"], |
|
403
|
|
|
["Time", "Time"], |
|
404
|
|
|
["Uptime", "Uptime"] |
|
405
|
|
|
]), |
|
406
|
|
|
|
|
407
|
|
|
# meters |
|
408
|
|
|
(re.compile(r'^\s*Meter\s*=\s*'), [ |
|
409
|
|
|
# key, value |
|
410
|
|
|
["Bar", "Bar"], |
|
411
|
|
|
["Bitmap", "Bitmap"], |
|
412
|
|
|
["Button", "Button"], |
|
413
|
|
|
["Histogram", "Histogram"], |
|
414
|
|
|
["Image", "Image"], |
|
415
|
|
|
["Line", "Line"], |
|
416
|
|
|
["Rotator", "Rotator"], |
|
417
|
|
|
["Roundline", "Roundline"], |
|
418
|
|
|
["Shape", "Shape"], |
|
419
|
|
|
["String", "String"] |
|
420
|
|
|
]), |
|
421
|
|
|
# general options |
|
422
|
|
|
|
|
423
|
|
|
# bar |
|
424
|
|
|
# bar orientation |
|
425
|
|
|
(re.compile(r'^\s*BarOrientation\s*=\s*'), [ |
|
426
|
|
|
# key, value |
|
427
|
|
|
["Horizontal", "Horizontal"], |
|
428
|
|
|
["Vertical\tDefault", "Vertical"] |
|
429
|
|
|
]), |
|
430
|
|
|
|
|
431
|
|
|
# bar flip |
|
432
|
|
|
(re.compile(r'^\s*Flip\s*=\s*'), [ |
|
433
|
|
|
# key, value |
|
434
|
|
|
["0\tDefault", "0"], |
|
435
|
|
|
["1\tBar is flipped", "1"] |
|
436
|
|
|
]), |
|
437
|
|
|
|
|
438
|
|
|
# bitmap |
|
439
|
|
|
|
|
440
|
|
|
# button |
|
441
|
|
|
# histogram |
|
442
|
|
|
# image |
|
443
|
|
|
# line |
|
444
|
|
|
# rotator |
|
445
|
|
|
# roundline |
|
446
|
|
|
# shape |
|
447
|
|
|
# string |
|
448
|
|
|
|
|
449
|
|
|
# plugins |
|
450
|
|
|
(re.compile(r'^\s*Plugin\s*=\s*'), [ |
|
451
|
|
|
# key, value |
|
452
|
|
|
["ActionTimer", "ActionTimer"], |
|
453
|
|
|
["AdvancedCPU", "AdvancedCPU"], |
|
454
|
|
|
["AudioLevel", "AudioLevel"], |
|
455
|
|
|
["CoreTemp", "CoreTemp"], |
|
456
|
|
|
["FileView", "FileView"], |
|
457
|
|
|
["FolderInfo", "FolderInfo"], |
|
458
|
|
|
["InputText", "InputText"], |
|
459
|
|
|
["iTunes", "iTunesPlugin"], |
|
460
|
|
|
["MediaKey", "MediaKey"], |
|
461
|
|
|
["NowPlaying", "NowPlaying"], |
|
462
|
|
|
["PerfMon", "PerfMon"], |
|
463
|
|
|
["Ping", "PingPlugin"], |
|
464
|
|
|
["Power", "PowerPlugin"], |
|
465
|
|
|
["Process", "Process"], |
|
466
|
|
|
["Quote", "QuotePlugin"], |
|
467
|
|
|
["RecycleManager", "RecycleManager"], |
|
468
|
|
|
["ResMon", "ResMon"], |
|
469
|
|
|
["RunCommand", "RunCommand"], |
|
470
|
|
|
["SpeedFan", "SpeedFanPlugin"], |
|
471
|
|
|
["SysInfo", "SysInfo"], |
|
472
|
|
|
["WebParser", "WebParser"], |
|
473
|
|
|
["WiFiStatus", "WiFiStatus"], |
|
474
|
|
|
["Win7Audio", "Win7AudioPlugin"], |
|
475
|
|
|
["WindowMessage", "WindowMessagePlugin"] |
|
476
|
|
|
]), |
|
477
|
|
|
] |
|
478
|
|
|
|
|
479
|
|
|
def on_query_completions(self, view, prefix, locations): |
|
480
|
|
|
for location in locations: |
|
481
|
|
|
# checks if the current scope is correct so it is only called in the files with the correct scope |
|
482
|
|
|
# here is scope only rainmeter files |
|
483
|
|
|
if view.match_selector(location, self.scope): |
|
484
|
|
|
# find last occurance of the [] to determine the ini sections |
|
485
|
|
|
line = view.line(location) |
|
486
|
|
|
line_contents = view.substr(line) |
|
487
|
|
|
|
|
488
|
|
|
# starts with Measure, followed by an equal sign |
|
489
|
|
|
for exp, elements in self.completions: |
|
490
|
|
|
if exp.search(line_contents): |
|
491
|
|
|
return elements, self.flags |
|
492
|
|
|
return None |
|
493
|
|
|
|
|
494
|
|
|
|
|
495
|
|
|
class CompletionProxy(sublime_plugin.EventListener): |
|
496
|
|
|
|
|
497
|
|
|
proxied_completion = None |
|
498
|
|
|
|
|
499
|
|
|
def __init__(self): |
|
500
|
|
|
self.proxied_completion = ContextSensAutoCompletion() |
|
501
|
|
|
|
|
502
|
|
|
def on_query_completions(self, view, prefix, locations): |
|
503
|
|
|
return self.proxied_completion.on_query_completions(view, prefix, locations) |
|
504
|
|
|
|