Skip to content

Commit 7307e04

Browse files
committed
chore: Code improvements and optimizations
1 parent 11b8a5e commit 7307e04

File tree

5 files changed

+81
-70
lines changed

5 files changed

+81
-70
lines changed

core/common.py

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
class ConfigDict(dict):
3232
_bypass_restrictions = False
33-
_allowed_keys_for_get = ['custom_modules', 'custom_modules_manifest', 'formatters', 'STOP', 'environ', 'quick_options']
33+
_allowed_keys_for_get = ['custom_modules', 'custom_modules_manifest', 'formatters', 'environ', 'quick_options']
3434

3535
def get(self, key, *args, **kwargs): # access via CONFIG.get('key')
3636
if key in ConfigDict._allowed_keys_for_get:
@@ -94,6 +94,7 @@ def __init__(cls, name, bases, namespace, **kwargs):
9494
class Module(metaclass=ModuleMeta):
9595
'''
9696
API solely for interacting with files located in the 'modules' folder.
97+
These methods allow you to create a custom formatter adapter for your plugin.
9798
'''
9899

99100
def __init__(self, view=None, uid=None, region=None, interpreters=None, executables=None, dotfiles=None, temp_dir=None, type=None, auto_format_config=None, **kwargs):
@@ -108,10 +109,37 @@ def __init__(self, view=None, uid=None, region=None, interpreters=None, executab
108109
self.auto_format_config = auto_format_config
109110
self.kwargs = kwargs # @unused
110111

112+
# Track temp files created
113+
self._tmp_files_created = {}
114+
115+
def __del__(self):
116+
# Clean up automatically if autodel=True for any tmp files
117+
for tmp_file, autodel in self._tmp_files_created.items():
118+
if autodel:
119+
TempFileHandler.remove_tmp_file(tmp_file)
120+
else:
121+
log.warning(
122+
'Temporary files were created but not removed: %s\n'
123+
'Ensure that all temporary files are manually removed by using "self.remove_tmp_file(tmp_file)"\n'
124+
'Or, create the temporary file with automatic deletion by using "self.create_tmp_file(suffix=None, autodel=True)"', tmp_file
125+
)
126+
111127
@abc.abstractmethod
112128
def format(self):
113129
raise NotImplementedError('Subclasses must implement the "format()" method.')
114130

131+
def create_tmp_file(self, suffix=None, autodel=False):
132+
tmp_file = TempFileHandler.create_tmp_file(view=self.view, uid=self.uid, region=self.region, auto_format_config=self.auto_format_config, suffix=suffix)
133+
self._tmp_files_created[tmp_file] = autodel
134+
return tmp_file
135+
136+
def remove_tmp_file(self, tmp_file=None):
137+
if tmp_file in self._tmp_files_created:
138+
del self._tmp_files_created[tmp_file]
139+
return TempFileHandler.remove_tmp_file(tmp_file=tmp_file)
140+
else:
141+
raise ValueError('Attempting to remove a temporary file that was not created by this module instance.')
142+
115143
def is_executable(self, file=None):
116144
return FileHandler.is_executable(file=file)
117145

@@ -154,12 +182,6 @@ def is_view_formattable(self):
154182
def query(self, data_dict, default=None, *keys):
155183
return OptionHandler.query(data_dict, default, *keys)
156184

157-
def create_tmp_file(self, suffix=None):
158-
return TempFileHandler.create_tmp_file(view=self.view, uid=self.uid, region=self.region, auto_format_config=self.auto_format_config, suffix=suffix)
159-
160-
def remove_tmp_file(self, tmp_file=None):
161-
return TempFileHandler.remove_tmp_file(tmp_file=tmp_file)
162-
163185
def get_executable(self, runtime_type=None):
164186
return ArgumentHandler.get_executable(view=self.view, uid=self.uid, executables=self.executables, runtime_type=runtime_type)
165187

@@ -215,6 +237,24 @@ def popup_message(self, text, title=None, dialog=False):
215237

216238
# === Module Supporting Classes === #
217239

240+
class TempFileHandler:
241+
@staticmethod
242+
def create_tmp_file(view=None, uid=None, region=None, auto_format_config=None, suffix=None):
243+
if not suffix:
244+
uid, syntax = SyntaxHandler.get_assigned_syntax(view=view, uid=uid, region=region, auto_format_config=auto_format_config)
245+
suffix = '.' + syntax if syntax else None
246+
247+
with tempfile.NamedTemporaryFile(mode='w+', delete=False, suffix=suffix, dir=None, encoding='utf-8') as file:
248+
file.write(ViewHandler.get_text_from_region(view=view, region=region))
249+
file.close()
250+
return file.name
251+
252+
@staticmethod
253+
def remove_tmp_file(tmp_file=None):
254+
if tmp_file and os.path.isfile(tmp_file):
255+
os.unlink(tmp_file)
256+
257+
218258
class FileHandler:
219259
@staticmethod
220260
def _is_valid_file(file=None):
@@ -530,26 +570,6 @@ def query(data_dict, default=None, *keys):
530570
return data_dict
531571

532572

533-
class TempFileHandler:
534-
@staticmethod
535-
def create_tmp_file(view=None, uid=None, region=None, auto_format_config=None, suffix=None):
536-
if not suffix:
537-
uid, syntax = SyntaxHandler.get_assigned_syntax(view=view, uid=uid, region=region, auto_format_config=auto_format_config)
538-
suffix = '.' + syntax if syntax else None
539-
540-
with tempfile.NamedTemporaryFile(mode='w+', delete=False, suffix=suffix, dir=None, encoding='utf-8') as file:
541-
file.write(ViewHandler.get_text_from_region(view=view, region=region))
542-
file.close()
543-
return file.name
544-
545-
return None
546-
547-
@staticmethod
548-
def remove_tmp_file(tmp_file=None):
549-
if tmp_file and os.path.isfile(tmp_file):
550-
os.unlink(tmp_file)
551-
552-
553573
class ModeHandler:
554574
@staticmethod
555575
def is_generic_mode(uid=None):
@@ -1131,9 +1151,10 @@ class DataHandler:
11311151
_categories = {
11321152
'__sublime_preferences__': {'key': None, 'value': None},
11331153
'__project_config__': {'key': None, 'value': None},
1134-
'__save_paste_action__': {'key': None, 'value': None}, # current action
1154+
'__save_paste_action__': {'key': None, 'value': None}, # current action state
11351155
'__auto_format_chain_item__': {'key': None, 'value': None}, # current chaining item
1136-
'__auto_format_noop__': {'key': None, 'value': None} # current no operation id
1156+
'__auto_format_noop__': {'key': None, 'value': None}, # current no operation id
1157+
'__dir_format_stop__': {'key': None, 'value': None} # current dir format state
11371158
}
11381159

11391160
@classmethod

core/smanager.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import sublime
88
import sublime_plugin
99

10-
from . import CONFIG, OptionHandler, bulk_operation_detector, log
10+
from . import CONFIG, DataHandler, OptionHandler, bulk_operation_detector, log
1111

1212
SESSION_FILE = join(sublime.packages_path(), '..', 'Local', 'Session.formatter_session')
1313
MAX_AGE_DAYS = 180
@@ -171,10 +171,10 @@ def run_on_load(self, view):
171171
class SessionManagerListener(sublime_plugin.EventListener):
172172
@bulk_operation_detector.bulk_operation_guard(register=True)
173173
def on_load(self, view):
174-
if OptionHandler.query(CONFIG, True, 'remember_session') and CONFIG.get('STOP', True):
174+
if OptionHandler.query(CONFIG, True, 'remember_session') and (DataHandler.get('__dir_format_stop__')[1] or True):
175175
session_manager.run_on_load(view)
176176

177177
@bulk_operation_detector.bulk_operation_guard(register=True)
178178
def on_pre_close(self, view):
179-
if OptionHandler.query(CONFIG, True, 'remember_session') and CONFIG.get('STOP', True):
179+
if OptionHandler.query(CONFIG, True, 'remember_session') and (DataHandler.get('__dir_format_stop__')[1] or True):
180180
session_manager.run_on_pre_close(view)

core/wcounter.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import sublime
22
import sublime_plugin
33

4-
from . import (CONFIG, STATUS_KEY, OptionHandler, bulk_operation_detector,
5-
debounce, skip_word_counter)
4+
from . import (CONFIG, STATUS_KEY, DataHandler, OptionHandler,
5+
bulk_operation_detector, debounce, skip_word_counter)
66

77
CHUNK_SIZE = 1024 * 1024 # ≈ 1048576 chars (1MB)
88

@@ -94,7 +94,7 @@ class WordCounterListener(sublime_plugin.EventListener):
9494
@debounce(delay_in_ms=300)
9595
def on_selection_modified_async(self, view):
9696
x = OptionHandler.query(CONFIG, {}, 'show_words_count')
97-
if x.get('enable', True) and CONFIG.get('STOP', True):
97+
if x.get('enable', True) and (DataHandler.get('__dir_format_stop__')[1] or True):
9898
ignore_whitespace_char = x.get('ignore_whitespace_char', True)
9999
use_short_label = x.get('use_short_label', False)
100100
view.settings().set('show_line_column', 'disabled')

plugin/dir_format.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@
77

88
from ..core import (CONFIG, PACKAGE_NAME, RECURSIVE_FAILURE_DIRECTORY,
99
RECURSIVE_SUCCESS_DIRECTORY, STATUS_KEY, ConfigHandler,
10-
InterfaceHandler, OptionHandler, PathHandler,
10+
DataHandler, InterfaceHandler, OptionHandler, PathHandler,
1111
SyntaxHandler, TextHandler, TransformHandler, check_stop,
1212
log)
1313
from ..core.formatter import Formatter
1414
from . import ActivityIndicator
1515

16-
STOP = False
17-
START_TIME = None
16+
17+
class DirFormatState:
18+
STOP = False
19+
START_TIME = None
1820

1921

2022
def get_stop_status():
21-
return STOP
23+
return DirFormatState.STOP
2224

2325

2426
class DirFormat:
@@ -51,9 +53,8 @@ def run(self):
5153
self.start_timer()
5254

5355
try:
54-
global STOP
55-
STOP = False
56-
CONFIG['STOP'] = False # pause smanager and wcounter
56+
DirFormatState.STOP = False
57+
DataHandler.set('__dir_format_stop__', 'STOP', False) # pause smanager and wcounter
5758

5859
# Show progress indicator if formatting takes longer than 1s
5960
with ActivityIndicator(view=self.view, label='In Progress...', delay=1000):
@@ -69,9 +70,8 @@ def run(self):
6970

7071
@staticmethod
7172
def stop():
72-
global STOP
73-
STOP = True
74-
CONFIG['STOP'] = True
73+
DirFormatState.STOP = True
74+
DataHandler.set('__dir_format_stop__', 'STOP', True)
7575

7676
@staticmethod
7777
def format_elapsed_time(seconds):
@@ -86,16 +86,14 @@ def format_elapsed_time(seconds):
8686

8787
@staticmethod
8888
def start_timer():
89-
global START_TIME
90-
START_TIME = perf_counter()
89+
DirFormatState.START_TIME = perf_counter()
9190

9291
def end_timer(self):
93-
global START_TIME
94-
if START_TIME is None:
92+
if DirFormatState.START_TIME is None:
9593
log.warning('Timer was not started.')
9694
return 'N/A'
97-
elapsed_time = perf_counter() - START_TIME
98-
START_TIME = None
95+
elapsed_time = perf_counter() - DirFormatState.START_TIME
96+
DirFormatState.START_TIME = None
9997
return self.format_elapsed_time(elapsed_time)
10098

10199
def get_current_working_directory(self):
@@ -253,7 +251,7 @@ def show_completion_message(self):
253251
'Time: {}\n\n'
254252
'Please check the result in:\n{}'
255253
).format(
256-
'COMPLETED' if STOP is False else 'ABORTED',
254+
'COMPLETED' if DirFormatState.STOP is False else 'ABORTED',
257255
ok, ko, total, etime, cwd
258256
)
259257

@@ -263,7 +261,7 @@ def reset_context(self):
263261
for key in self.CONTEXT:
264262
self.CONTEXT[key] = [] if isinstance(self.CONTEXT[key], list) else 0 if isinstance(self.CONTEXT[key], int) else None
265263
# Reset and end
266-
CONFIG['STOP'] = True
264+
DataHandler.set('__dir_format_stop__', 'STOP', True)
267265

268266
@staticmethod
269267
def handle_error(error, cwd=None, file_path=None):

plugin/formatter_listener.py

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,23 @@ def on_activated(self, view):
2525
if OptionHandler.query(CONFIG, False, 'layout', 'sync_scroll') and LayoutHandler.want_layout():
2626
sync_scroll_manager.stop_sync_scroll()
2727

28-
src_view = self._find_src_view_by_dst_view(view)
28+
src_view = self._find_view_by_reference(view, lookup_src=False)
2929
if src_view:
3030
sync_scroll_manager.start_sync_scroll('src', view, src_view)
3131
else:
32-
dst_view = self._find_dst_view_by_src_view(view)
32+
dst_view = self._find_view_by_reference(view, lookup_src=True)
3333
if dst_view:
3434
sync_scroll_manager.start_sync_scroll('dst', view, dst_view)
3535

3636
@staticmethod
37-
def _find_src_view_by_dst_view(dst_view):
38-
src_view_id = dst_view.settings().get('txt_vref')
39-
if src_view_id:
40-
for window in sublime.windows():
41-
for view in window.views():
42-
if view.id() == src_view_id:
43-
return view
44-
return None
37+
def _find_view_by_reference(view, lookup_src=True):
38+
view_id = view.id() if lookup_src else view.settings().get('txt_vref')
4539

46-
@staticmethod
47-
def _find_dst_view_by_src_view(src_view):
48-
src_view_id = src_view.id()
49-
for window in sublime.windows():
50-
for view in window.views():
51-
if view.settings().get('txt_vref') == src_view_id:
52-
return view
40+
if view_id:
41+
for window in sublime.windows():
42+
for v in window.views():
43+
if (v.settings().get('txt_vref') == view_id) if lookup_src else (v.id() == view_id):
44+
return v
5345
return None
5446

5547
def on_pre_close(self, view):

0 commit comments

Comments
 (0)