forked from hayaku/hayaku
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadd_code_block.py
160 lines (135 loc) · 6.43 KB
/
add_code_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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/python
import re
import sublime
import sublime_plugin
# __all__ = [
# 'HayakuAddCodeBlockCommand',
# 'HayakuExpandCodeBlockCommand',
# ]
# Guessing the codestyle 1 2 3 4 5 6 7 8 9
GUESS_REGEX = re.compile(r'selector(\s*)(\{)?(\s*)property(:)?(\s*)value(;)?(\s*)(\})?(\s*)', re.IGNORECASE)
def get_hayaku_options(self):
settings = self.view.settings()
options = {}
match = {}
# Autoguessing the options
if settings.get("hayaku_CSS_syntax_autoguess"):
autoguess = settings.get("hayaku_CSS_syntax_autoguess")
offset = len(autoguess[0]) - len(autoguess[0].lstrip())
autoguess = [ s[offset:].rstrip() for s in autoguess]
match = GUESS_REGEX.search('\n'.join(autoguess))
# Helper to set an option got from multiple sources
def get_setting(setting, fallback, match_group = False):
if match_group and match:
fallback = match.group(match_group)
single_setting = False
if settings.has("hayaku_" + setting):
single_setting = settings.get("hayaku_" + setting, fallback)
options[setting] = single_setting or fallback
# Some hardcode for different scopes
# (could this be defined better?)
scope_name = self.view.scope_name(self.view.sel()[0].a)
is_sass = sublime.score_selector(scope_name, 'source.sass') > 0
is_stylus = sublime.score_selector(scope_name, 'source.stylus') > 0
disable_braces = is_stylus or is_sass
if is_stylus and match and match.group(2) and match.group(8):
disable_braces = False
disable_colons = is_stylus
if match and match.group(4):
disable_colons = False
disable_semicolons = is_stylus or is_sass
if is_stylus and match and match.group(6):
disable_semicolons = False
# Calling helper, getting all the needed options
get_setting("CSS_whitespace_block_start_before", " ", 1 )
get_setting("CSS_whitespace_block_start_after", "\n\t", 3 )
get_setting("CSS_whitespace_block_end_before", "\n", 7 )
get_setting("CSS_whitespace_block_end_after", "", 9 )
get_setting("CSS_whitespace_after_colon", " ", 5 )
get_setting("CSS_newline_after_expand", False)
get_setting("CSS_syntax_no_curly_braces", disable_braces )
get_setting("CSS_syntax_no_colons", disable_colons )
get_setting("CSS_syntax_no_semicolons", disable_semicolons )
get_setting("CSS_syntax_url_quotes", (is_stylus or is_sass) )
get_setting("CSS_syntax_quote_symbol", "\"" ) # or "'"
get_setting("CSS_prefixes_disable", False )
get_setting("CSS_prefixes_align", not (is_stylus or is_sass) )
get_setting("CSS_prefixes_only", [] )
get_setting("CSS_prefixes_no_unprefixed", False )
get_setting("CSS_disable_postexpand", False )
get_setting("CSS_units_for_unitless_numbers", False )
get_setting("CSS_colors_case", "uppercase" ) # or "lowercase" or "initial"
get_setting("CSS_colors_length", "short" ) # or "long" or "initial"
get_setting("CSS_clipboard_defaults", ["colors","images"] )
return options
def hayaku_get_block_snippet(options, inside = False):
start_before = options["CSS_whitespace_block_start_before"]
start_after = options["CSS_whitespace_block_start_after"]
end_before = options["CSS_whitespace_block_end_before"]
end_after = options["CSS_whitespace_block_end_after"]
opening_brace = "{"
closing_brace = "}"
if options["CSS_syntax_no_curly_braces"]:
opening_brace = ""
closing_brace = ""
if '\n' in start_before:
start_after = ""
end_after = ""
if inside:
opening_brace = ""
closing_brace = ""
start_before = ""
end_after = ""
return ''.join([
start_before
, opening_brace
, start_after
, "$0"
, end_before
, closing_brace
, end_after
])
# Command
class HayakuExpandCodeBlockCommand(sublime_plugin.TextCommand):
def run(self, edit):
# TODO: consume the braces and whitespaces around and inside
self.view.run_command("insert_snippet", {"contents": hayaku_get_block_snippet(get_hayaku_options(self),True)})
class HayakuAddCodeBlockCommand(sublime_plugin.TextCommand):
def run(self, edit):
result = '/* OVERRIDE ME */'
# Determine the limits for place searching
regions = self.view.sel()
region = regions[0]
line = self.view.line(region)
stop_point = self.view.find('[}]\s*',line.begin())
if stop_point is not None and not (-1, -1):
end = stop_point.end()
else:
end = self.view.find('[^}]*',line.begin()).end()
where_to_search = self.view.substr(
sublime.Region(
line.begin(),
end
)
)
options = get_hayaku_options(self)
# Insert a code block if we must
found_insert_position = re.search('^([^}{]*?[^;,}{\s])\s*(?=\n|$)',where_to_search)
if found_insert_position is not None:
self.view.sel().clear()
self.view.sel().add(sublime.Region(len(found_insert_position.group(1)) + line.begin(), len(found_insert_position.group(1)) + line.begin()))
result = hayaku_get_block_snippet(options)
else:
# Place a caret + create a new line otherwise
# FIXME: the newline is not perfectly inserted. Must rethink it so there wouldn't
# be replacement of all whitespaces and would be better insertion handling
found_insert_rule = re.search('^(([^}]*?[^;]?)\s*)(?=\})',where_to_search)
if found_insert_rule:
self.view.sel().clear()
self.view.sel().add(sublime.Region(len(found_insert_rule.group(2)) + line.begin(), len(found_insert_rule.group(1)) + line.begin()))
result = ''.join([
options["CSS_whitespace_block_start_after"]
, "$0"
, options["CSS_whitespace_block_end_before"]
])
self.view.run_command("insert_snippet", {"contents": result})