def load_sleep_wake_grammar(initial_awake): sleep_grammar = Grammar("sleep") def sleep(force=False): global sleeping if not sleeping or force: sleeping = True sleep_grammar.set_exclusiveness(True) notify('sleep') def wake(force=False): global sleeping if sleeping or force: sleeping = False sleep_grammar.set_exclusiveness(False) notify('wake') class SleepRule(MappingRule): mapping = { "start listening": Function(wake) + Function(lambda: get_engine().start_saving_adaptation_state()), "stop listening": Function(lambda: get_engine().stop_saving_adaptation_state()) + Function(sleep), "halt listening": Function(lambda: get_engine().stop_saving_adaptation_state()) + Function(sleep), } sleep_grammar.add_rule(SleepRule()) sleep_noise_rule = MappingRule( name = "sleep_noise_rule", mapping = { "<text>": Function(lambda text: False and print(text)) }, extras = [ Dictation("text") ], context = FuncContext(lambda: sleeping), ) sleep_grammar.add_rule(sleep_noise_rule) sleep_grammar.load() if initial_awake: wake(force=True) else: sleep(force=True)
class GlobalRule(MappingRule): mapping = { '[<text>] go to sleep': Function(go_to_sleep), 'mouse': Key('f3,f4/350,f4'), "touch": Mouse("left"), "touch two": Mouse("left:2"), 'touch are': Mouse('right'), "touch mid": Mouse("middle"), "[<n>] scroll down": (Mouse("wheeldown") + Pause('5')) * Repeat(extra='n') * 2, "[<n>] scroll up": (Mouse("wheelup") + Pause('5')) * Repeat(extra='n') * 2, "[<n>] scroll right": (Mouse("wheelright") + Pause('5')) * Repeat(extra='n') * 2, "[<n>] scroll left": (Mouse("wheelleft") + Pause('5')) * Repeat(extra='n') * 2, "drag": Mouse("left:down"), "drop": Mouse("left:up"), "[<n>] alt tab": Key("alt:down,tab/50:%(n)d/50,alt:up"), "alt tab show": Key("alt:down,tab/10,s-tab"), 'reload natlink': Function(reload_natlink), } extras = [ IntegerRef('n', 1, 101, default=1), Dictation('text'), ]
class NavigationRule(MappingRule): mapping = { "move up [<n>]": Key("cs-tab:%(n)d"), "move down [<n>]": Key("c-tab:%(n)d"), "close tab": Key("c-w"), "(join room | private message) <room>": Key("c-j/25") + Text("%(room)s") + Key("enter"), "search [room] history": Key("c-f"), } extras = [ IntegerRef("n", 1, 10), Dictation("room"), ] defaults = { "n": 1, }
class CommandRule(MappingRule): mapping = { "dragonfly add buffer": Exec("dragonfly-add-buffer"), "dragonfly add word": Exec("dragonfly-add-word"), "dragonfly blacklist word": Exec("dragonfly-blacklist-word"), "Foreclosure next": Exec("4clojure-next-question"), "Foreclosure previous": Exec("4clojure-previous-question"), "Foreclosure check": Exec("4clojure-check-answers"), "confirm": Text("yes") + Key("enter"), "deny": Text("no") + Key("enter"), "relative line numbers": Exec("linum-relative-toggle"), "revert buffer": Exec("revert-buffer"), "exit out of Emacs": Key("c-x, c-c"), } extras = [ IntegerRef("n", 1, 20), IntegerRef("line", 1, 10000), Dictation("text"), ] defaults = { "n": 1, }
class CommandRule(MappingRule): mapping = { "zoom in [<n>]": Key("c-equals:%(n)d"), "zoom out [<n>]": Key("c-hyphen:%(n)d"), "zoom [one] hundred": Key("c-1"), "zoom [whole | full] page": Key("c-2"), "zoom [page] width": Key("c-3"), "find <text>": Key("c-f") + Text("%(text)s") + Key("f3"), "find next": Key("f3"), "[go to] page <int>": Key("cs-n") + Text("%(int)d\n"), "print file": Key("c-p"), "print setup": Key("a-f, r"), } extras = [ IntegerRef("n", 1, 10), IntegerRef("int", 1, 10000), Dictation("text"), ] defaults = { "n": 1, }
class BringRule(SelfModifyingRule): pronunciation = "bring me" def refresh(self, *args): #logger.debug('Bring me refresh') self.extras[0] = Choice('desired_item', _rebuild_items()) self.reset(self.mapping) mapping = { "bring me <desired_item>": R(Function(bring_it), rdescript="Launch preconfigured program, folder or website"), "<launch> to bring me as <key>": R(Function(bring_add, extra={"launch", "key"}), rdescript="Add program, folder or website to the bring me list"), "remove <key> from bring me": R(Function(bring_remove, extra="key"), rdescript="Remove program, folder or website from the bring me list" ), "restore bring me defaults": R(Function(bring_restore), rdescript="Delete bring me list and put defaults in its place"), } extras = [ Choice("desired_item", _rebuild_items()), Choice( "launch", { "[current] program": "program", "website": "website", "folder": "folder", "file": "file", }), Dictation("key"), ] defaults = {'desired_item': ('', ""), 'launch': 'program', 'key': ''}
class QuickSettingsRule(MappingRule): mapping = { "win diff": Key("colon") + Text("windo diffthis"), "win diff off": Key("colon") + Text("windo diffoff"), "win scroll": Key("colon") + Text("windo setl scrollbind"), "win scroll off": Key("colon") + Text("windo setl noscrollbind"), "fix exec": Key("q, colon"), "fix search": Key("q, slash"), "show registers": Text(":registers") + Key("enter"), "show dir": Text(":pwd") + Key("enter"), "show history": Text(":history") + Key("enter"), "show buffers": Text(":buffers") + Key("enter"), "show version": Text(":version") + Key("enter"), "show help": Text(":help ") + Key("enter"), # Preview windows: "show quick fix": Text(":copen") + Key("enter"), "hide quick fix": Text(":cclose") + Key("enter"), "show lock": Text(":lopen") + Key("enter"), "hide lock": Text(":lclose") + Key("enter"), # GUI windows: "system search": Text(":promptfind") + Key("enter"), "system sub": Text(":promptrepl") + Key("enter"), "show help [<text>]": Key("colon, h, space") + Text("%(text)s"), } extras = [ Dictation('text') ] defaults = { 'text': '' }
class MSVCRule(MergeRule): pronunciation = "Microsoft visual studio" mapping = { "cursor prior": R(Key("c-minus"), rdescript="MSVC: Cursor Prior"), "cursor next": R(Key("cs-minus"), rdescript="MSVC: Cursor Next"), "toggle fullscreen": R(Key("sa-enter"), rdescript="MSVC: Toggle Fullscreen"), "resolve": R(Key("c-dot"), rdescript="MSVC: Resolve"), "jump to source": R(Key("f12"), rdescript="MSVC: Jump To Source"), "snippet": R(Key("tab"), rdescript="MSVC: Snippet"), "step over [<n>]": R(Key("f10/50") * Repeat(extra="n"), rdescript="MSVC: Step Over"), "step into": R(Key("f11"), rdescript="MSVC: Step Into"), "step out [of]": R(Key("s-f11"), rdescript="MSVC: Step Out"), "resume": R(Key("f8"), rdescript="MSVC: Resume"), "build [last]": R(Key("ca-f7"), rdescript="MSVC: Build"), "debug [last]": R(Key("f5"), rdescript="MSVC: Debug"), "comment out": R(Key("c-k/50, c-c"), rdescript="MSVC: Comment Out"), "on comment out": R(Key("c-k/50, c-u"), rdescript="MSVC: Uncomment Out"), "set bookmark": R(Key("c-k, c-k"), rdescript="MSVC: Set Bookmark"), "next bookmark": R(Key("c-k, c-n"), rdescript="MSVC: Next Bookmark"), "breakpoint": R(Key("f9"), rdescript="MSVC: Breakpoint"), "format code": R(Key("cs-f"), rdescript="MSVC: Format Code"), "(do imports | import all)": R(Key("cs-o"), rdescript="MSVC: Do Imports"), "comment line": R(Key("c-slash"), rdescript="MSVC: Comment Line"), "go to line": R(Key("c-g"), rdescript="MSVC: Go To Line"), } extras = [ Dictation("text"), IntegerRefST("n", 1, 1000), ] defaults = {"n": 1}
class GoogleDocsMappings(MappingRule): mapping = { # "new task": Key("tab:down/25, n/25, tab:up"), # "save task": Key("c-s"), # "(complete | done) task": Key("tab:down/25, m/25, tab:up"), "Add bullets": Key("cs-8"), "heading one": Key("ca-1"), "heading two": Key("ca-2"), "heading three": Key("ca-3"), "heading four": Key("ca-4"), "heading five": Key("ca-5"), "heading six": Key("ca-6"), } extras = [ Dictation("text"), Integer("n", 1, 50), ] defaults = { "n": 1, }
class SlackMapping(MappingRule): mapping = { # "new (thing | tab)": Key("c-t"), # "new window": Key("c-n"), # "reopen tab": Key("cs-t"), # "(next | nex) (tab | ab) [<n>]": Key("c-pgdown:%(n)d"), # "(previous | preev) tab [<n>]": Key("c-pgup:%(n)d"), # "show tab <tab>": Key("c-%(tab)d"), "switch <text>": Key("c-k/25") + Text("%(text)s") + Key("enter"), "show switch": Key("c-k"), "left (pain | pane)": Key("f6/10:3"), # "open <w> [<x>] [<y>] [<z>]": Key("cs-space/" + click_by_voice_delay) + Function(printNumber) + Key("enter"), # click by voice # "open focus <w> [<x>] [<y>] [<z>]": Key("cs-space/" + click_by_voice_delay) + Function(printNumberFocus) + Key("enter"), # click by voice } extras = [ Integer("n", 1, 50), Integer("number", 1, 9999), Dictation("text"), ] defaults = { "n": 1, }
class EclipseCCR(MergeRule): pronunciation = "eclipse jump" 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)), "jump in [<n>]": R( Key("c-f, a-o") + Paste(r"[\(\[\{\<]") + Function(ec_con.regex_on) + Key("enter:%(n)d/5, escape, right")), "jump out [<n>]": R( Key("c-f, a-o") + Paste(r"[\)\] \}\>]") + Function(ec_con.regex_on) + Key("enter:%(n)d/5, escape, right")), "jump back [<n>]": R( Key("c-f/5, a-b") + Paste(r"[\)\]\}\>]") + Function(ec_con.regex_on) + Key("enter:%(n)d/5, escape, left")), "[go to] line <n>": R( Key("c-l") + Pause("50") + Text("%(n)d") + Key("enter") + Pause("50")), "shackle <n> [<back>]": R( Key("c-l") + Key("right, cs-left") + Function(ec_con.lines_relative)), } extras = [ Dictation("text"), IntegerRefST("n", 1, 1000), Boolean("back"), ] defaults = {"n": 1, "back": False}
class DevelopmentHelp(MappingRule): mapping = { # caster development tools "(show | open) <url> documentation": Function(launch_url), "open natlink folder": R(BringApp("C:/Windows/explorer.exe", settings.SETTINGS["paths"]["BASE_PATH"].replace("/", "\\")), rdescript="Open Natlink Folder"), "refresh debug file": Function(devgen.refresh), "Agrippa <filetype> <path>": Function(grep_this), "run rule complexity test": Function(lambda: run_tests()), "run unit tests": Function(testrunner.run_tests), "run remote debugger": Function(run_remote_debugger), } extras = [ Dictation("text"), Choice("path", { "natlink": "c:/natlink/natlink", "sea": "C:/", }), Choice("filetype", { "java": "*.java", "python": "*.py", }), Choice( "url", { "caster": "https://caster.readthedocs.io/en/latest/", "dragonfly": "https://dragonfly2.readthedocs.io/en/latest/", }), ] defaults = {"text": ""}
def _deserialize(self): """ This _deserialize creates mapping which uses the user-made extras. """ self._initialize() self._smr_mapping = { "bring me <program>": R(Function(self._bring_program)), "bring me <website>": R(Function(self._bring_website)), "bring me <folder> [in <app>]": R(Function(self._bring_folder)), "bring me <file>": R(Function(self._bring_file)), "refresh bring me": R(Function(self._load_and_refresh)), "<launch_type> to bring me as <key>": R(Function(self._bring_add)), "to bring me as <key>": R(Function(self._bring_add_auto)), "remove <key> from bring me": R(Function(self._bring_remove)), "restore bring me defaults": R(Function(self._bring_reset_defaults)), } self._smr_extras = [ Choice( "launch_type", { "[current] program": "program", "website": "website", "folder": "folder", "file": "file", }), Choice("app", { "terminal": "terminal", "explorer": "explorer", }), # Sanitize free dictation for spec, words and apostrophes only. Dictation("key").apply( lambda key: re.sub(r'[^A-Za-z\'\s]+', '', key).lower()), ] self._smr_extras.extend(self._rebuild_items()) self._smr_defaults = {"app": None}
class IERule(MergeRule): pronunciation = "explorer" mapping = { "address bar": R(Key("a-d"), rdescript="Explorer: Address Bar"), "new folder": R(Key("cs-n"), rdescript="Explorer: New Folder"), "new file": R(Key("a-f, w, t"), rdescript="Explorer: New File"), "(show | file | folder) properties": R(Key("a-enter"), rdescript="Explorer: Properties Dialog"), "get up": R(Key("a-up"), rdescript="Explorer: Navigate up"), "get back": R(Key("a-left"), rdescript="Explorer: Navigate back"), "get forward": R(Key("a-right"), rdescript="Explorer: Navigate forward"), } extras = [ Dictation("text"), IntegerRefST("n", 1, 1000), ] defaults = {"n": 1}
class InsertModeStartRule(MappingRule): exported = True mapping = { "change <motion> [<text>]": Key("c") + execute_rule('motion') + Text('%(text)s'), "change <object> [<text>]": Key("c") + execute_rule('object') + Text('%(text)s'), "change line [<text>]": Key("c,c") + Text('%(text)s'), "insert [<text>]": Key("i") + Text('%(text)s'), "prepend [<text>]": Key("I") + Text('%(text)s'), "after [<text>]": Key("a") + Text('%(text)s'), "append [<text>]": Key("A") + Text('%(text)s'), "oh [<text>]": Key("o") + Text('%(text)s'), "bo [<text>]": Key("O") + Text('%(text)s'), "insert last [<text>]": Key("g, i") + Text('%(text)s'), } extras = [ RuleRef(rule = motion.MotionRule(name = "insert_motion"), name = "motion"), RuleRef(rule = object.ObjectRule(name = "insert_object"), name = "object"), Dictation("text"), ] defaults = { "text": "", }
class IdentifierInsertion(CompoundRule): spec = ('[upper | natural] ( proper | camel | rel-path | abs-path | score | sentence |' 'scope-resolve | jumble | dotword | dashword | natword | snakeword | brooding-narrative) [<dictation>]') extras = [Dictation(name='dictation')] def value(self, node): words = node.words() uppercase = words[0] == 'upper' lowercase = words[0] != 'natural' if lowercase: words = [word.lower() for word in words] if uppercase: words = [word.upper() for word in words] words = [word.split('\\', 1)[0].replace('-', '') for word in words] if words[0].lower() in ('upper', 'natural'): del words[0] function = globals()['format_%s' % words[0].lower()] formatted = function(words[1:]) return Text(formatted)
class GlobalChromeMappings(MappingRule): mapping = { 'close tab': Key('c-w'), 'new tab': Key('c-t'), 'reopen tab': Key('cs-t'), 'next': Key('c-pgdown'), 'previous': Key('c-pgup'), 'tab <tab>': Key('c-%(tab)d'), 'first tab': Key('c-1'), 'last tab': Key('c-9'), 'back': Key('a-left'), 'forward': Key('a-right'), 'address': Key('c-l'), 'reload page': Key('f5'), 'link': Key('f'), # vimium '[go to] label <number>': Text('%(number)d'), # vimium 'find': Key('c-f'), 'search <text>': Key('c-l') + Text('%(text)s\r'), } extras = [ Integer('tab', 1, 30), Integer('number', 1, 9999), Dictation("text"), ]
def __init__(self, config_path, name=None): """ SelfModifyingRule is a kind of rule which gets its command set changed on-the-fly based on some kind of user interaction. Child classes must implement their own version of the _refresh and _deserialize methods. :param name: str """ self._reload_shim = None self._hooks_runner = None default_smr_mapping = {"spec which gets replaced": NullAction()} self._smr_mapping = default_smr_mapping # extras and defaults may not get replaced: self._smr_extras = [ShortIntegerRef("n", 1, 50), Dictation("s")] self._smr_defaults = {"n": 1, "s": ""} self._config = SelfModStateSavingConfig(config_path) self._config.load() self._deserialize() MergeRule.__init__(self, name, self._smr_mapping, self._smr_extras, self._smr_defaults)
class NPPRule(MergeRule): pronunciation = "notepad plus plus" mapping = { "stylize <n2>": R(Mouse("right") + Key("down:6/5, right") + (Key("down") * Repeat(extra="n2")) + Key("enter"), rdescript="Notepad++: Stylize"), "remove style": R(Mouse("right") + Key("down:6/5, right/5, down:5/5, enter"), rdescript="Notepad++: Remove Style"), "preview in browser": R(Key("cas-r"), rdescript="Notepad++: Preview In Browser"), # requires function list plug-in: "function list": R(Key("cas-l"), rdescript="Notepad++: Function List"), } extras = [ Dictation("text"), IntegerRefST("n", 1, 100), IntegerRefST("n2", 1, 10), ] defaults = {"n": 1}
class MainRule(MappingRule): mapping = { "run dispel": R(Function(ALARM.start), rdescript="Turn On Ergonomic Alarm"), "kill dispel": R(Function(ALARM.stop), rdescript="Turn Off Ergonomic Alarm"), "resume dispel": R(Function(ALARM.resume), rdescript="Resume Ergonomic Alarm"), # "delay dispel": R(Function(ALARM.delay), rdescript="Delay Ergonomic Alarm"), "reset dispel": R(Function(ALARM.reset), rdescript="Reset Ergonomic Alarm"), } extras = [ IntegerRef("n", 1, 500), IntegerRef("n2", 1, 500), Dictation("text"), ] defaults = { "n": 1, "n2": 1, "text": "", }
class Navigation(MergeRule): pronunciation = "navigation" mapping = { # "periodic" repeats whatever comes next at 1-second intervals until "terminate" # or "escape" (or your SymbolSpecs.CANCEL) is spoken or 100 tries occur "periodic": ContextSeeker(forward=[ L( S(["cancel"], lambda: None), S(["*"], lambda fnparams: UntilCancelled( Mimic(*filter(lambda s: s != "periodic", fnparams)), 1). execute(), use_spoken=True)) ]), # VoiceCoder-inspired -- these should be done at the IDE level "fill <target>": R(Key("escape, escape, end"), show=False) + AsynchronousAction( [L(S(["cancel"], Function(context.fill_within_line)))], time_in_seconds=0.2, repetitions=50), "jump in": AsynchronousAction( [L(S(["cancel"], context.nav, ["right", "(~[~{~<"]))], time_in_seconds=0.1, repetitions=50), "jump out": AsynchronousAction( [L(S(["cancel"], context.nav, ["right", ")~]~}~>"]))], time_in_seconds=0.1, repetitions=50), "jump back": AsynchronousAction( [L(S(["cancel"], context.nav, ["left", "(~[~{~<"]))], time_in_seconds=0.1, repetitions=50), "jump back in": AsynchronousAction( [L(S(["cancel"], context.nav, ["left", "(~[~{~<"]))], finisher=Key("right"), time_in_seconds=0.1, repetitions=50), # keyboard shortcuts 'save': R(Key("c-s"), rspec="save"), "shift click": R(Key("shift:down") + Mouse("left") + Key("shift:up")), "stoosh [<nnavi500>]": R(Function(navigation.stoosh_keep_clipboard), rspec="stoosh"), "cut [<nnavi500>]": R(Function(navigation.cut_keep_clipboard), rspec="cut"), "spark [<nnavi500>] [(<capitalization> <spacing> | <capitalization> | <spacing>) [(bow|bowel)]]": R(Function(navigation.drop_keep_clipboard), rspec="spark"), "splat [<splatdir>] [<nnavi10>]": R(Key("c-%(splatdir)s"), rspec="splat") * Repeat(extra="nnavi10"), SymbolSpecs.CANCEL: R(Key("escape"), rspec="cancel"), "shackle": R(Key("home/5, s-end"), rspec="shackle"), "(tell | tau) <semi>": R(Function(navigation.next_line), rspec="tell dock"), "(hark | heart) <semi>": R(Function(navigation.previous_line), rspec="hark dock"), "duple [<nnavi50>]": R(Function(navigation.duple_keep_clipboard), rspec="duple"), "Kraken": R(Key("c-space"), rspec="Kraken"), "undo [<nnavi10>]": R(Key("c-z")) * Repeat(extra="nnavi10"), "redo [<nnavi10>]": R( ContextAction( default=Key("c-y") * Repeat(extra="nnavi10"), actions=[ (AppContext(executable=["rstudio", "foxitreader"]), Key("cs-z") * Repeat(extra="nnavi10")), ])), # text formatting "set [<big>] format (<capitalization> <spacing> | <capitalization> | <spacing>) [(bow|bowel)]": R(Function(textformat.set_text_format)), "clear castervoice [<big>] formatting": R(Function(textformat.clear_text_format)), "peek [<big>] format": R(Function(textformat.peek_text_format)), "(<capitalization> <spacing> | <capitalization> | <spacing>) [(bow|bowel)] <textnv> [brunt]": R(Function(textformat.master_format_text)), "[<big>] format <textnv>": R(Function(textformat.prior_text_format)), "<word_limit> [<big>] format <textnv>": R(Function(textformat.partial_format_text)), "hug <enclosure>": R(Function(text_utils.enclose_selected)), "dredge [<nnavi10>]": R(Key("alt:down, tab/20:%(nnavi10)d, alt:up"), rdescript="Core: switch to most recent Windows"), # Ccr Mouse Commands "kick [<nnavi3>]": R(Function(navigation.left_click)) * Repeat(extra="nnavi3"), "psychic": R(Function(navigation.right_click)), "(kick double|double kick)": R(Function(navigation.left_click) * Repeat(2)), "squat": R(Function(navigation.left_down)), "bench": R(Function(navigation.left_up)), # special keystroke commands "(lease wally | latch) [<nnavi10>]": R(Key("home:%(nnavi10)s")), "(ross wally | ratch) [<nnavi10>]": R(Key("end:%(nnavi10)s")), "sauce wally [<nnavi10>]": R(Key("c-home:%(nnavi10)s")), "dunce wally [<nnavi10>]": R(Key("c-end:%(nnavi10)s")), "bird [<nnavi500>]": R(Key("c-left:%(nnavi500)s")), "firch [<nnavi500>]": R(Key("c-right:%(nnavi500)s")), "brick [<nnavi500>]": R(Key("s-left:%(nnavi500)s")), "frick [<nnavi500>]": R(Key("s-right:%(nnavi500)s")), "blitch [<nnavi500>]": R(Key("cs-left:%(nnavi500)s")), "flitch [<nnavi500>]": R(Key("cs-right:%(nnavi500)s")), "<button_dictionary_500_no_prefix_no_modifier> [<nnavi500>]": R(Key("%(button_dictionary_500_no_prefix_no_modifier)s") * Repeat(extra='nnavi500'), rdescript= "press buttons from button_dictionary_500_no_prefix_no_modifier"), "<modifier> <button_dictionary_500_modifier> [<nnavi500>]": R(Key("%(modifier)s-%(button_dictionary_500_modifier)s") * Repeat(extra='nnavi500'), rdescript= "press modifiers plus buttons from button_dictionary_500_modifier"), "<modifier> <button_dictionary_1_modifier>": R(Key("%(modifier)s-%(button_dictionary_1_modifier)s"), rdescript= "press modifiers plus buttons from button_dictionary_1_modifier"), } tell_commands_dict = { "dock": ";", "doc": ";", "sink": "", "com": ",", "deck": ":" } tell_commands_dict.update(_tpd) button_dictionary_500_no_prefix_no_modifier = { "tabby": "tab", "clear": "backspace", "deli": "del", "shock": "enter", "lease": "left", "ross": "right", "sauce": "up", "dunce": "down", "page (down | dunce)": "pgdown", "page (up | sauce)": "pgup", } button_dictionary_500_modifier = { key: value for key, value in keyboard_support.button_dictionary_1.items() if value in [ "backspace", "del", "enter", "left", "right", "up", "down", "pgdown", "pgup" ] } button_dictionary_1_modifier = { key: value for key, value in keyboard_support.button_dictionary_1.items() if value in ["home", "end"] } extras = [ ShortIntegerRef("nnavi10", 1, 11), ShortIntegerRef("nnavi3", 1, 4), ShortIntegerRef("nnavi50", 1, 50), ShortIntegerRef("nnavi500", 1, 500), Dictation("textnv"), Choice("enclosure", _dtpd), Choice( "capitalization", { "yell": 1, "tie": 2, "gerrish": 3, "sing": 4, "laws": 5, "say": 6, "cop": 7, "slip": 8, }), Choice( "spacing", { "gum": 1, "gun": 1, "spine": 2, "snake": 3, "pebble": 4, "incline": 5, "dissent": 6, "descent": 6, }), Choice("semi", tell_commands_dict), Choice("word_limit", { "single": 1, "double": 2, "triple": 3, "Quadra": 4 }), navigation_support.TARGET_CHOICE, Choice("extreme", { "Wally": "way", }), Choice("big", { "big": True, }), Choice("splatdir", { "lease": "backspace", "ross": "delete", }), keyboard_support.modifier_choice_object, Choice("button_dictionary_500_no_prefix_no_modifier", button_dictionary_500_no_prefix_no_modifier), Choice("button_dictionary_500_modifier", button_dictionary_500_modifier), Choice("button_dictionary_1_modifier", button_dictionary_1_modifier) ] defaults = { "nnavi500": 1, "nnavi50": 1, "nnavi10": 1, "nnavi3": 1, "textnv": "", "capitalization": 0, "spacing": 0, "extreme": None, "big": False, "splatdir": "backspace", }
class NavigationNon(MappingRule): mapping = { "<direction> <time_in_seconds>": AsynchronousAction( [L(S(["cancel"], Key("%(direction)s"), consume=False))], repetitions=1000, blocking=False), "erase multi clipboard": R(Function(navigation.erase_multi_clipboard, nexus=_NEXUS), rdescript="Erase Multi Clipboard"), "find": R(Key("c-f"), rdescript="Find"), "find next [<n>]": R(Key("f3"), rdescript="Find Next") * Repeat(extra="n"), "find prior [<n>]": R(Key("s-f3"), rdescript="Find Prior") * Repeat(extra="n"), "find everywhere": R(Key("cs-f"), rdescript="Find Everywhere"), "replace": R(Key("c-h"), rdescript="Replace"), "(F to | F2)": R(Key("f2"), rdescript="Key: F2"), "(F six | F6)": R(Key("f6"), rdescript="Key: F6"), "(F nine | F9)": R(Key("f9"), rdescript="Key: F9"), "[show] context menu": R(Key("s-f10"), rdescript="Context Menu"), 'kick': R(Function(navigation.kick, nexus=_NEXUS), rdescript="Mouse: Left Click"), 'kick mid': R(Function(navigation.kick_middle, nexus=_NEXUS), rdescript="Mouse: Middle Click"), 'psychic': R(Function(navigation.kick_right, nexus=_NEXUS), rdescript="Mouse: Right Click"), '(kick double|double kick)': R(Function(navigation.kick, nexus=_NEXUS) * Repeat(2), rdescript="Mouse: Double Click"), "shift right click": R(Key("shift:down") + Mouse("right") + Key("shift:up"), rdescript="Mouse: Shift + Right Click"), "curse <direction> [<direction2>] [<nnavi500>] [<dokick>]": R(Function(navigation.curse), rdescript="Curse"), "scree <direction> [<nnavi500>]": R(Function(navigation.wheel_scroll), rdescript="Wheel Scroll"), "colic": R(Key("control:down") + Mouse("left") + Key("control:up"), rdescript="Mouse: Ctrl + Left Click"), "garb [<nnavi500>]": R(Mouse("left") + Mouse("left") + Key("c-c") + Function(navigation.clipboard_to_file, nexus=_NEXUS), rdescript="Highlight @ Mouse + Copy"), "drop [<nnavi500>]": R(Mouse("left") + Mouse("left") + Function(navigation.drop, nexus=_NEXUS), rdescript="Highlight @ Mouse + Paste"), "sure stoosh": R(Key("c-c"), rdescript="Simple Copy"), "sure cut": R(Key("c-x"), rdescript="Simple Cut"), "sure spark": R(Key("c-v"), rdescript="Simple Paste"), "undo [<n>]": R(Key("c-z"), rdescript="Undo") * Repeat(extra="n"), "redo [<n>]": R(Key("c-y"), rdescript="Redo") * Repeat(extra="n"), "refresh": R(Key("c-r"), rdescript="Refresh"), "maxiwin": R(Key("w-up"), rdescript="Maximize Window"), "move window": R(Key("a-space, r, a-space, m"), rdescript="Move Window"), "window (left | lease) [<n>]": R(Key("w-left"), rdescript="Window Left") * Repeat(extra="n"), "window (right | ross) [<n>]": R(Key("w-right"), rdescript="Window Right") * Repeat(extra="n"), "monitor (left | lease) [<n>]": R(Key("sw-left"), rdescript="Monitor Left") * Repeat(extra="n"), "monitor (right | ross) [<n>]": R(Key("sw-right"), rdescript="Monitor Right") * Repeat(extra="n"), "(next | prior) window": R(Key("ca-tab, enter"), rdescript="Next Window"), "switch (window | windows)": R(Key("ca-tab"), rdescript="Switch Window") * Repeat(extra="n"), "next tab [<n>]": R(Key("c-pgdown"), rdescript="Next Tab") * Repeat(extra="n"), "prior tab [<n>]": R(Key("c-pgup"), rdescript="Previous Tab") * Repeat(extra="n"), "close tab [<n>]": R(Key("c-w/20"), rdescript="Close Tab") * Repeat(extra="n"), "elite translation <text>": R(Function(alphanumeric.elite_text), rdescript="1337 Text"), } extras = [ Dictation("text"), Dictation("mim"), IntegerRefST("n", 1, 50), IntegerRefST("nnavi500", 1, 500), Choice( "time_in_seconds", { "super slow": 5, "slow": 2, "normal": 0.6, "fast": 0.1, "superfast": 0.05 }), navigation.get_direction_choice("direction"), navigation.get_direction_choice("direction2"), navigation.TARGET_CHOICE, Choice("dokick", { "kick": 1, "psychic": 2 }), Choice("wm", { "ex": 1, "tie": 2 }), ] defaults = { "n": 1, "mim": "", "nnavi500": 1, "direction2": "", "dokick": 0, "text": "", "wm": 2 }
def load_sleep_wake_grammar(initial_awake): sleep_grammar = Grammar("sleep") def sleep(force=False): get_engine().stop_saving_adaptation_state() global sleeping if not sleeping or force: sleeping = True sleep_grammar.set_exclusiveness(True) notify('sleep') def wake(force=False): get_engine().start_saving_adaptation_state() global sleeping if sleeping or force: sleeping = False sleep_grammar.set_exclusiveness(False) notify('wake') class SleepRule(MappingRule): mapping = { "go to sleep":Function(sleep), "bake up": Function(noop), "rake up":Function(noop), "shake up":Function(noop), "lake up":Function(noop), "nake up":Function(noop), "wake tup":Function(noop), "wake sup":Function(noop), "whey grub":Function(noop), "wake":Function(noop), "wake up":Function(wake), } sleep_grammar.add_rule(SleepRule()) sleep_noise_rule = MappingRule( name = "sleep_noise_rule", mapping = { "<text>": Function(lambda text: False and print("(asleep) " + text)) }, extras = [ Dictation("text") ], context = FuncContext(lambda: sleeping), ) sleep_grammar.add_rule(sleep_noise_rule) sleep_grammar.load() # def checkIniFile(): # global sleeping # global sleepOverride # voice = readIni('voice') # new_value = (voice=="off") # if new_value: # sleep() # else: # wake() # set_interval(checkIniFile,3) # watchingIniFile = True if initial_awake: wake(force=True) else: sleep(force=True)
class EmacsRule(MergeRule): pronunciation = "E max" mapping = { "open file": R(Key("c-x, c-f"), rdescript="Emacs: Open File"), "save file": R(Key("c-x, c-s"), rdescript="Emacs: Save File"), "save as": R(Key("c-x, c-w"), rdescript="Emacs: Save As"), "save all": R(Key("c-x, s"), rdescript="Emacs: Save All"), "revert to file": R(Key("c-x, c-v"), rdescript="Emacs: Revert To File"), "revert buffer": R(Key("a-x"), rdescript="Revert Buffer"), "close buffer": R(Key("c-x, c-c"), rdescript="Close Buffer"), "undo": R(Key("c-underscore"), rdescript="Emacs: Undo"), "begin selection": R(Key("c-space"), rdescript="Emacs: Begin Selection"), "cancel selection": R(Key("c-g"), rdescript="Emacs: Cancel Selection"), "cut selection": R(Key("c-w"), rdescript="Emacs: Cut Selection"), "paste": R(Key("c-y"), rdescript="Emacs: Paste"), "copy number <n>": R(Key("c-x, r, s, %(n)d"), rdescript="Emacs: Copy Number"), "paste number <n>": R(Key("c-x, r, i, %(n)d"), rdescript="Emacs: Paste Number"), # delete "forward delete": R(Key("c-delete"), rdescript="Emacs: Forward Delete"), "delete word": R(Key("a-delete"), rdescript="Emacs: Delete Word"), "forward delete word": R(Key("a-d"), rdescript="Emacs: Forward Delete Word"), "word forward": R(Key("a-f"), rdescript="Emacs: Word Forward"), "word backward": R(Key("a-b"), rdescript="Emacs: Word Backward"), "line forward": R(Key("c-a"), rdescript="Emacs: Line Forward"), "line backward": R(Key("c-e"), rdescript="Emacs: Line Backward"), "paragraph forward": R(Key("a-lbrace"), rdescript="Emacs: Paragraph Forward"), "paragraph backward": R(Key("a-rbrace"), rdescript="Emacs: Paragraph Backward"), "document forward": R(Key("a-langle"), rdescript="Emacs: Document Forward"), "document backward": R(Key("a-rangle"), rdescript="Emacs: Document Backward"), "C function forward": R(Key("ac-a"), rdescript="Emacs: C Function Forward"), "C function backward": R(Key("ac-e"), rdescript="Emacs: C Function Forward"), "incremental search": R(Key("c-s"), rdescript="Emacs: Incremental Search"), "incremental reverse": R(Key("c-r"), rdescript="Emacs: Incremental Reverse"), "interactive search": R(Key("a-percent"), rdescript="Emacs: Interactive Search"), "go to line <n>": R(Key("a-x, %(n)d"), rdescript="Emacs: Go To Line"), "prior bracket": R(Key("escape:down, c-b, escape:up"), rdescript="Emacs: Prior Bracket"), "next bracket": R(Key("escape:down, c-f, escape:up"), rdescript="Emacs: Next Bracket"), } extras = [ Dictation("text"), Dictation("mim"), IntegerRefST("n", 1, 1000), ] defaults = {"n": 1, "mim": ""}
class Navigation(MergeRule): non = NavigationNon pronunciation = CCRMerger.CORE[1] mapping = { # "periodic" repeats whatever comes next at 1-second intervals until "cancel" is spoken or 100 tries occur "periodic": ContextSeeker(forward=[L(S(["cancel"], lambda: None), \ S(["*"], \ lambda fnparams: UntilCancelled(Mimic(*filter(lambda s: s != "periodic", fnparams)), 1).execute(), \ use_spoken=True))]), # VoiceCoder-inspired -- these should be done at the IDE level "fill <target>": R(Key("escape, escape, end"), show=False) + AsynchronousAction([L(S(["cancel"], Function(context.fill_within_line, nexus=_NEXUS))) ], time_in_seconds=0.2, repetitions=50, rdescript="Fill" ), "jump in": AsynchronousAction([L(S(["cancel"], context.nav, ["right", "(~[~{~<"])) ], time_in_seconds=0.1, repetitions=50, rdescript="Jump: In" ), "jump out": AsynchronousAction([L(S(["cancel"], context.nav, ["right", ")~]~}~>"])) ], time_in_seconds=0.1, repetitions=50, rdescript="Jump: Out" ), "jump back": AsynchronousAction([L(S(["cancel"], context.nav, ["left", "(~[~{~<"])) ], time_in_seconds=0.1, repetitions=50, rdescript="Jump: Back" ), "jump back in": AsynchronousAction([L(S(["cancel"], context.nav, ["left", "(~[~{~<"])) ], finisher=Key("right"), time_in_seconds=0.1, repetitions=50, rdescript="Jump: Back In" ), # keyboard shortcuts 'save': R(Key("c-s"), rspec="save", rdescript="Save"), 'shock [<nnavi50>]': R(Key("enter"), rspec="shock", rdescript="Enter")* Repeat(extra="nnavi50"), "(<mtn_dir> | <mtn_mode> [<mtn_dir>]) [(<nnavi500> | <extreme>)]": R(Function(textformat.master_text_nav), rdescript="Keyboard Text Navigation"), "stoosh [<nnavi500>]": R(Key("c-c")+Function(navigation.clipboard_to_file, nexus=_NEXUS), rspec="stoosh", rdescript="Copy"), "cut [<nnavi500>]": R(Key("c-x")+Function(navigation.clipboard_to_file, nexus=_NEXUS), rspec="cut", rdescript="Cut"), "spark [<nnavi500>]": R(Function(navigation.drop, nexus=_NEXUS), rspec="spark", rdescript="Paste"), "deli [<nnavi50>]": R(Key("del/5"), rspec="deli", rdescript="Delete") * Repeat(extra="nnavi50"), "clear [<nnavi50>]": R(Key("backspace/5:%(nnavi50)d"), rspec="clear", rdescript="Backspace"), SymbolSpecs.CANCEL: R(Key("escape"), rspec="cancel", rdescript="Cancel Action"), "shackle": R(Key("home/5, s-end"), rspec="shackle", rdescript="Select Line"), "(tell | tau) <semi>": R(Function(navigation.next_line), rspec="tell dock", rdescript="Complete Line"), "duple [<nnavi50>]": R(Key("escape, home, s-end, c-c, end, enter, c-v"), rspec="duple", rdescript="Duplicate Line") * Repeat(extra="nnavi50"), "Kraken": R(Key("c-space"), rspec="Kraken", rdescript="Control Space"), # text formatting "set format (<capitalization> <spacing> | <capitalization> | <spacing>) (bow|bowel)": R(Function(textformat.set_text_format), rdescript="Set Text Format"), "clear caster formatting": R(Function(textformat.clear_text_format), rdescript="Clear Caster Formatting"), "peek format": R(Function(textformat.peek_text_format), rdescript="Peek Format"), "(<capitalization> <spacing> | <capitalization> | <spacing>) (bow|bowel) <textnv> [brunt]": R(Function(textformat.master_format_text), rdescript="Text Format"), "format <textnv>": R(Function(textformat.prior_text_format), rdescript="Last Text Format"), "<word_limit> format <textnv>": R(Function(textformat.partial_format_text), rdescript="Partial Text Format"), "dredge": R(Key("a-tab"), rdescript="Alt-Tab"), } extras = [ IntegerRefST("nnavi50", 1, 50), IntegerRefST("nnavi500", 1, 500), Dictation("textnv"), Choice("capitalization", { "yell": 1, "tie": 2, "Gerrish": 3, "sing": 4, "laws": 5 }), Choice("spacing", { "gum": 1, "gun": 1, "spine": 2, "snake": 3 }), Choice("semi", { "dock": ";", "doc": ";", "sink": "" }), Choice("word_limit", { "single": 1, "double": 2, "triple": 3, "Quadra": 4 }), navigation.TARGET_CHOICE, navigation.get_direction_choice("mtn_dir"), Choice("mtn_mode", { "shin": "s", "queue": "cs", "fly": "c", }), Choice("extreme", { "Wally": "way", }), ] defaults = { "nnavi500": 1, "nnavi50": 1, "textnv": "", "capitalization": 0, "spacing": 0, "mtn_mode": None, "mtn_dir": "right", "extreme": None }
Text(".org"), # Protocols. "protocol H T T P": Text("http://"), "protocol H T T P S": Text("https://"), "protocol (git|G I T)": Text("git://"), "protocol F T P": Text("ftp://"), "protocol S S H": Text("ssh://"), }, extras=[ IntegerRef("n", 1, 100), Dictation("text"), ], defaults={"n": 1}) terminator_grammar = Grammar("Programming help", context=GlobalDynamicContext()) terminator_grammar.add_rule(series_rule) terminator_grammar.load() # Unload function which will be called at unload time. def unload(): global terminator_grammar if grammar: grammar.unload() grammar = None
class VisualStudioCodeRule(MergeRule): pronunciation = "visual studio code" mapping = { ### ported from my dragonfly scripts # File management "[open] command palette": R(Key("cs-p"), rdescript="Visual Studio Code: Command Palette"), "(Open [file] | Go to [tab]) [<text>]": R(Key("c-p") + Text("%(text)s"), rdescript="Visual Studio Code: Go To File"), "Close tab": R(Key("c-w"), rdescript="Visual Studio Code: Close Tab"), "Save file": R(Key("c-s"), rdescript="Visual Studio Code: Save File"), "Save and close": R(Key("c-s/10, c-w"), rdescript="Visual Studio Code: Save And Close File"), # Search "(search | find in) [all] (files | codebase)": R(Key("cs-f"), rdescript="Visual Studio Code: Find in Codebase"), "(search | find) [file]": R(Key("c-f"), rdescript="Visual Studio Code: Find in File"), "(Find | Jump [to]) next <text>": R(Function(findNthToken, n=1, direction="forward"), rdescript="Visual Studio Code: Find Next"), "(Find | Jump [to]) previous <text>": R(Function(findNthToken, n=1, direction="reverse"), rdescript="Visual Studio Code: Find Previous"), # Tab management "nexta [<n>]": R(Key("c-pgdown"), rdescript="Visual Studio Code: Next Tab") * Repeat( extra="n" ), # These would be next and previous tab but i have a conflict with chrome "prexta [<n>]": R(Key("c-pgup"), rdescript="Visual Studio Code: Previous Tab") * Repeat(extra="n"), "Close tab": R(Key("c-f4"), rdescript="Visual Studio Code: Close Tab"), "Exit preview": R(Key("space, c-z"), rdescript="Visual Studio Code: Exit Preview"), # moving around a file "(go to | jump | jump to) line <n>": R(Key("c-g") + Text("%(n)d") + Key("enter"), rdescript="Visual Studio Code: Go to Line"), "Go to definition": R(Key("f12"), rdescript="Visual Studio Code: Go to Definition"), "Go to required definition": R(Key("c-f12:2, c-right:5, left/50, f12"), rdescript="Visual Studio Code: Go to Required Definition"), "Go to (top | first line)": R(Key("c-home"), rdescript="Visual Studio Code: Go to Top"), "Go to ( bottom | last line)": R(Key("c-end"), rdescript="Visual Studio Code: Go to Bottom"), "ee-ol": R(Key("end"), rdescript="Visual Studio Code: End Of Line"), "beol": R(Key("home"), rdescript="Visual Studio Code: Beginning of Line"), "Go back [<n>]": R(Key("a-left"), rdescript="Visual Studio Code: Go Back") * Repeat(extra="n"), "Go forward [<n>]": R(Key("a-right"), rdescript="Visual Studio Code: Go Forward") * Repeat(extra="n"), # Formatting "indent [<n>]": R(Key("tab"), rdescript="Visual Studio Code: Indent") * Repeat(extra="n"), "Unindent [<n>]": R(Key("s-tab"), rdescript="Visual Studio Code: Unindent") * Repeat(extra="n"), "Comment": R(Key("c-slash"), rdescript="Visual Studio Code: Line Comment"), "Block comment": R(Key("sa-a"), rdescript="Visual Studio Code: Block Comment"), # Window Management "[toggle] full screen": R(Key("f11"), rdescript="Visual Studio Code:Fullscreen"), "[toggle] Zen mode": R(Key("c-k/3, z")), # Debugging "[toggle] breakpoint": R(Key("f9"), rdescript="Visual Studio Code:Breakpoint"), "step over [<n>]": R(Key("f10/50") * Repeat(extra="n"), rdescript="Visual Studio Code:Step Over"), "step into": R(Key("f11"), rdescript="Visual Studio Code:Step Into"), "step out [of]": R(Key("s-f11"), rdescript="Visual Studio Code:Step Out"), "resume": R(Key("f5"), rdescript="Visual Studio Code:Resume"), } extras = [ Dictation("text"), Dictation("mim"), IntegerRefST("n", 1, 1000), ] defaults = {"n": 1, "mim": "", "text": ""}
class CommandRule(MappingRule): mapping = { # Code execution. "run app": Key("s-f10"), "debug app": Key("s-f9"), "re-run app": Key("c-f5"), "run this [app]": Key("cs-f10"), "run test": Key("cs-f10"), "stop running": Key("c-f2"), "[toggle] (breakpoint | break)": Key("c-f8"), "step [over]": Key("f8"), "step into": Key("f11"), "step out": Key("s-f8"), "(keep running | resume)": Key("f9"), # Code navigation. "(go to | show) class": Key("c-n"), "get file [<text>]": Function(getFile), # "Navigate > File..." "([go to | show] declaration | dive | plunge)": Key("c-b"), "[go to | show] implementation": Key("ca-b"), "[go to | show] super": Key("c-u"), "float [file] structure": Key("c-f12"), "[go to | show] structure": Key("a-7"), "[go to | show] hierarchy": Key("a-8"), "[go to | show] version control": Key("a-9"), "quick definition": Key("cs-i"), "quick (documentation | docs)": Key("c-q"), "toggle (book | bookmark)": Key("f7"), "next (book | bookmark)": Key("cs-n"), "(prev | previous) book": Key("cs-p"), "expand": Key("c-npadd"), "collapse": Key("c-npsub"), # Project settings. "[go to | show] project [window]": Key("a-1"), "[go to | show] module settings": Key("f4"), "[go to | show] [project] settings": Key("cas-s"), "[go to | show] Global settings": Key("ca-s"), # Terminal. "run terminal": Key("a-f12"), # Search. "replace": Key("c-r"), "show find": Key("c-f"), "find <text>": Key("c-f/25") + Text("%(text)s"), "find next": Key("f3"), "find (prev | previous)": Key("s-f3"), "find in files": Key("cs-f"), "find usages": Key("a-f7"), # Code. "show intentions": Key("a-enter"), "accept choice": Key("c-enter"), "implement method": Key("c-i"), "override method": Key("c-o"), "(correct | red light bulb)": Key("a-enter"), "show complete": Key("c-space"), "context complete": Key("cs-space"), "syntax complete": Key("cs-enter"), "gets complete": Key("space, equal, space/10, cs-space"), # Edit "[shoreline | show] line <w> [<x>] [<y>] [<z>]": Key("c-g/30") + Function(printNumber) + Key("enter"), "(full-screen | full screen)": Key( "cs-x" ), # macro, combination of: "Toggle Full Screen Mode" and "Hide All Tool Windows" "(Hide | hide | hi) bottom": Key("s-escape"), # "hide active tool window" "(Hide | hide | hi) side": Key("cas-c"), # "hide side tool windows" "comment [line | that | it]": Key("c-slash"), "show white space": Key("cs-w"), "redo": Key("cs-z"), # Window handling. # "preev file": Key("c-tab"), "next tab [<t>]": Key("a-right/5:%(t)d"), "(preev | previous) tab [<t>]": Key("a-left/5:%(t)d"), "close tab": Key("c-w"), # Version control. "show diff": Key("c-d"), # Refactoring. "(refactor|re-factor) (this|choose)": Key("cas-t"), "[(refactor|re-factor)] rename": Key("s-f6"), "[(refactor|re-factor)] change signature": Key("c-f6"), "(refactor|re-factor) move": Key("f6"), "(refactor|re-factor) copy": Key("f5"), "[(refactor|re-factor)] safe delete": Key("a-del"), "[(refactor|re-factor)] extract constant": Key("ca-c"), "[(refactor|re-factor)] extract field": Key("ca-f"), "[(refactor|re-factor)] extract parameter": Key("ca-p"), "[(refactor|re-factor)] extract variable": Key("ca-v"), "[(refactor|re-factor)] extract method": Key("ca-w"), "[(refactor|re-factor)] (in line|inline)": Key("ca-n"), # Custom key mappings. # "(run SSH session|run SSH console|run remote terminal|run remote console)": Key("a-f11/25, enter"), } extras = [ Integer("t", 1, 50), Dictation("text"), IntegerRef("n", 1, 50000), Integer("w", 0, 10), Integer("x", 0, 10), Integer("y", 0, 10), Integer("z", 0, 10), ] defaults = { "t": 1, }
class PythonRule(MappingRule): mapping = { "(shells | else) if": Key("e,l,i,f,space,colon,left"), specs.SymbolSpecs.IF: Key("i,f,space,colon,left"), specs.SymbolSpecs.ELSE: Text("else:") + Key("enter"), specs.SymbolSpecs.DEFINE_METHOD: Text("def ():") + Key("left:3"), "define self": Text("def (self):") + Key("left:7"), specs.SymbolSpecs.FOR_LOOP: Text("for i in range(0, ):") + Key("left:2"), specs.SymbolSpecs.FOR_EACH_LOOP: Text("for in :") + Key("left:4"), specs.SymbolSpecs.SYSOUT: Text("print "), specs.SymbolSpecs.TO_STRING: Text("str()") + Key("left"), "with": Text("with "), # "open file": Text("open('filename','r') as f:"), # "read lines": Text("content = f.readlines()"), # "try catch": Text("try:")+Key("enter:2/10, backspace")+Text("except Exception:")+Key("enter"), specs.SymbolSpecs.BREAK: Text("break"), specs.SymbolSpecs.WHILE_LOOP: Text("while :") + Key("left"), specs.SymbolSpecs.TO_INTEGER: Text("int()") + Key("left"), specs.SymbolSpecs.TO_FLOAT: Text("float()") + Key("left"), specs.SymbolSpecs.AND: Text(" and "), specs.SymbolSpecs.OR: Text(" or "), specs.SymbolSpecs.NOT: Text("!"), specs.SymbolSpecs.IMPORT: Text("import "), specs.SymbolSpecs.CLASS: Text("class ") + Text("%(text)s:") + Key("enter"), specs.SymbolSpecs.COMMENT: Text("#"), specs.SymbolSpecs.LONG_COMMENT: Text("\"\"\""), specs.SymbolSpecs.NOT_EQUAL_NULL: Text(" not None"), specs.SymbolSpecs.NULL: Text("None"), specs.SymbolSpecs.RETURN: Text("return "), specs.SymbolSpecs.TRUE: Text("True"), specs.SymbolSpecs.FALSE: Text("False"), # "sue iffae": Text("if "), # "sue shells": Text("else "), "from": Text("from "), "self": Text("self"), "long not": Text(" not "), "it are in": Text(" in "), #supposed to sound like "iter in" # "shell iffae | LFA": Key("e,l,i,f,space,colon,left"), "convert to character": Text("chr()") + Key("left"), "global": Text("global "), "list comprehension": Text("[x for x in if ]"), "[dot] (pie | pi)": Text(".py"), "identity is": Text(" is "), "length ": Text("len()") + Key("left"), } extras = [ Dictation("modifiers"), Dictation("text"), ] defaults = { "modifiers": None, }
class MergeRule(MappingRule): @staticmethod def _get_next_id(): if not hasattr(MergeRule._get_next_id, "id"): MergeRule._get_next_id.id = 0 MergeRule._get_next_id.id += 1 return MergeRule._get_next_id.id @staticmethod def get_merge_name(): # returns unique str(int) for procedural rule names return str(MergeRule._get_next_id()) mapping = {"hello world default macro": Pause("10")} '''MergeRules which define `pronunciation` will use the pronunciation string rather than their class name for their respective enable/disable commands''' pronunciation = None # Allows for self referencing rules (which include arbitrary sequences of other commands from the rule) to be included nested = None '''MergeRules which define `non` will instantiate their paired non-CCR MergeRule and activate it alongside themselves''' non = None '''MergeRules which define `mcontext` with a Dragonfly AppContext become non-global; this is the same as adding a context to a Grammar''' mcontext = None '''app MergeRules MUST define `mwith` in order to define what else they can merge with -- this is an optimization to prevent pointlessly large global CCR copies; mwith is a list of get_pronunciation()s''' mwith = None default_extras = [ IntegerRef("n", 1, 20, default=1), Dictation("text", default=""), ] def __init__(self, name=None, mapping=None, extras=None, defaults=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 self._mwith = self.__class__.mwith if self._mwith is None: self._mwith = mwith self.extras.extend(self.default_extras) MappingRule.__init__(self, name, mapping, extras, defaults, exported) def __eq__(self, other): if not isinstance(other, MergeRule): return False return self.ID == other.ID def __call__(self): return self ''' "copy" getters used for safe merging; "actual" versions used for filter functions''' def mapping_copy(self): return self._mapping.copy() def mapping_actual(self): return self._mapping def extras_copy(self): return self._extras.copy() def extras_actual(self): return self._extras def defaults_copy(self): return self._defaults.copy() def defaults_actual(self): return self._defaults def merge(self, other): mapping = self.mapping_copy() mapping.update(other.mapping_copy()) extras_dict = self.extras_copy() extras_dict.update(other.extras_copy()) # not just combining lists avoids duplicates extras = extras_dict.values() defaults = self.defaults_copy() defaults.update(other.defaults_copy()) context = self._mcontext if self._mcontext is not None else other.get_context( ) # one of these should always be None; contexts don't mix here return MergeRule( "Merged" + MergeRule.get_merge_name() + self.get_pronunciation()[0] + other.get_pronunciation()[0], mapping, extras, defaults, self._exported and other._exported, # no ID composite=self.composite.union(other.composite), mcontext=context) def get_pronunciation(self): return self.pronunciation if self.pronunciation is not None else self.name 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._mwith) def compatibility_check(self, other): if other.ID in self.compatible: return self.compatible[other.ID] # lazily compatible = True for key in self._mapping.keys(): if key in other.mapping_actual().keys(): compatible = False break self.compatible[other.ID] = compatible other.compatible[self.ID] = compatible return compatible def incompatible_IDs(self): return [ID for ID in self.compatible if not self.compatible[ID]] 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(): print(spec) # do something fancier when the ui is better def generate_docs(self): result = "# %s\n## Commands\n" % self.pronunciation.capitalize() result += "| Command | Action | Options |\n" result += "| --- | --- | --- |\n" for k, v in self.mapping.items(): if hasattr(v, "base"): v = v.base command = "%s" % k action = str(v).replace("ActionSeries", "").replace(", dynamic", "") action = re.sub(r"^\(+", "", action) action = re.sub(r"\)+", ")", action) action = re.sub(r"%\(", "***", action) action = re.sub(r"\)s", "***", action) action = re.sub(r"/\d+", "", action) options = ", ".join(re.findall(r"\<(.+?)\>", k)) result += "| `%s` | `%s` | `%s ` |\n" % (command, action, options) if not self.extras: return result result += "\n## Extras\n" for e in self.extras: if isinstance(e, RuleWrap): values = "### %s : Numbers %s-%s\n" % ( e.name, e.rule._element._min, e.rule._element._max) elif isinstance(e, Dictation): values = "### %s : Free dictation\n" % e.name elif isinstance(e, Choice): values = "### %s\n" % e.name values += "| Spoken form | Result |\n" values += "| --- | --- |\n" for k, v in e._choices.items(): values += "| `%s` | `%s` |\n" % (k, v) else: values = "" result += values # result += "| Name | Values | Default |\n" # result += "| --- | --- | --- |\n" # for e in self.extras: # name = e.name # if isinstance(e, RuleWrap): # values = "Numbers %s-%s" % (e.rule._element._min, e.rule._element._max) # elif isinstance(e, Dictation): # values = "Free dictation" # elif isinstance(e, Choice): # values = "<br/>".join(["`%s`:`%s`" % (k,v) for k,v in e._choices.items()]) + "`" # else: # values = "" # default = self.defaults[name] if name in self.defaults else "No default" # result += "| %s | %s | %s |\n" % (name, values, default) return result def _process_recognition(self, value, extras): if isinstance(value, ActionBase): value.execute(extras) elif self._log_proc: self._log_proc.warning("%s: mapping value is not an action," " cannot execute." % self)