-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathappend_seletion.py
121 lines (93 loc) · 2.78 KB
/
append_seletion.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
import sublime
import sublime_plugin
import re
selection_added = False
class AppendSeletion(sublime_plugin.TextCommand):
def __init__(self, view):
super().__init__(view)
self.last_word = None
def run(self, edit, word = False, backward = False, skip = False,
repeat_last_with_skip = False):
if repeat_last_with_skip:
word = self.last_word
backward = self.last_backward
skip = True
self.last_word = word
self.last_backward = backward
sels = self.view.sel()
if len(sels) == 0:
return
result = self._get_next_selection(sels, word, backward)
if result == None:
return
sel, matches, shift = result
self._append_selection(skip, sel, matches, shift)
global selection_added
selection_added = True
def _append_selection(self, skip, sel, matches, shift):
try:
match = matches.__next__()
except StopIteration:
return
start, end = match.start(1) + shift, match.end(1) + shift
if sel.a > sel.b:
start, end = end, start
selection = sublime.Region(start, end)
if skip:
self.remove_last_selection()
self.view.sel().add(selection)
regions = []
for match in matches:
start, end = match.start(1) + shift, match.end(1) + shift
regions.append(sublime.Region(start, end))
self.view.erase_regions('append_selection')
self.view.add_regions('append_selection', regions, 'string', '',
sublime.DRAW_EMPTY)
def remove_last_selection(self):
sels = self.view.sel()
old = []
for index, sel in enumerate(sels):
if index == len(sels) - 1:
continue
old.append(sel)
self.view.sel().clear()
for sel in old:
self.view.sel().add(sel)
def _get_next_selection(self, sels, word, backward):
if backward:
sel = sels[0]
else:
sel = sels[-1]
if sel.empty():
sel = self.view.word(sel.b)
if sel.empty():
return None
if backward:
cursor = sel.end()
else:
cursor = sel.begin()
else:
if backward:
cursor = sel.begin()
else:
cursor = sel.end()
selected = self.view.substr(sel)
if backward:
region = sublime.Region(0, cursor)
else:
region = sublime.Region(cursor, self.view.size())
text = self.view.substr(region)
if word:
matches = re.finditer(r'\W(' + re.escape(selected) + r')\W', text)
else:
matches = re.finditer(r'(' + re.escape(selected) + r')', text)
if backward:
matches = reversed(list(matches))
return sel, matches, region.a
class AppendSeletionListener(sublime_plugin.EventListener):
def on_selection_modified_async(self, view):
global selection_added
if selection_added:
selection_added = False
return
view.erase_regions('append_selection')