Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: Meta-Interpreter #59

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions ExpandRegion.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sublime, sublime_plugin, os
import sublime
import sublime_plugin

try:
import expand_region_handler
Expand Down Expand Up @@ -37,6 +38,7 @@ def _detect_language(view, settings_name):
point = view.sel()[0].b
settings = sublime.load_settings(settings_name + ".sublime-settings")
selectors = settings.get("scope_selectors")

def maximal_score(scopes):
if not scopes: # validity check
return 0
Expand Down Expand Up @@ -68,7 +70,8 @@ def run(self, edit, language="", undo=False, debug=False):

if not language:
language = (_detect_language(view, "ExpandRegion") or
_detect_language(view, "ExpandRegionFallback"))
_detect_language(view, "ExpandRegionFallback") or
"javascript")
if debug:
print("ExpandRegion, ExpandRegion.py, Determined language: '{0}'".format(language))

Expand Down Expand Up @@ -146,6 +149,7 @@ def run(self, edit, language="", undo=False, debug=False):
view.run_command( "expand_selection", {"to": "scope"} )



class ExpandRegionContext(sublime_plugin.EventListener):
def on_query_context(self, view, key, *args):
if key == "expand_region_soft_undo":
Expand Down
32 changes: 8 additions & 24 deletions expand_region_handler.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
import re, hashlib, json
import hashlib
import json

try:
import javascript
import html
import latex
import python
import interpreter
import utils
except:
from . import javascript
from . import html
from . import latex
from . import python
from . import interpreter
from . import utils


def expand(string, start, end, language="", settings=None):

if language == "html":
result = html.expand(string, start, end)
elif language == "latex":
result = latex.expand(string, start, end)
elif language == "python":
result = python.expand(string, start, end)
else:
result = javascript.expand(string, start, end)
def expand(string, start, end, language, settings=None):
result = interpreter.interp(language, string, start, end)

if (result != None and settings):
expand_region_settings = settings.get("expand_region_settings")
Expand All @@ -34,8 +21,8 @@ def expand(string, start, end, language="", settings=None):

return result;

def undo(string, start, end, settings=None):

def undo(string, start, end, settings=None):
if (settings):
expand_region_settings = settings.get("expand_region_settings")
result = get_last_selection(expand_region_settings, string.encode('utf-8'), start, end)
Expand Down Expand Up @@ -67,6 +54,7 @@ def add_to_stack(settingsJson, string, startIndex, endIndex, oldStartIndex, oldE
newSettingsJson = json.dumps(settings)
return newSettingsJson


def get_last_selection(settingsJson, string, startIndex, endIndex):
settings = json.loads(settingsJson)
newSelection = None
Expand All @@ -90,7 +78,3 @@ def get_last_selection(settingsJson, string, startIndex, endIndex):
newSelection = {"startIndex": lastStackItem.get("start"), "endIndex": lastStackItem.get("end")}
newSettingsJson = json.dumps(settings)
return {"newSettingsJson": newSettingsJson, "newSelection": newSelection}




33 changes: 11 additions & 22 deletions expand_to_indent.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,21 @@
import re

try:
# Block it from trying to import something which should not be on the python sys.path
# https://github.com/hktonylee/SublimeNumberKing/issues/4
import expand_region_handler
import utils
import interpreter
except:
from . import utils


_INDENT_RE = re.compile(r"^(?P<spaces>\s*)")
from . import interpreter


def empty_line(string, line):
return not string[line["start"]:line["end"]].strip()


def get_indent(string, line):
line_str = string[line["start"]:line["end"]]
m = _INDENT_RE.match(line_str)
if m is None: # should never happen
return 0
return len(m.group("spaces"))


def _expand_to_indent(string, start, end):
line = utils.get_line(string, start, end)
indent = get_indent(string, line)
indent = utils.get_indent(string, line)
start = line["start"]
end = line["end"]
before_line = line
Expand All @@ -36,7 +25,7 @@ def _expand_to_indent(string, start, end):
if pos <= 0:
break
before_line = utils.get_line(string, pos, pos)
before_indent = get_indent(string, before_line)
before_indent = utils.get_indent(string, before_line)
# done if the line has a lower indent
if not indent <= before_indent and not empty_line(string, before_line):
break
Expand All @@ -51,7 +40,7 @@ def _expand_to_indent(string, start, end):
if pos >= len(string):
break
after_line = utils.get_line(string, pos, pos)
after_indent = get_indent(string, after_line)
after_indent = utils.get_indent(string, after_line)
# done if the line has a lower indent
if not indent <= after_indent and not empty_line(string, after_line):
break
Expand All @@ -64,15 +53,12 @@ def _expand_to_indent(string, start, end):

def expand_to_indent(string, start, end):
result = _expand_to_indent(string, start, end)
if result["start"] == start and result["end"] == end:
return None
return result


def py_expand_to_indent(string, start,
end):
def py_expand_to_indent(string, start, end):
line = utils.get_line(string, start, end)
indent = get_indent(string, line)
indent = utils.get_indent(string, line)
# we don't expand to indent 0 (whole document)
if indent == 0:
return None
Expand All @@ -90,10 +76,13 @@ def py_expand_to_indent(string, start,
return None
# get the indent of the line before
before_line = utils.get_line(string, pos, pos)
before_indent = get_indent(string, before_line)
before_indent = utils.get_indent(string, before_line)
if not empty_line(string, before_line) and before_indent < indent:
start = before_line["start"]
end = result["end"]
return utils.create_return_obj(start, end, string, "py_indent")
# goto the line before the line befor
pos = before_line["start"] - 1

interpreter.register_command("indent", expand_to_indent)
interpreter.register_command("py_indent", py_expand_to_indent)
57 changes: 19 additions & 38 deletions expand_to_line.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,32 @@
import re

try:
# Block it from trying to import something which should not be on the python sys.path
# https://github.com/hktonylee/SublimeNumberKing/issues/4
import expand_region_handler
import utils
import interpreter
except:
from . import utils
from . import interpreter

def expand_to_line(string, startIndex, endIndex):
linebreakRe = re.compile(r'\n')

spacesAndTabsRe = re.compile(r'([ \t]+)')
def expand_to_line(string, start, end):
line = utils.get_line(string, start, end)
indent = utils.get_indent(string, line)
lstart = line["start"] + indent
if start < lstart:
lstart = line["start"]
lend = max(end, line["end"])
if lstart == start and lend == end:
return
return utils.create_return_obj(lstart, lend, string, "line")

searchIndex = startIndex - 1;
while True:
if searchIndex < 0:
newStartIndex = searchIndex + 1
break
char = string[searchIndex:searchIndex+1]
if linebreakRe.match(char):
newStartIndex = searchIndex + 1
break
else:
searchIndex -= 1

searchIndex = endIndex;
while True:
if searchIndex > len(string) - 1:
newEndIndex = searchIndex
break
char = string[searchIndex:searchIndex+1]
if linebreakRe.match(char):
newEndIndex = searchIndex
break
else:
searchIndex += 1
def expand_to_full_line(string, start, end):
line = utils.get_line(string, start, end)
lstart = line["start"]
lend = line["end"]
return utils.create_return_obj(lstart, lend, string, "full_line")

s = string[newStartIndex:newEndIndex]
r = spacesAndTabsRe.match(s)
if r and r.end() <= startIndex:
newStartIndex = newStartIndex + r.end();

try:
if startIndex == newStartIndex and endIndex == newEndIndex:
return None
else:
return utils.create_return_obj(newStartIndex, newEndIndex, string, "line")
except NameError:
return None
interpreter.register_command("line", expand_to_line)
interpreter.register_command("full_line", expand_to_full_line)
8 changes: 7 additions & 1 deletion expand_to_quotes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
# https://github.com/hktonylee/SublimeNumberKing/issues/4
import expand_region_handler
import utils
import interpreter
except:
from . import utils
from . import interpreter


def expand_to_quotes(string, selection_start, selection_end):
quotes_regex = re.compile("(['\"])(?:\\\.|.)*?\\1")
Expand All @@ -20,7 +23,8 @@ def expand_to_quotes(string, selection_start, selection_end):
if quotes_end < selection_start:
continue

# quotes pair start is after selection, return, no need to continue loop
# quotes pair start is after selection, return, no need to continue
# loop
if quotes_start > selection_end:
return None

Expand All @@ -39,3 +43,5 @@ def expand_to_quotes(string, selection_start, selection_end):
# selection is within the found quote pairs, return "quotes content"
if(selection_start > quotes_start and selection_end < quotes_end):
return utils.create_return_obj(quotes_content_start, quotes_content_end, string, "quotes")

interpreter.register_command("quotes", expand_to_quotes)
13 changes: 11 additions & 2 deletions expand_to_regex_set.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import re

try:
# Block it from trying to import something which should not be on the python sys.path
# https://github.com/hktonylee/SublimeNumberKing/issues/4
import expand_region_handler
import utils
import interpreter
except:
from . import utils
from . import interpreter


def _expand_to_regex_rule(string, startIndex, endIndex, regex, type):
def expand_to_regex_rule(string, startIndex, endIndex, regex=r"\w",
expand_type="regex"):
regex = re.compile(regex)
# if there is a selection (and not only a blinking cursor)
if(startIndex != endIndex):
selection = string[startIndex:endIndex]
Expand Down Expand Up @@ -49,8 +56,10 @@ def _expand_to_regex_rule(string, startIndex, endIndex, regex, type):
if startIndex == newStartIndex and endIndex == newEndIndex:
return None
else:
return utils.create_return_obj(newStartIndex, newEndIndex, string, type)
return utils.create_return_obj(newStartIndex, newEndIndex, string, expand_type)
except NameError:
# newStartIndex or newEndIndex might not have been defined above, because
# the character was not found.
return None

interpreter.register_command("regex", expand_to_regex_rule)
5 changes: 5 additions & 0 deletions expand_to_semantic_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
# https://github.com/hktonylee/SublimeNumberKing/issues/4
import expand_region_handler
import utils
import interpreter
except:
from . import utils
from . import interpreter


# This function definitely sucks and needs a serious rework. Finding semantic
# units is not that easy. Maybe a parser is needed?
Expand Down Expand Up @@ -91,3 +94,5 @@ def expand_to_semantic_unit(string, startIndex, endIndex):
return utils.create_return_obj(newStartIndex, newEndIndex, string, "semantic_unit")
except NameError:
return None

interpreter.register_command("semantic_unit", expand_to_semantic_unit)
6 changes: 5 additions & 1 deletion expand_to_subword.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

try:
import expand_to_regex_set
import interpreter
except:
from . import expand_to_regex_set
from . import interpreter


def expand_to_subword(string, start, end):
Expand All @@ -14,7 +16,7 @@ def expand_to_subword(string, start, end):
else:
regex = re.compile(r"[a-z]")

result = expand_to_regex_set._expand_to_regex_rule(
result = expand_to_regex_set.expand_to_regex_rule(
string, start, end, regex, "subword")
if result is None:
return None
Expand Down Expand Up @@ -49,3 +51,5 @@ def _is_inside_upper(string, start, end):
sub_str = sub_str[1:3]
contains_lower = re.search(r"[a-z]", sub_str)
return bool(contains_upper) and not bool(contains_lower)

interpreter.register_command("subword", expand_to_subword)
Loading