-
Notifications
You must be signed in to change notification settings - Fork 52
/
indent_list_item.py
85 lines (66 loc) · 3.3 KB
/
indent_list_item.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
import re
import sublime
import sublime_plugin
class IndentListItemCommand(sublime_plugin.TextCommand):
bullet_pattern = r'([-+*]|([(]?(\d+|#|[a-y]|[A-Y]|[MDCLXVImdclxvi]+))([).]))'
bullet_pattern_re = re.compile(bullet_pattern)
line_pattern_re = re.compile(r'^\s*' + bullet_pattern)
spaces_re = re.compile(r'^\s*')
def run(self, edit, reverse=False):
for region in self.view.sel():
if region.a != region.b:
continue
line = self.view.line(region)
line_content = self.view.substr(line)
new_line = line_content
m = self.line_pattern_re.match(new_line)
if not m:
return
# Determine how to indent (tab or spaces)
tab_str = self.view.settings().get('tab_size', 4) * ' '
sep_str = ' ' if m.group(4) else ''
prev_line = self.view.line(sublime.Region(line.begin() - 1, line.begin() - 1))
prev_line_content = self.view.substr(prev_line)
prev_prev_line = self.view.line(sublime.Region(prev_line.begin() - 1, prev_line.begin() - 1))
prev_prev_line_content = self.view.substr(prev_prev_line)
if not reverse:
# Do the indentation
new_line = self.bullet_pattern_re.sub(tab_str + sep_str + r'\1', new_line)
# Insert the new item
if prev_line_content:
new_line = '\n' + new_line
else:
if not new_line.startswith(tab_str):
continue
# Do the unindentation
new_line = re.sub(tab_str + sep_str + self.bullet_pattern, r'\1', new_line)
# Insert the new item
if prev_line_content:
new_line = '\n' + new_line
else:
prev_spaces = self.spaces_re.match(prev_prev_line_content).group(0)
spaces = self.spaces_re.match(new_line).group(0)
if prev_spaces == spaces:
line = sublime.Region(line.begin() - 1, line.end())
endings = ['.', ')']
# Transform the bullet to the next/previous bullet type
if self.view.settings().get('list_indent_auto_switch_bullet', True):
bullets = self.view.settings().get('list_indent_bullets', ['*', '-', '+'])
def change_bullet(m):
bullet = m.group(1)
try:
return bullets[(bullets.index(bullet) + (1 if not reverse else -1)) % len(bullets)]
except ValueError:
pass
n = m.group(2)
ending = endings[(endings.index(m.group(4)) + (1 if not reverse else -1)) % len(endings)]
if n.isdigit():
return '${1:a}' + ending
elif n != '#':
return '${1:0}' + ending
return m.group(2) + ending
new_line = self.bullet_pattern_re.sub(change_bullet, new_line)
self.view.replace(edit, line, '')
self.view.run_command('insert_snippet', {'contents': new_line})
def is_enabled(self):
return bool(self.view.score_selector(self.view.sel()[0].a, 'text.restructuredtext'))