class ChromiumRule(MappingRule): mapping = aenea.configuration.make_grammar_commands('chromium', { 'open frame': Key('c-t'), 'close frame [<n>]': (Key('c-w') + Pause('40')) * Repeat(extra='n'), 'frame [<n>]': Key('c-%(n)d'), 'west [<n>]': Key('cs-tab:%(n)d'), 'east [<n>]': Key('c-tab:%(n)d'), # url 'search [<text>]': Key('c-k') + Text('%(text)s'), 'address': Key('c-l'), # search query # 'selection': Key('c-c') + Key('c-t') + Pause('90') + Key('c-v') + Key('enter'), 'quick search': Key('c-t') + Key('c-v') + Key('enter'), 'voice search': Key('c-1') + Function(mute_microphone), # find on a page 'find [<text>]': Key('c-f') + Text('%(text)s'), 'bind [<text>]': Text('/') + Pause('50') + Text('%(text)s'), 'next [<n>]': Key('c-g:%(n)d'), 'previous [<n>]': Key('cs-g:%(n)d'), 'history': Key('c-h'), 'bookmarks': Key('c-h'), # navigation 'back [<n>]': Key('a-left:%(n)d'), 'reload': Key('c-r'), # 'back [<n>]': Key('a-left:%(n)d'), -> to global 'forward [<n>]': Key('a-right:%(n)d'), # vimium 'link': Key('f'), 'new link': Key('s-f'), 'number [<n>]': Text('%(n)d'), # zoom 'zoom in [<n>]': Key('c-plus:%(n)d'), 'zoom out [<n>]': Key('c-minus:%(n)d'), # scroll slow 'slide': Key('c-0'), }) extras = [IntegerRef('n', 1, 100), Dictation('text')] defaults = { 'n': 1, 'text': '' }
def value(self, node): words = node.words() print("format rule:", words) leading = (words[0] != 'start') trailing = False #(words[0] != 'end' and words[0] != 'isolated') if words[0] == 'start' or words[0] == 'isolated': words = words[1:] capitalize = (words[0] == 'new') if words[0] == 'new': words = words[1:] words = words[1:] # delete "phrase" if len(words) == 0: return Pause("0") formatted = '' addedWords = False for word in words: special = word.split('\\', 1) if(len(special) > 1 and special[1] != 'pronoun' and special[1] != 'determiner'): formatted += special[0] else: if(addedWords): formatted += ' ' formatted += special[0] addedWords = True if capitalize: formatted = formatted[:1].capitalize() + formatted[1:] if leading: formatted = ' ' + formatted if trailing: formatted += ' ' global lastFormatRuleWords lastFormatRuleWords = words global lastFormatRuleLength lastFormatRuleLength = len(formatted) print(" ->", formatted) return Text(formatted)
class MappingTerminal(MappingRule): mapping = { 'open terminal': Key('control:down, alt:down, t, control:up, alt:up'), 'cancel': Key('c-c'), # fzf 'get command [<text>]': Key('c-r') + Pause('200') + Text('%(text)s'), 'get file': Key('c-t'), 'get folder': Key('a-c'), # copy/paste terminal 'copy raw': Key('cs-c'), 'plop raw': Key('cs-v'), } extras = [IntegerRef('n', 1, 10), Dictation('text')] defaults = {'n': 1, 'text': ''}
class jideaRule(MappingRule): mapping = aenea.configuration.make_grammar_commands('jidea', { "all actions": Key("cs-a"), # Code execution. "run app": Key("s-f10"), "re-run app": Key("c-f5"), "run test": Key("cs-f10"), "stop running": Key("c-f2"), # Code navigation. "navigate to class <text>": Key("c-n") + Pause("30") + Function(format.pascal_case_text) + Pause("30") + Key( "enter"), "navigate to class chooser <text>": Key("c-n") + Pause("30") + Function(format.pascal_case_text) + Pause("30"), "navigate to file <text>": Key("cs-n") + Pause("30") + Function(format.camel_case_text) + Pause("30") + Key( "enter"), "navigate to file chooser <text>": Key("cs-n") + Pause("30") + Function(format.camel_case_text) + Pause("30"), "navigate to symbol <text>": Key("cas-n") + Pause("30") + Function(format.camel_case_text) + Pause("30") + Key( "enter"), "navigate to symbol chooser <text>": Key("cas-n") + Pause("30") + Function(format.camel_case_text) + Pause( "30"), "go to declaration": Key("c-b"), "go to implementation": Key("ca-b"), "go to super": Key("c-u"), "go to (class|test)": Key("cs-t"), "go back": Key("a-left"), # Project settings. "go to project window": Key("a-1"), "go to module settings": Key("f4"), "go to [project] settings": Key("ca-s"), "synchronize files": Key("ca-y"), # Terminal. "run terminal": Key("a-f12"), # Search. "find in path": Key("cs-f"), "find usages": Key("a-f7"), "find <text>": Key("c-f") + Text('%(text)s'), "replace <text>": Key("c-r") + Text('%(text)s'), # Edit. "save [file|all]": Key("c-s"), # Code. "show intentions": Key("a-enter"), "accept choice": Key("c-enter"), "go to line": Key("c-g"), "go to line <n>": Key("c-g/25") + Text("%(n)d") + Key("enter"), "[go to] start of line": Key("home"), "[go to] end of line": Key("end"), "down": Key("down"), # Window handling. "tab foo": Key("c-tab"), "tab bar": Key("cs-tab"), "close tab": Key("c-f4"), # 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 variable": Key("ca-v"), "(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 method": Key("ca-m"), "(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"), #debug }) extras = [ Dictation("text"), IntegerRef("n", 1, 50000) ]
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 `auto` (array of strings, each string a file extension for a language) will work with auto command and language mode''' auto = None '''MergeRules which define `pronunciation` will use the pronunciation string rather than their class name for their respective enable/disable commands''' pronunciation = None '''MergeRules which define `non` will instantiate their paired non-CCR MergeRule and activate it alongside themselves''' non = None '''MergeRules which define `token_set` will enable scanning of directories for use with the "symbol match" command in their language''' token_set = 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_name()s''' mwith = None 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 if mapping is not None: mapping["display available commands"] = Function( lambda: self._display_available_commands()) MappingRule.__init__(self, name, mapping, extras, defaults, exported) def __eq__(self, other): if not isinstance(other, MergeRule): return False return self.ID == other.ID ''' "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_name()[0] + other.get_name()[0], mapping, extras, defaults, self._exported and other._exported, # no ID composite=self.composite.union(other.composite), mcontext=context) 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._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
genericKeys = { "release all": Key("shift:up, ctrl:up, alt:up, win:up"), "say <reservedWord>": Text("%(reservedWord)s"), # press keystroke "press <pressKey>": Key("%(pressKey)s"), "<modifier1> <pressKey> [<n>]": Key("%(modifier1)s-%(pressKey)s:%(n)d"), "<modifier1> <modifier2> <pressKey> [<n>]": Key("%(modifier1)s%(modifier2)s-%(pressKey)s:%(n)d"), # keystroke with intervals "play <pressKey>": (Key("%(pressKey)s") + Pause('100')) * Repeat(10), "play <specials>": (Key("%(specials)s") + Pause('100')) * Repeat(10), "play <pressKey> <n>": (Key("%(pressKey)s") + Pause('100')) * Repeat(extra="n"), "play <specials> <n>": (Key("%(specials)s") + Pause('100')) * Repeat(extra="n"), # mouse buttons "tick": Mouse("left"), "dooble": Mouse("left:2"), "tock": Mouse("right"), "hold tick": Mouse("left:down"),