160 lines
6.2 KiB
Python
160 lines
6.2 KiB
Python
#!/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 = ""
|
|
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})
|