Skip to content

Commit

Permalink
refs #133, Line Ops
Browse files Browse the repository at this point in the history
  • Loading branch information
synkarius committed Jan 31, 2016
1 parent 42a5c80 commit 918cc27
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 31 deletions.
38 changes: 16 additions & 22 deletions caster/apps/eclipse.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,51 +117,45 @@ class CommandRule(MappingRule):
"split view vertical": R(Key("cs-lbrace"), rdescript="Eclipse: Split View (V)"),

#Line Ops
"configure": R(Paste(ec_con.analysis_chars)+Key("left:2/5, c-f/20, backslash, rbracket, enter") + \
Function(ec_con.analyze_for_configure), rdescript="Eclipse: Configure"),
"shackle <n> [<back>]": R(Key("c-l")+Key("right, cs-left")+ \
Function(ec_con.lines_relative), rdescript="Eclipse: Select Relative Lines"),
"jump in [<n>]": R(Key("c-f, a-o")+Paste(r"[\(\[\{\<]")+Function(ec_con.regex_on)+ \
Key("enter:%(n)d/5, escape, right") , rdescript="Eclipse: Jump In"),
"jump out [<n>]": R(Key("c-f, a-o")+Paste(r"[\)\] \}\>]")+Function(ec_con.regex_on)+ \
Key("enter:%(n)d/5, escape, right") , rdescript="Eclipse: Jump Out"),
"jump back [<n>]": R(Key("c-f/5, a-b")+Paste(r"[\)\]\}\>]")+Function(ec_con.regex_on)+ \
Key("enter:%(n)d/5, escape, left") , rdescript="Eclipse: Jump Back"),

# "search [<regex>] [<rtog>] [<direction>] <text>": R(Key("c-f") + Pause("50") + \
# Function(process_text_for_search) + \
# Function(set_direction), rdescript="Eclipse: Search") + \
# AsynchronousAction([L(S(["cancel"], Key("enter")))], 1, 50, "...", False),


}
extras = [
Dictation("text"),
Dictation("mim"),
IntegerRefST("n", 1, 3000),

# line ops
Boolean("back"),
# Choice("direction", {"back" : 0}),
# Choice("regex", {"reg" : 1}),
# Choice("rtog", {"toggle" : 1}),

]
defaults = {"n": 1, "mim":"", "back": False}#, "regex": 0, "rtog":0s
defaults = {"n": 1, "mim":""}#, "regex": 0, "rtog":0s

class EclipseCCR(MergeRule):
pronunciation = "eclipse"

mwith = [Navigation().get_name()]

mapping = {
#Line Ops
"configure": R(Paste(ec_con.analysis_chars)+Key("left:2/5, c-f/20, backslash, rbracket, enter") + \
Function(ec_con.analyze_for_configure), rdescript="Eclipse: Configure"),
"jump in [<n>]": R(Key("c-f, a-o")+Paste(r"[\(\[\{\<]")+Function(ec_con.regex_on)+ \
Key("enter:%(n)d/5, escape, right") , rdescript="Eclipse: Jump In"),
"jump out [<n>]": R(Key("c-f, a-o")+Paste(r"[\)\] \}\>]")+Function(ec_con.regex_on)+ \
Key("enter:%(n)d/5, escape, right") , rdescript="Eclipse: Jump Out"),
"jump back [<n>]": R(Key("c-f/5, a-b")+Paste(r"[\)\]\}\>]")+Function(ec_con.regex_on)+ \
Key("enter:%(n)d/5, escape, left") , rdescript="Eclipse: Jump Back"),
"[go to] line <n>": R(Key("c-l") + Pause("50") + Text("%(n)d") + Key("enter")+ Pause("50")+
Mimic(extra="mim"), rdescript="Eclipse: Go To Line"),
"shackle <n> [<back>]": R(Key("c-l")+Key("right, cs-left")+ \
Function(ec_con.lines_relative), rdescript="Eclipse: Select Relative Lines"),

}
extras = [
Dictation("text"),
IntegerRefST("n", 1, 1000),
Boolean("back"),
]
defaults = {"n": 1}
defaults = {"n": 1, "back": False}
#---------------------------------------------------------------------------

context = AppContext(executable="javaw", title="Eclipse") | AppContext(executable="eclipse", title="Eclipse") | AppContext(executable="AptanaStudio3")
Expand Down
4 changes: 3 additions & 1 deletion caster/apps/flashdevelop.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from dragonfly import (Grammar, AppContext, MappingRule,
Dictation, Key, Text, Repeat, Pause)

from caster.lib import settings
from caster.lib import control
from caster.lib import settings
from caster.lib.ccr.core.nav import Navigation
from caster.lib.dfplus.additions import IntegerRefST
from caster.lib.dfplus.merge.mergerule import MergeRule
from caster.lib.dfplus.state.short import R
Expand Down Expand Up @@ -54,6 +55,7 @@ class CommandRule(MappingRule):

class FlashDevelopCCR(MergeRule):
pronunciation = "flash develop"
mwith = [Navigation().get_name()]

mapping = {
"[go to] line <n>": R(Key("c-g") + Pause("50") + Text("%(n)d") + Key("enter"),
Expand Down
44 changes: 39 additions & 5 deletions caster/lib/dfplus/merge/ccrmerger.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from caster.lib import utilities, settings
from caster.lib.dfplus.merge.mergerule import MergeRule


class Inf(object):
TYPE = "type"
GLOBAL = 0
Expand All @@ -23,13 +22,36 @@ class Inf(object):


class MergePair(object):
def __init__(self, time, type, rule1, rule2, check_compatibility):
def __init__(self, time, type, rule1, rule2, check_compatibility, extras=None):
self.time = time
self.type = type
self.rule1 = rule1
self.rule2 = rule2
self.changed = False # presently unused
self.check_compatibility = check_compatibility
self.extras = extras

'''Standard merge filter: app_merge'''
def app_merge(mp):
'''forces app rules to define which parts of the base rule they will accept'''
if mp.type == Inf.APP:
base = mp.rule1 #base copy, actually
if base is None:
return
app = mp.rule2
mw = app.get_merge_with()
specs_per_rulename = mp.extras

'''flatten acceptable specs into a list'''
acceptable_specs = []
for rulename in specs_per_rulename:
if rulename in mw:
acceptable_specs.extend(specs_per_rulename[rulename])

'''remove anything the app rule hasn't defined as mergeable'''
for spec in base.mapping_actual().keys():
if not spec in acceptable_specs:
del base.mapping_actual()[spec]

class CCRMerger(object):
CORE = ["alphabet", "navigation", "numbers", "punctuation"]
Expand All @@ -53,6 +75,7 @@ def __init__(self, use_real_config=True):
self.use_real_config = use_real_config
self.load_config()
self.update_config() # this call prepares the config to receive new modules
self.add_filter(app_merge)

'''config file stuff'''
def save_config(self):
Expand Down Expand Up @@ -99,6 +122,7 @@ def add_global_rule(self, rule):
def add_app_rule(self, rule, context=None):
if context is not None and rule.get_context() is None: rule.set_context(context)
assert rule.get_context() is not None, "app rules must have contexts, "+rule.get_name()+" has no context"
assert rule.get_merge_with() is not None, "app rules must define mwith, "+rule.get_name()+" has no mwith"
self._add_to(rule, self._app_rules)
def add_selfmodrule(self, rule):
assert hasattr(rule, "set_merger"), "only SelfModifyingRules may be added by add_selfmodrule()"
Expand Down Expand Up @@ -245,10 +269,11 @@ def merge(self, time, name=None, enable=True, save=False):
'''have base, make copies, merge in apps'''
active_apps = []
for rule in self._app_rules.values():
base_copy = base.copy() if base is not None else base # make a copy b/c commands will get stripped out
context = rule.get_context()
mp = MergePair(time, Inf.APP, base, rule.copy(), False)
mp = MergePair(time, Inf.APP, base_copy, rule.copy(), False, CCRMerger.specs_per_rulename(self._global_rules))
self._run_filters(mp)
rule = self._compatibility_merge(mp, base, mp.rule2) # mp.rule2 because named_rule got copied
rule = self._compatibility_merge(mp, base_copy, mp.rule2) # mp.rule2 because named_rule got copied
rule.set_context(context)
active_apps.append(rule)

Expand Down Expand Up @@ -292,7 +317,16 @@ def merge(self, time, name=None, enable=True, save=False):
for rule_name in self._self_modifying_rules:
self._config[CCRMerger._SELFMOD][rule_name] = rule_name in active_selfmod_names
self.save_config()


@staticmethod
def specs_per_rulename(d):
result = {}
for rulename in d.keys():
rule = d[rulename]
specs = rule.mapping_actual().keys()
result[rulename] = specs
return result

def _run_filters(self, merge_pair):
for filter_fn in self._filters:
try: filter_fn(merge_pair)
Expand Down
11 changes: 8 additions & 3 deletions caster/lib/dfplus/merge/mergerule.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,16 @@ def get_merge_name(): # returns unique str(int) for procedural rule names
mwith = None

def __init__(self, name=None, mapping=None, extras=None, defaults=None,
exported=None, ID=None, composite=None, compatible=None, mcontext=None):
exported=None, ID=None, composite=None, compatible=None, mcontext=None, mwith=None):

self.ID = ID if ID is not None else MergeRule._get_next_id()
self.compatible = {} if compatible is None else compatible
'''composite is the IDs of the rules which this MergeRule is composed of: '''
self.composite = composite if composite is not None else set([self.ID])
self._mcontext = self.__class__.mcontext
if self._mcontext is None: self._mcontext = mcontext
if self._mcontext is None: self._mcontext = mcontext
self._mwith = self.__class__.mwith
if self._mwith is None: self._mwith = mwith

if mapping is not None:
mapping["display available commands"] = Function(lambda: self._display_available_commands())
Expand Down Expand Up @@ -110,7 +112,7 @@ def get_name(self):
return self.name if self.pronunciation is None else self.pronunciation
def copy(self):
return MergeRule(self.name, self._mapping.copy(), self._extras.values(), self._defaults.copy(),
self._exported, self.ID, self.composite, self.compatible, self._mcontext)
self._exported, self.ID, self.composite, self.compatible, self._mcontext, self._mwith)
def compatibility_check(self, other):
if other.ID in self.compatible:
return self.compatible[other.ID] # lazily
Expand All @@ -129,6 +131,9 @@ def get_context(self):
return self._mcontext
def set_context(self, context):
self._mcontext = context

def get_merge_with(self):
return self._mwith

def _display_available_commands(self):
for spec in self.mapping_actual().keys():
Expand Down

0 comments on commit 918cc27

Please sign in to comment.