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

152 lines
5.1 KiB
Python

# -*- coding: utf-8 -*-
import os
import re
from itertools import chain, product
import sublime
import sublime_plugin
def import_dir(name, fromlist=()):
PACKAGE_EXT = '.sublime-package'
dirname = os.path.basename(os.path.dirname(os.path.realpath(__file__)))
if dirname.endswith(PACKAGE_EXT):
dirname = dirname[:-len(PACKAGE_EXT)]
return __import__('{0}.{1}'.format(dirname, name), fromlist=fromlist)
try:
extract = import_dir('probe', ('extract',)).extract
except ImportError:
from probe import extract
try:
make_template = import_dir('templates', ('make_template',)).make_template
except ImportError:
from templates import make_template
try:
parse_dict_json = import_dir('css_dict_driver', ('parse_dict_json',)).parse_dict_json
except ImportError:
from css_dict_driver import parse_dict_json
try:
get_hayaku_options = import_dir('add_code_block', ('add_code_block',)).get_hayaku_options
except ImportError:
from add_code_block import get_hayaku_options
# The maximum size of a single propery to limit the lookbehind
MAX_SIZE_CSS = len('-webkit-transition-timing-function')
ABBR_REGEX = re.compile(r'[\s|;|{]([\.:%#a-z-,\d]+!?)$', re.IGNORECASE)
class HayakuCommand(sublime_plugin.TextCommand):
def run(self, edit):
cur_pos = self.view.sel()[0].begin()
start_pos = cur_pos - MAX_SIZE_CSS
if start_pos < 0:
start_pos = 0
# TODO: Move this to the contexts, it's not needed here
probably_abbr = self.view.substr(sublime.Region(start_pos, cur_pos))
match = ABBR_REGEX.search(probably_abbr)
if match is None:
self.view.insert(edit, cur_pos, '\t')
return
abbr = match.group(1)
# Extracting the data from the abbr
args = extract(abbr)
if not args:
return
# Getting the options and making a snippet
# from the extracted data
get_hayaku_options(self)
options = get_hayaku_options(self)
template = make_template(args, options)
if template is None:
return
# Inserting the snippet
new_cur_pos = cur_pos - len(abbr)
assert cur_pos - len(abbr) >= 0
self.view.erase(edit, sublime.Region(new_cur_pos, cur_pos))
self.view.run_command("insert_snippet", {"contents": template})
# Helpers for getting the right indent for the Add Line Command
WHITE_SPACE_FINDER = re.compile(r'^(\s*)(-)?[\w]*')
def get_line_indent(line):
return WHITE_SPACE_FINDER.match(line).group(1)
def is_prefixed_property(line):
return WHITE_SPACE_FINDER.match(line).group(2) is not None
def get_previous_line(view, line_region):
return view.line(line_region.a - 1)
def get_nearest_indent(view):
line_region = view.line(view.sel()[0])
line = view.substr(line_region)
line_prev_region = get_previous_line(view,line_region)
found_indent = None
first_indent = None
first_is_ok = True
is_nested = False
# Can we do smth with all those if-else noodles?
if not is_prefixed_property(line):
first_indent = get_line_indent(line)
if not is_prefixed_property(view.substr(line_prev_region)):
return first_indent
if is_prefixed_property(view.substr(line_prev_region)):
first_is_ok = False
while not found_indent and line_prev_region != view.line(sublime.Region(0)):
line_prev = view.substr(line_prev_region)
if not first_indent:
if not is_prefixed_property(line_prev):
first_indent = get_line_indent(line_prev)
if is_prefixed_property(view.substr(get_previous_line(view,line_prev_region))):
first_is_ok = False
else:
if not is_prefixed_property(line_prev) and not is_prefixed_property(view.substr(get_previous_line(view,line_prev_region))):
found_indent = min(first_indent,get_line_indent(line_prev))
line_prev_region = get_previous_line(view,line_prev_region)
if line_prev.count("{"):
is_nested = True
if found_indent and found_indent < first_indent and not is_prefixed_property(view.substr(get_previous_line(view,line_region))) and first_is_ok or is_nested:
found_indent = found_indent + " "
if not found_indent:
if first_indent:
found_indent = first_indent
else:
found_indent = ""
return found_indent
class HayakuAddLineCommand(sublime_plugin.TextCommand):
def run(self, edit):
nearest_indent = get_nearest_indent(self.view)
# Saving current auto_indent setting
# This hack fixes ST2's bug with incorrect auto_indent for snippets
# It seems that with auto indent off it uses right auto_indent there lol.
current_auto_indent = self.view.settings().get("auto_indent")
self.view.settings().set("auto_indent",False)
self.view.run_command('insert', {"characters": "\n"})
self.view.erase(edit, sublime.Region(self.view.line(self.view.sel()[0]).a, self.view.sel()[0].a))
self.view.run_command('insert', {"characters": nearest_indent})
self.view.settings().set("auto_indent",current_auto_indent)