Skip to content

Commit ff34629

Browse files
authored
add type annotations (#159)
1 parent a0fcf9a commit ff34629

File tree

1 file changed

+46
-40
lines changed

1 file changed

+46
-40
lines changed

trailing_spaces.py

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010

1111
from .settings import TrailingSpacesSettings
1212
from os.path import isfile
13+
from typing import Dict, List, Literal, Tuple, Union, cast
1314
import codecs
1415
import difflib
1516
import re
1617
import sublime
1718
import sublime_plugin
1819

1920
# dictionary of currently active view ids and last visible regions
20-
active_views = {}
21+
active_views: Dict[int, sublime.Region] = {}
2122
current_highlight_color = ''
2223
on_disk = None
2324
# Highlight color as defined in settings. Plugin mutates that setting when disabled so
@@ -27,7 +28,7 @@
2728
settings = TrailingSpacesSettings()
2829

2930

30-
def plugin_loaded():
31+
def plugin_loaded() -> None:
3132
global current_highlight_color, INITIAL_HIGHLIGHT_COLOR
3233

3334
settings.load()
@@ -44,7 +45,7 @@ def plugin_loaded():
4445
# Private: Makes sure all timers are stopped.
4546
#
4647
# Returns nothing.
47-
def plugin_unloaded():
48+
def plugin_unloaded() -> None:
4849
global on_disk
4950

5051
# clear all active views to kill all timeouts
@@ -59,8 +60,8 @@ def plugin_unloaded():
5960
# regex - the regex pattern to search for
6061
#
6162
# Returns all matching trailing regions within regions.
62-
def view_find_all_in_regions(view, regions, regex):
63-
found = []
63+
def view_find_all_in_regions(view: sublime.View, regions: List[sublime.Region], regex: str) -> List[sublime.Region]:
64+
found: List[sublime.Region] = []
6465

6566
# find all matches in the region's text
6667
for region in regions:
@@ -81,15 +82,17 @@ def view_find_all_in_regions(view, regions, regex):
8182
#
8283
# Returns both the list of regions which map to trailing spaces and the list of
8384
# regions which are to be highlighted, as a list [matched, highlightable].
84-
def find_trailing_spaces(view, scan_only_visible=True):
85+
def find_trailing_spaces(
86+
view: sublime.View, scan_only_visible: bool = True
87+
) -> Tuple[List[sublime.Region], List[sublime.Region]]:
8588
include_empty_lines = settings.include_empty_lines
8689
include_current_line = settings.include_current_line
8790
regexp = settings.regexp + "$"
8891

8992
if not include_empty_lines:
9093
regexp = "(?<=\\S)%s$" % regexp
9194

92-
trailing_regions = []
95+
trailing_regions: List[sublime.Region] = []
9396

9497
non_visible_highlighting = settings.non_visible_highlighting
9598

@@ -114,13 +117,13 @@ def find_trailing_spaces(view, scan_only_visible=True):
114117
sel = view.sel()
115118

116119
if include_current_line or len(sel) == 0:
117-
return [trailing_regions, trailing_regions]
120+
return (trailing_regions, trailing_regions)
118121
else:
119122
selection_lines = [view.line(region.b) for region in sel]
120123
# find all matches in the current line and exclude them from highlighting
121124
selection_offenders = view_find_all_in_regions(view, selection_lines, regexp)
122125
highlightable = [r for r in trailing_regions if r not in selection_offenders]
123-
return [trailing_regions, highlightable]
126+
return (trailing_regions, highlightable)
124127

125128

126129
# Private: Find the freaking trailing spaces in the view and flags them as such!
@@ -132,7 +135,7 @@ def find_trailing_spaces(view, scan_only_visible=True):
132135
# view - the view, you know
133136
#
134137
# Returns nothing.
135-
def match_trailing_spaces(view):
138+
def match_trailing_spaces(view: sublime.View) -> None:
136139
# Silently pass ignored views.
137140
if ignore_view(view):
138141
return
@@ -150,14 +153,14 @@ def match_trailing_spaces(view):
150153
# view - the view to check.
151154
#
152155
# Returns True if the view should be ignored, False otherwise.
153-
def ignore_view(view):
156+
def ignore_view(view: sublime.View) -> bool:
154157
if view.is_scratch():
155158
return True
156159

157160
view_settings = view.settings()
158161
view_syntax = view_settings.get('syntax')
159162

160-
if not view_syntax or view_settings.get('is_widget'):
163+
if not isinstance(view_syntax, str) or view_settings.get('is_widget'):
161164
return False
162165

163166
for syntax_ignore in settings.syntax_ignore:
@@ -172,7 +175,7 @@ def ignore_view(view):
172175
# view - the view, you know
173176
#
174177
# Returns True or False.
175-
def max_size_exceeded(view):
178+
def max_size_exceeded(view: sublime.View) -> bool:
176179
return view.size() > settings.file_max_size
177180

178181

@@ -184,7 +187,7 @@ def max_size_exceeded(view):
184187
# regions - regions qualified as trailing spaces
185188
#
186189
# Returns nothing.
187-
def highlight_trailing_spaces_regions(view, regions):
190+
def highlight_trailing_spaces_regions(view: sublime.View, regions: List[sublime.Region]) -> None:
188191
view.erase_regions(HIGHLIGHT_REGION_KEY)
189192
if regions:
190193
view.add_regions(HIGHLIGHT_REGION_KEY, regions, current_highlight_color or "", "", sublime.HIDE_ON_MINIMAP)
@@ -197,7 +200,7 @@ def highlight_trailing_spaces_regions(view, regions):
197200
# view - the view, you know
198201
#
199202
# Returns True (highlighting was turned on) or False (turned off).
200-
def toggle_highlighting(view):
203+
def toggle_highlighting(view: sublime.View) -> Literal['disabled!', 'off', 'on']:
201204
global current_highlight_color
202205

203206
# If the scope is that of an invisible, there is nothing to toggle.
@@ -223,7 +226,7 @@ def toggle_highlighting(view):
223226
# window - the window, you know
224227
#
225228
# Returns nothing.
226-
def clear_trailing_spaces_highlight(window):
229+
def clear_trailing_spaces_highlight(window: sublime.Window) -> None:
227230
for view in window.views():
228231
view.erase_regions('TrailingSpacesMatchedRegions')
229232

@@ -241,7 +244,7 @@ def clear_trailing_spaces_highlight(window):
241244
# new - a buffer of lines, as in "new version"
242245
#
243246
# Returns the list of edited line numbers.
244-
def modified_lines_as_numbers(old, new):
247+
def modified_lines_as_numbers(old: List[str], new: List[str]) -> Union[Literal[False], List[int]]:
245248
d = difflib.Differ()
246249
diffs = d.compare(old, new)
247250

@@ -251,7 +254,7 @@ def modified_lines_as_numbers(old, new):
251254
# - the line is only in b: it qualifies as an edited line!
252255
# Starting from -1 as ST2 is internally 0-based for lines.
253256
lineNum = -1
254-
edited_lines = []
257+
edited_lines: List[int] = []
255258
for line in diffs:
256259
code = line[:2]
257260
# those lines with "? " are not real! watch out!
@@ -268,7 +271,7 @@ def modified_lines_as_numbers(old, new):
268271
# view - the view, you know
269272
#
270273
# Returns the list of regions matching dirty lines.
271-
def get_modified_lines(view):
274+
def get_modified_lines(view: sublime.View) -> List[sublime.Region]:
272275
on_buffer = view.substr(sublime.Region(0, view.size())).splitlines()
273276
lines = []
274277
line_numbers = modified_lines_as_numbers(on_disk or [], on_buffer)
@@ -286,7 +289,7 @@ def get_modified_lines(view):
286289
# view - the view, you know
287290
#
288291
# Returns a list of regions to be deleted.
289-
def find_regions_to_delete(view):
292+
def find_regions_to_delete(view: sublime.View) -> List[sublime.Region]:
290293
(regions, highlightable) = find_trailing_spaces(view, scan_only_visible=False)
291294

292295
# Filtering is required in case triming is restricted to dirty regions only.
@@ -295,7 +298,7 @@ def find_regions_to_delete(view):
295298

296299
# If there are no dirty lines, don't do nothing.
297300
if not modified_lines:
298-
return
301+
return []
299302

300303
# Super-private: filters trailing spaces regions to dirty lines only.
301304
#
@@ -314,9 +317,9 @@ def find_regions_to_delete(view):
314317
# we can re-create and store a Region for the relevant trailing spaces boundaries.
315318
#
316319
# Returns the filtered list of trailing spaces regions for the modified lines set.
317-
def only_those_with_trailing_spaces():
318-
regions_by_begin = {}
319-
matches = []
320+
def only_those_with_trailing_spaces() -> List[sublime.Region]:
321+
regions_by_begin: Dict[sublime.Point, Tuple[sublime.Point, sublime.Point]] = {}
322+
matches: List[sublime.Region] = []
320323
for region in regions:
321324
begin = view.line(region).begin()
322325
regions_by_begin[begin] = (region.begin(), region.end())
@@ -339,7 +342,7 @@ def only_those_with_trailing_spaces():
339342
# edit - the Edit object spawned by the deletion command
340343
#
341344
# Returns the number of deleted regions.
342-
def delete_trailing_regions(view, edit):
345+
def delete_trailing_regions(view: sublime.View, edit: sublime.Edit) -> int:
343346
regions = find_regions_to_delete(view)
344347

345348
if regions:
@@ -355,8 +358,11 @@ def delete_trailing_regions(view, edit):
355358

356359
# Public: Toggles the highlighting on or off.
357360
class ToggleTrailingSpacesCommand(sublime_plugin.WindowCommand):
358-
def run(self):
361+
def run(self) -> None:
359362
view = self.window.active_view()
363+
if not view:
364+
return
365+
360366
if max_size_exceeded(view):
361367
sublime.status_message("File is too big, trailing spaces handling disabled.")
362368
return
@@ -366,13 +372,13 @@ def run(self):
366372
settings.save()
367373
sublime.status_message('Highlighting of trailing spaces is %s' % state)
368374

369-
def is_checked(self):
375+
def is_checked(self) -> bool:
370376
return current_highlight_color != ""
371377

372378

373379
# Public: Toggles "Modified Lines Only" mode on or off.
374380
class ToggleTrailingSpacesModifiedLinesOnlyCommand(sublime_plugin.WindowCommand):
375-
def run(self):
381+
def run(self) -> None:
376382
was_on = settings.modified_lines_only
377383
settings.modified_lines_only = not was_on
378384
settings.save()
@@ -381,22 +387,22 @@ def run(self):
381387
else "Let's trim trailing spaces only on modified lines"
382388
sublime.status_message(message)
383389

384-
def is_checked(self):
390+
def is_checked(self) -> bool:
385391
return settings.modified_lines_only
386392

387393

388394
# Public: Matches and highlights trailing spaces on key events, according to the
389395
# current settings.
390396
class TrailingSpacesListener(sublime_plugin.EventListener):
391-
def on_modified_async(self, view):
397+
def on_modified_async(self, view: sublime.View) -> None:
392398
if settings.enabled:
393399
match_trailing_spaces(view)
394400

395-
def on_selection_modified_async(self, view):
401+
def on_selection_modified_async(self, view: sublime.View) -> None:
396402
if settings.enabled:
397403
match_trailing_spaces(view)
398404

399-
def on_activated_async(self, view):
405+
def on_activated_async(self, view: sublime.View) -> None:
400406
if settings.modified_lines_only:
401407
self.freeze_last_version(view)
402408

@@ -409,18 +415,18 @@ def on_activated_async(self, view):
409415
active_views[view.id()] = view.visible_region()
410416
self.update_on_region_change(view)
411417

412-
def on_pre_save(self, view):
418+
def on_pre_save(self, view: sublime.View) -> None:
413419
if settings.modified_lines_only:
414420
self.freeze_last_version(view)
415421

416422
if settings.trim_on_save:
417423
view.run_command("delete_trailing_spaces")
418424

419-
def on_close(self, view):
425+
def on_close(self, view: sublime.View) -> None:
420426
# untrack
421427
active_views.pop(view.id(), None)
422428

423-
def update_on_region_change(self, view):
429+
def update_on_region_change(self, view: sublime.View) -> None:
424430
# remove views not currently visible
425431
if not self.is_view_visible(view):
426432
active_views.pop(view.id(), None)
@@ -441,7 +447,7 @@ def update_on_region_change(self, view):
441447
# Anyway, let's cache the persisted version of the document's buffer for
442448
# later use on specific event, so that we always have a decent version of
443449
# "what's on the disk" to work with.
444-
def freeze_last_version(self, view):
450+
def freeze_last_version(self, view: sublime.View) -> None:
445451
global on_disk
446452

447453
file_name = view.file_name()
@@ -451,7 +457,7 @@ def freeze_last_version(self, view):
451457
encoding = view.encoding()
452458

453459
if encoding == "Undefined":
454-
encoding = view.settings().get("default_encoding", "UTF-8")
460+
encoding = cast(str, view.settings().get("default_encoding", "UTF-8"))
455461

456462
if encoding == "Hexadecimal": # not supported?
457463
on_disk = None
@@ -463,7 +469,7 @@ def freeze_last_version(self, view):
463469
with codecs.open(file_name, "r", encoding) as f:
464470
on_disk = f.read().splitlines()
465471

466-
def is_view_visible(self, view):
472+
def is_view_visible(self, view: sublime.View) -> bool:
467473
window = view.window()
468474
if not window:
469475
return False
@@ -497,7 +503,7 @@ def is_view_visible(self, view):
497503

498504
# Public: Deletes the trailing spaces.
499505
class DeleteTrailingSpacesCommand(sublime_plugin.TextCommand):
500-
def run(self, edit):
506+
def run(self, edit: sublime.Edit) -> None:
501507
if max_size_exceeded(self.view):
502508
sublime.status_message("File is too big, trailing spaces handling disabled.")
503509
return
@@ -516,7 +522,7 @@ def run(self, edit):
516522

517523
sublime.status_message(message)
518524

519-
def save(self, view):
525+
def save(self, view: sublime.View) -> None:
520526
if view.file_name() is None:
521527
view.run_command('prompt_save_as')
522528
else:

0 commit comments

Comments
 (0)