forked from evandroforks/SublimePackageDefault
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
block.py
109 lines (79 loc) · 2.97 KB
/
block.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
import sublime
import sublime_plugin
def next_line(view, pt):
return view.line(pt).b + 1
def prev_line(view, pt):
return view.line(pt).a - 1
def is_ws(str):
for ch in str:
if ch != ' ' and ch != '\t':
return False
return True
def indented_block(view, r):
if r.empty():
if r.a == view.size():
return False
nl = next_line(view, r.a)
nr = view.indented_region(nl)
if nr.a < nl:
nr.a = nl
this_indent = view.indentation_level(r.a)
next_indent = view.indentation_level(nl)
ok = False
if this_indent + 1 == next_indent:
ok = True
if not ok:
prev_indent = view.indentation_level(prev_line(view, r.a))
# Mostly handle the care where the user has just pressed enter, and the
# auto indent will update the indentation to something that will trigger
# the block behavior when { is pressed
line_str = view.substr(view.line(r.a))
if is_ws(line_str) and len(view.get_regions("autows")) > 0:
if prev_indent + 1 == this_indent and this_indent == next_indent:
ok = True
if ok:
# ensure that every line of nr is indented more than nl
l = next_line(view, nl)
while l < nr.end():
if view.indentation_level(l) == next_indent:
return False
l = next_line(view, l)
return True
return False
class BlockContext(sublime_plugin.EventListener):
def on_query_context(self, view, key, operator, operand, match_all):
if key == "indented_block":
is_all = True
is_any = False
if operator != sublime.OP_EQUAL and operator != sublime.OP_NOT_EQUAL:
return False
for r in view.sel():
if operator == sublime.OP_EQUAL:
b = (operand == indented_block(view, r))
else:
b = (operand != indented_block(view, r))
if b:
is_any = True
else:
is_all = False
if match_all:
return is_all
else:
return is_any
return None
class WrapBlockCommand(sublime_plugin.TextCommand):
def run(self, edit, begin, end):
self.view.run_command('insert', {'characters': begin})
regions = reversed([s for s in self.view.sel()])
for r in regions:
if r.empty():
nl = next_line(self.view, r.a)
nr = self.view.indented_region(nl)
begin_line = self.view.substr(self.view.line(r.a))
ws = ""
for ch in begin_line:
if ch == ' ' or ch == '\t':
ws += ch
else:
break
self.view.insert(edit, nr.end(), ws + end + "\n")