Files
2013-04-04 08:54:25 -04:00

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})