Skip to content

Commit 94e4057

Browse files
committed
Update aliases and theme patches after ignored_packages change
Help prevent confusion with alias syntaxes overriding real syntaxes, directly after installation of new packages.
1 parent 1b976e5 commit 94e4057

File tree

4 files changed

+100
-24
lines changed

4 files changed

+100
-24
lines changed

core/aliases.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@
6161
).lstrip()
6262

6363

64-
def check(desired_state):
64+
def check(desired_state, on_demand=False):
6565
if desired_state:
66-
enable()
66+
enable(on_demand)
6767
else:
6868
disable()
6969

@@ -87,12 +87,22 @@ def delete_alias_files(syntaxes):
8787
delete_alias_files(file_type.get("aliases", []))
8888
delete_alias_files(file_type.get("syntaxes", []))
8989

90-
shutil.rmtree(path.overlay_aliases_path(), ignore_errors=True)
91-
shutil.rmtree(path.overlay_cache_path(), ignore_errors=True)
90+
def remove():
91+
shutil.rmtree(path.overlay_aliases_path(), ignore_errors=True)
92+
shutil.rmtree(path.overlay_cache_path(), ignore_errors=True)
9293

94+
sublime.set_timeout_async(remove)
9395

94-
def enable():
96+
97+
def enable(on_demand=False):
9598
real_syntaxes = get_real_syntaxes()
99+
syntax_names = real_syntaxes.keys()
100+
try:
101+
if on_demand and enable.syntax_names == syntax_names:
102+
return
103+
except Exception:
104+
pass
105+
enable.syntax_names = syntax_names
96106

97107
def real_syntax_for(selector):
98108
for scope in selector.split(","):
@@ -158,13 +168,16 @@ def delete_alias_file(alias, real_syntax):
158168
if syntax and syntax == alias_resource:
159169
view.assign_syntax(real_syntax)
160170

161-
# actually delete the alias syntax
162-
try:
163-
os.remove(alias_path)
164-
except Exception as error:
165-
dump("- {} | {}".format(alias_name, error))
166-
else:
167-
dump("- {}".format(alias_name))
171+
# delete the alias syntax asynchronously, after ST applied real syntax
172+
def remove():
173+
try:
174+
os.remove(alias_path)
175+
except Exception as error:
176+
dump("- {} | {}".format(alias_name, error))
177+
else:
178+
dump("- {}".format(alias_name))
179+
180+
sublime.set_timeout_async(remove)
168181

169182

170183
def get_real_syntaxes():

core/settings.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,43 @@
55
from . import themes
66

77
from .overlay import with_ignored_overlay
8+
from .utils.decorators import debounce
89
from .utils.logging import log
910
from .utils.path import PACKAGE_NAME
1011

1112
PACKAGE_SETTINGS = "A File Icon.sublime-settings"
13+
USER_SETTINGS = "Preferences.sublime-settings"
1214

15+
_cached_packages = []
1316
_cached_settings = {}
1417
_uuid = "9ebcce78-4cac-4089-8bd7-d551c634b052"
1518

1619

1720
def add_listener():
1821
log("Initializing settings")
1922
path = "Packages/{0}/{1}".format(PACKAGE_NAME, PACKAGE_SETTINGS)
20-
settings = sublime.load_settings(PACKAGE_SETTINGS)
23+
package_settings = sublime.load_settings(PACKAGE_SETTINGS)
2124
for key in sublime.decode_value(sublime.load_resource(path)).keys():
2225
if key not in ("dev_mode", "dev_trace"):
23-
_cached_settings[key] = settings.get(key)
26+
_cached_settings[key] = package_settings.get(key)
27+
28+
user_settings = sublime.load_settings(USER_SETTINGS)
29+
_cached_packages = user_settings.get("ignored_packages")
2430

2531
icons.init()
2632
themes.patch(_cached_settings)
2733
aliases.check(_cached_settings["aliases"])
28-
sublime.load_settings(PACKAGE_SETTINGS).add_on_change(_uuid, _on_change)
34+
35+
package_settings.add_on_change(_uuid, _on_change_package)
36+
user_settings.add_on_change(_uuid, _on_change_user)
2937

3038

3139
def clear_listener():
3240
sublime.load_settings(PACKAGE_SETTINGS).clear_on_change(_uuid)
41+
sublime.load_settings(USER_SETTINGS).clear_on_change(_uuid)
3342

3443

35-
def _on_change():
44+
def _on_change_package():
3645
is_aliases_changed = False
3746
is_icons_changed = False
3847
is_force_mode_changed = False
@@ -55,12 +64,18 @@ def _on_change():
5564
aliases.check(_cached_settings["aliases"])
5665
if is_icons_changed:
5766
log("Icons settings changed")
58-
_patch_theme(True)
67+
themes.patch(_cached_settings, overwrite=True)
5968
elif is_force_mode_changed:
6069
log("Force mode settings changed")
61-
_patch_theme(False)
62-
63-
64-
@with_ignored_overlay
65-
def _patch_theme(overwrite):
66-
themes.patch(_cached_settings, overwrite)
70+
themes.patch(_cached_settings)
71+
72+
73+
@debounce(2000)
74+
def _on_change_user():
75+
global _cached_packages
76+
settings = sublime.load_settings(USER_SETTINGS)
77+
packages = settings.get("ignored_packages")
78+
if packages != _cached_packages:
79+
_cached_packages = packages
80+
themes.patch(_cached_settings, on_demand=True)
81+
aliases.check(_cached_settings["aliases"], on_demand=True)

core/themes.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,25 @@
44

55
import sublime
66

7+
from itertools import chain
8+
79
from .utils import path
810
from .utils.colors import convert_color_value
911
from .utils.logging import log, dump
1012

1113
from . import icons
1214

1315

14-
def patch(settings, overwrite=False):
16+
def patch(settings, overwrite=False, on_demand=False):
1517
theme_packages = _installed_themes()
18+
themes = set((theme for theme in chain(*theme_packages.values())))
19+
try:
20+
if on_demand and patch.themes == themes:
21+
return
22+
except Exception:
23+
pass
24+
patch.themes = themes
25+
1626
supported = [] if settings.get("force_mode") else _customizable_themes()
1727

1828
general_patch = _create_general_patch(settings)

core/utils/decorators.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from functools import partial, wraps
2+
from timeit import default_timer
3+
4+
import sublime
5+
6+
7+
def debounce(delay_in_ms, sync=False):
8+
"""Delay calls to functions until they weren't triggered for n ms."""
9+
10+
# We assume that locking is not necessary because each function will be called
11+
# from either the ui or the async thread only.
12+
set_timeout = sublime.set_timeout if sync else sublime.set_timeout_async
13+
14+
def decorator(func):
15+
call_at = 0
16+
17+
def _debounced_callback(callback):
18+
nonlocal call_at
19+
diff = call_at - int(default_timer() * 1000)
20+
if diff > 0:
21+
set_timeout(partial(_debounced_callback, callback), diff)
22+
else:
23+
call_at = 0
24+
callback()
25+
26+
@wraps(func)
27+
def wrapper(*args, **kwargs):
28+
nonlocal call_at
29+
pending = call_at > 0
30+
call_at = int(default_timer() * 1000) + delay_in_ms
31+
if pending:
32+
return
33+
callback = partial(func, *args, **kwargs)
34+
set_timeout(partial(_debounced_callback, callback), delay_in_ms)
35+
36+
return wrapper
37+
38+
return decorator

0 commit comments

Comments
 (0)