"set file format UNIX": Text("set fileformat=unix "), "set file format DOS": Text("set fileformat=dos "), "set file type Python": Text("set filetype=python"), "set file type tex": Text("set filetype=tex"), "P. W. D.": Text("pwd "), "help": Text("help"), "substitute": Text("s/"), "up": Key("up"), "down": Key("down"), "[<n>] left": Key("left:%(n)d"), "[<n>] right": Key("right:%(n)d"), } extras = [ Dictation("text"), IntegerRef("n", 1, 50), ] defaults = { "n": 1, } # set up the grammar for vim's ex mode exModeBootstrap = Grammar("ExMode bootstrap", context=general_context) exModeBootstrap.add_rule(ExModeEnabler()) exModeBootstrap.load() ExModeGrammar = Grammar("ExMode grammar", context=general_context) ExModeGrammar.add_rule(ExModeCommands()) ExModeGrammar.add_rule(ExModeDisabler()) ExModeGrammar.load() ExModeGrammar.disable()
}, extras=[ IntegerRef("n", 1, 100), Dictation("text"), Choice("gitcmd", gitcmd), Choice("gitopt", gitopt), ], defaults={ "n": 1 } ) terminator_grammar = Grammar("Git commands", context=GlobalDynamicContext()) terminator_grammar.add_rule(series_rule) terminator_grammar.load() terminator_grammar.disable() def dynamic_enable(): global terminator_grammar if grammar.enabled: return False else: grammar.enable() return True def dynamic_disable(): global terminator_grammar if grammar.enabled: grammar.disable()
def _process_recognition(self, node, extras): typescript_grammar.disable() typescript_bootstrap.enable() print("TypeScript grammar disabled") class TypeScript(MappingRule): mapping = { "new react component": Key("f, c, tab"), } extras = [] typescript_bootstrap = Grammar("TypeScript bootstrap") typescript_bootstrap.add_rule(TypeScriptEnabler()) typescript_bootstrap.load() typescript_grammar = Grammar("TypeScript grammar") typescript_grammar.add_rule(TypeScriptDisabler()) typescript_grammar.add_rule(TypeScript()) typescript_grammar.load() typescript_grammar.disable() def unload(): global typescript_grammar if typescript_grammar: typescript_grammar.unload() typescript_grammar = None
"window up": Key("c-w,k"), "window down": Key("c-w,j"), "terminal tabulator next": Key("c-w") + Text(":tabn") + Key('enter'), "terminal tabulator previous": Key("c-w") + Text(":tabp") + Key('enter'), # debugger options "debug next": Text("n") + Key("enter"), "debug quit": Text("quit()") + Key("enter"), "debug continue": Text("c") + Key("enter"), } # The main Python grammar rules are activated here vimTerminalBootstrap = Grammar("vim terminal bootstrap") vimTerminalBootstrap.add_rule(TerminalEnabler()) vimTerminalBootstrap.load() terminalGrammer = Grammar("terminal grammar") terminalGrammer.add_rule(TerminalCommands()) terminalGrammer.add_rule(TerminalDisabler()) terminalGrammer.load() terminalGrammer.disable() # Unload function which will be called by natlink at unload time. def unload(): global terminalGrammer if terminalGrammer: terminalGrammer.unload() terminalGrammer = None
extras): # Callback when command is spoken. pythonBootstrap.disable() pythonGrammar.enable() print("Python grammar enabled") class PythonDisabler(CompoundRule): spec = "switch language" # spoken command to disable the Python grammar. def _process_recognition(self, node, extras): # Callback when command is spoken. pythonGrammar.disable() pythonBootstrap.enable() print("Python grammar disabled") pythonBootstrap = Grammar("python bootstrap") pythonBootstrap.add_rule(PythonEnabler()) pythonBootstrap.load() pythonGrammar = Grammar("python grammar") pythonGrammar.load() pythonGrammar.disable() def unload(): global pythonGrammar if pythonGrammar: pythonGrammar.unload() pythonGrammar = None
"title": "title", # means the same thing and represents a table row "table row": "tr", "TR": "tr", "track": "track", "unordered list": "ul", "variable": "var", "video": "video", "label": "label", } ) ] # Code for initial setup of the HTML grammar htmlBootstrap = Grammar("html bootstrap") # Create a grammar to contain the command rule. htmlBootstrap.add_rule(HTMLEnabler()) htmlBootstrap.load() htmlGrammar = Grammar("html grammar") htmlGrammar.add_rule(HTMLTestRule()) htmlGrammar.add_rule(HTMLDisabler()) htmlGrammar.add_rule(HTMLTags()) htmlGrammar.load() htmlGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global htmlGrammar if htmlGrammar: htmlGrammar.unload() htmlGrammar = None
# The main Java grammar rules are activated here javaBootstrap = Grammar("java bootstrap") javaBootstrap.add_rule(JavaEnabler()) javaBootstrap.load() javaGrammar = Grammar("java grammar") javaGrammar.add_rule(JavaTestRule()) javaGrammar.add_rule(JavaCommentsSyntax()) javaGrammar.add_rule(JavaDataTypes()) javaGrammar.add_rule(JavaComparisonOperators()) javaGrammar.add_rule(JavaBooleanOperators()) javaGrammar.add_rule(JavaControlStructures()) javaGrammar.add_rule(JavaUsefulMethods()) javaGrammar.add_rule(JavaArithmeticOperators()) javaGrammar.add_rule(JavaAssignmentOperators()) javaGrammar.add_rule(JavaMiscellaneousStuff()) javaGrammar.add_rule(JavaAccessModifiers()) javaGrammar.add_rule(JavaEscapeSequences()) javaGrammar.add_rule(JavaDisabler()) javaGrammar.load() javaGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global javaGrammar if javaGrammar: javaGrammar.unload() javaGrammar = None
class MasterGrammar(object): """A MasterGrammar is built up from a specific set of active rules. They synthesize the different rule types into one dragonfly grammar. There is only ever one master grammar active at a time.""" def __init__(self, baseRuleSet, client, ruleCache): self.client = client self.ruleCache = ruleCache # Hashes that are directly part of this grammar self.baseRuleSet = set(baseRuleSet) # Hashes of rules that we discover are dependencies # of the base rule set self.dependencyRuleSet = set() # hash -> dragonfly rule self.concreteRules = {} # one hash per merge group, hash is of hashes of rules that were merged self.seriesRules = set() # one hash, hash is of hashes of rules that were merged self.terminatorRule = "" # one hash per rule, hash is the rule's actual hash self.independentRules = set() # Rule references are stored as hashes, so rules that # contain rule refs already effectively include those # rules in their hash, so just hashing the base set is # all we need. x = hashlib.sha256() x.update("".join(sorted([r for r in self.baseRuleSet]))) self.hash = x.hexdigest()[:32] # Hashes of rules we depend on but haven't arrived yet. # These will be discovered during the dfly grammar building # process. self.missing = set() self.checkDeps(self.fullRullSet) # build self.missing self.finalDflyRule = None self.dflyGrammar = None # word lists are *not* hashed. they are global state the # client can update at any time, and the change has to be # propogated into the currently active grammar. the client # can choose to make them rule specific by making the name # be the hash of the rule the word list applies to, but this # is only convention and not enforced self.concreteWordLists = {} @property def fullRullSet(self): return self.baseRuleSet | self.dependencyRuleSet def satisfyDependency(self, r): """Marks dependency on hash r as satisfied, and tries to build if no more known deps are missing. During the build process new indirect dependencies may still be discovered however.""" assert r in self.missing self.missing.remove(r) if not self.missing: self.build() def checkDep(self, r): "Checks if dep r is present. Not recursive." if r not in self.ruleCache: self.ruleCache[r] = NeedDependency() if isinstance(self.ruleCache[r], NeedDependency): self.ruleCache[r].add(self.hash) self.missing.add(r) return False return True def checkMissing(self): if self.missing: raise MissingDependency(copy(self.missing)) def checkDeps(self, ruleSet): "Recursively check if all deps in ruleSet are satisfied." if not ruleSet: return True newDeps = set() for r in ruleSet: if self.checkDep(r): rule = self.ruleCache[r] # HashedRule rule = rule.rule log.info("rule [%s]" % (rule, )) for e in rule.extras: if hasattr(e, "rule_ref"): newDeps.add(e.rule_ref) self.dependencyRuleSet.update(newDeps) self.checkDeps(newDeps) def ready(self): return len(self.missing) == 0 def build(self): if self.dflyGrammar: # already built return buildStartTime = time.time() self.checkMissing() self.checkDeps(self.fullRullSet) self.checkMissing() # from here on we assume all deps are present all the way down seriesGroups = {} terminal = {} allRules = [] mergeStartTime = time.time() # Merge series and terminal rules, set independent rules aside self.fullName = [] for r in self.fullRullSet: rule = self.ruleCache[r].rule hash = self.ruleCache[r].hash if rule.ruleType == RuleType.SERIES: if rule.seriesMergeGroup not in seriesGroups: seriesGroups[rule.seriesMergeGroup] = {} x = seriesGroups[rule.seriesMergeGroup] elif rule.ruleType == RuleType.TERMINAL: x = terminal elif rule.ruleType == RuleType.INDEPENDENT: x = {} if "mapping" not in x: x["mapping"] = {} if "extras" not in x: x["extras"] = {} if "defaults" not in x: x["defaults"] = {} if "name" not in x: x["name"] = "" if "hash" not in x: x["hash"] = set() x["ruleType"] = rule.ruleType x["seriesMergeGroup"] = rule.seriesMergeGroup x["name"] = x["name"] + ("," if x["name"] else "") + rule.name x["mapping"].update(rule.mapping.items()) for e in rule.extras: x["extras"][e.name] = e x["defaults"].update(rule.defaults.items()) log.info("Adding hash [%s] to name [%s]" % (hash, x["name"])) x["hash"].add(hash) x["built"] = False x["exported"] = (rule.ruleType == RuleType.INDEPENDENT) # allRules will contain all the rules we have left # *after* merging. So only one series rule per merge # group and only one terminal rule. allRules.append(x) mergeEndTime = time.time() log.info("Grammar merge time: %ss" % (mergeEndTime - mergeStartTime)) # We really should be doing a topological sort, but this # isn't a frequent operation so this inefficiency should # be OK. Keep trying to link deps until they're all good. uniqueRules = [] for r in allRules: if r not in uniqueRules: uniqueRules.append(r) self.fullName.append(r["name"]) self.fullName = ",".join(self.fullName) allRules = uniqueRules # collapse the hashes for r in allRules: assert type(r["hash"]) == set assert len(r["hash"]) >= 1 if r["ruleType"] in (RuleType.SERIES, RuleType.TERMINAL): # We generate a composite hash for our new composite rules log.info("Multi-hash: [%s]" % r["hash"]) hashes = sorted(list(r["hash"])) x = hashlib.sha256() x.update("".join(sorted([h for h in hashes]))) hash = x.hexdigest()[:32] log.info("Composite: [%s]" % hash) else: # We just use the exising hash for a rule if it's not composite [hash] = r["hash"] log.info("Single hash: [%s]" % r["hash"]) r["hash"] = hash allPrototypes = {i["hash"]: i for i in allRules} self.concreteTime = 0 cleanupTime = 0 for k, v in allPrototypes.items(): if not v["built"]: cleanupStart = time.time() self.cleanupProtoRule(v, allPrototypes) cleanupEnd = time.time() cleanupTime += (cleanupEnd - cleanupStart) log.info("Total Cleanup time: %ss" % cleanupTime) log.info("Total Concrete time: %ss" % (self.concreteTime)) #log.info("made it out of loop") self.buildFinalMergedRule() buildEndTime = time.time() log.info("Grammar build time: %ss" % (buildEndTime - buildStartTime)) self.setupFinalDflyGrammar() def buildFinalMergedRule(self): #log.info("Building final merged rule.") if not self.seriesRules and not self.terminatorRule: return extras = [] seriesRefNames = [] for i, r in enumerate(self.seriesRules): name = "s" + str(i) seriesRefNames.append(name) ref = dfly.RuleRef(self.concreteRules[r], name) extras.append(ref) seriesPart = "[" + " | ".join([("<" + r + ">") for r in seriesRefNames]) + "]" terminatorPart = "" if self.terminatorRule: extras.append( dfly.RuleRef(self.concreteRules[self.terminatorRule], "terminator")) terminatorPart = " [<terminator>]" masterPhrase = seriesPart + terminatorPart mapping = { masterPhrase: ReportingAction(masterPhrase, self.client, self.hash) } log.info( "Building master grammar rule with name [%s] mapping [%s] extras [%s] defaults [%s]" % (self.fullName, mapping, extras, {})) masterTimeStart = time.time() self.finalDflyRule = MappingRule(name=self.hash, mapping=mapping, extras=extras, defaults={}, exported=True) masterTimeEnd = time.time() log.info("Master rule construction time: %ss" % (masterTimeEnd - masterTimeStart)) def setupFinalDflyGrammar(self): log.info("Setting up final grammar.") assert not self.dflyGrammar self.dflyGrammar = Grammar(self.fullName + "Grammar") if self.finalDflyRule: self.dflyGrammar.add_rule(self.finalDflyRule) for r in self.independentRules: self.dflyGrammar.add_rule(self.concreteRules[r]) loadStart = time.time() self.dflyGrammar.load() loadEnd = time.time() log.info("Grammar load time: %ss" % (loadEnd - loadStart)) get_engine().set_exclusiveness(self.dflyGrammar, 1) # These should never be recognized on their own, only as part of the # master rule, quirk of dragonfly that you have to do this even though # they're only pulled in by ruleref. for r in self.seriesRules: self.concreteRules[r].disable() if self.terminatorRule: self.concreteRules[self.terminatorRule].disable() # independent rules only enabled via being a dependency need to have disable # called on their dragonfly version so that they don't get recognized by # themselves, same quirk. notEnabledRules = self.dependencyRuleSet - self.baseRuleSet for r in notEnabledRules: self.concreteRules[r].disable() # they're enabled by default, don't activate until explicitly made to self.dflyGrammar.disable() def active(self): #log.info("active check [%s %s %s]" % (self.dflyGrammar is None, self.dflyGrammar and self.dflyGrammar.loaded, self.dflyGrammar and self.dflyGrammar.enabled)) return self.dflyGrammar and self.dflyGrammar.loaded and self.dflyGrammar.enabled def activate(self): self.build() self.dflyGrammar.enable() log.info("Grammar activated: [%s]" % self.hash) def deactivate(self): # it's possible we never built successfully if self.dflyGrammar: self.dflyGrammar.disable() log.info("Grammar deactivated: [%s]" % self.hash) def unload(self): self.deactivate() if self.dflyGrammar: self.dflyGrammar.unload() def buildConcreteRule(self, r): # for independent rules we could use the plain # name, but it turns out Dragon crashes if your # names get too long, so for combined rules we # just use the hash as the name... hopefully # that's under the limit name = r["hash"] if r["ruleType"] == RuleType.SERIES: t = SeriesMappingRule elif r["ruleType"] == RuleType.TERMINAL: t = MappingRule else: t = MappingRule constructionStartTime = time.time() log.info( "Building rule [%s] with size [%s] num extras [%s] num defaults [%s]" % (r["name"], len(r["mapping"]), len( r["extras"]), len(r["defaults"]))) rule = t(name=name, mapping=r["mapping"], extras=r["extras"], defaults=r["defaults"], exported=r["exported"]) constructionEndTime = time.time() log.info("Rule construction time: %ss" % (constructionEndTime - constructionStartTime)) self.concreteRules[r["hash"]] = rule if r["ruleType"] == RuleType.SERIES: self.seriesRules.add(r["hash"]) elif r["ruleType"] == RuleType.TERMINAL: self.terminatorRule = r["hash"] elif r["ruleType"] == RuleType.INDEPENDENT: self.independentRules.add(r["hash"]) else: assert False log.info("done building") def cleanupProtoRule(self, r, allPrototypes): # have to uniquify in this round about way because lists # aren't hashable and we need them for ListRef. if type(r["extras"]) == dict: r["extras"] = r["extras"].values() newExtras = [] for e in r["extras"]: if isinstance(e, protocol.Integer): newExtras.append(dfly.Integer(e.name, e.min, e.max)) elif isinstance(e, protocol.Dictation): newExtras.append(dfly.Dictation(e.name)) elif isinstance(e, protocol.Repetition): if e.rule_ref not in self.concreteRules: self.cleanupProtoRule(allPrototypes[e.rule_ref], allPrototypes) # Dragonfly wants RuleRef to take a RuleRef rather than an actual # Rule, so we just make one rather than forcing the server to # handle this, see protocol.py comments. concrete = self.concreteRules[e.rule_ref] log.info("concrete type: [%s]" % type(concrete)) newExtras.append( dfly.Repetition(dfly.RuleRef(rule=concrete), e.min, e.max, e.name)) elif isinstance(e, protocol.RuleRef): if e.rule_ref not in self.concreteRules: self.cleanupProtoRule(allPrototypes[e.rule_ref], allPrototypes) newExtras.append( dfly.RuleRef(self.concreteRules[e.rule_ref], e.name)) elif isinstance(e, protocol.ListRef): self.concreteWordLists[e.name] = List(e.name + "ConcreteList") # self.concreteWordLists[e.name].set(e.words) newExtras.append( dfly.ListRef(e.ref_name, self.concreteWordLists[e.name])) else: raise Exception("Unknown extra type: [%s]" % e) r["extras"] = newExtras self.concreteStartTime = time.time() self.buildConcreteRule(r) self.concreteEndTime = time.time() self.concreteTime += (self.concreteEndTime - self.concreteStartTime) r["built"] = True return True def updateWordList(self, name, words): if name not in self.concreteWordLists: # log.info("Word list [%s] not in grammar [%s], ignoring" % (name, self.hash)) return # We want to check if the value has actually changed because List's # set method will blindly tell Dragon to delete its old list and replace # it with this one and we don't want to disturb Dragon unless we have to # because Dragon is slow. if sorted(words) != sorted(self.concreteWordLists[name]): log.info( "Updating word list [%s] on grammar [%s] with contents [%s]" % (name, self.hash, len(words))) log.info("old list: %s" % self.concreteWordLists[name]) # TODO: need to check existing load state, then send a loading message here, then restore # old state. This way we can see when word lists are taking a long time to load... updateStart = time.time() self.concreteWordLists[name].set(words) updateEnd = time.time() log.info("Word list update time: %ss" % (updateEnd - updateStart))
Function(middle_slash_format) + Text(":;") + Key("left"), "comment": Text("/* */"), } extras = [ Dictation("command"), ] # Code for initial setup of the HTML grammar cssBootstrap = Grammar( "css bootstrap") # Create a grammar to contain the command rule. cssBootstrap.add_rule(CSSEnabler()) cssBootstrap.load() cssGrammar = Grammar("css grammar") cssGrammar.add_rule(CSSTestRule()) cssGrammar.add_rule(CSSDisabler()) cssGrammar.add_rule(CSSValues()) cssGrammar.add_rule(CSSSelectors()) cssGrammar.add_rule(CSSTags()) cssGrammar.load() cssGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global cssGrammar if cssGrammar: cssGrammar.unload() cssGrammar = None
} phpBootstrap = Grammar("php bootstrap") # Create a grammar to contain the command rule. phpBootstrap.add_rule(PHPEnabler()) phpBootstrap.load() phpGrammar = Grammar("php grammar") phpGrammar.add_rule(PHPTestRule()) phpGrammar.add_rule(PHPDataTypes()) phpGrammar.add_rule(PHPVariableDeclarations()) phpGrammar.add_rule(PHPCommentsSyntax()) phpGrammar.add_rule(PHPSuperGlobals()) phpGrammar.add_rule(PHPControlStructures()) phpGrammar.add_rule(PHPAccessModifiers()) phpGrammar.add_rule(PHPUsefulMethods()) phpGrammar.add_rule(PHPLogicalOperators()) phpGrammar.add_rule(PHPAssignmentOperators()) phpGrammar.add_rule(PHPArithmeticOperators()) phpGrammar.add_rule(PHPEscapeSequences()) phpGrammar.add_rule(PHPComparisonOperators()) phpGrammar.add_rule(PHPMiscellaneousStuff()) phpGrammar.add_rule(PHPDisabler()) phpGrammar.load() phpGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global phpGrammar if phpGrammar: phpGrammar.unload() phpGrammar = None
class MasterGrammar(object): """A MasterGrammar is built up from a specific set of active rules. They synthesize the different rule types into one dragonfly grammar. There is only ever one master grammar active at a time.""" def __init__(self, baseRuleSet, client, ruleCache): self.client = client self.ruleCache = ruleCache # Hashes that are directly part of this grammar self.baseRuleSet = set(baseRuleSet) # Hashes of rules that we discover are dependencies # of the base rule set self.dependencyRuleSet = set() # hash -> dragonfly rule self.concreteRules = {} # one hash per merge group, hash is of hashes of rules that were merged self.seriesRules = set() # one hash, hash is of hashes of rules that were merged self.terminatorRule = "" # one hash per rule, hash is the rule's actual hash self.independentRules = set() # Rule references are stored as hashes, so rules that # contain rule refs already effectively include those # rules in their hash, so just hashing the base set is # all we need. x = hashlib.sha256() x.update("".join(sorted([r for r in self.baseRuleSet]))) self.hash = x.hexdigest()[:32] # Hashes of rules we depend on but haven't arrived yet. # These will be discovered during the dfly grammar building # process. self.missing = set() self.checkDeps(self.fullRullSet) # build self.missing self.finalDflyRule = None self.dflyGrammar = None # word lists are *not* hashed. they are global state the # client can update at any time, and the change has to be # propogated into the currently active grammar. the client # can choose to make them rule specific by making the name # be the hash of the rule the word list applies to, but this # is only convention and not enforced self.concreteWordLists = {} @property def fullRullSet(self): return self.baseRuleSet | self.dependencyRuleSet def satisfyDependency(self, r): """Marks dependency on hash r as satisfied, and tries to build if no more known deps are missing. During the build process new indirect dependencies may still be discovered however.""" assert r in self.missing self.missing.remove(r) if not self.missing: self.build() def checkDep(self, r): "Checks if dep r is present. Not recursive." if r not in self.ruleCache: self.ruleCache[r] = NeedDependency() if isinstance(self.ruleCache[r], NeedDependency): self.ruleCache[r].add(self.hash) self.missing.add(r) return False return True def checkMissing(self): if self.missing: raise MissingDependency(copy(self.missing)) def checkDeps(self, ruleSet): "Recursively check if all deps in ruleSet are satisfied." if not ruleSet: return True newDeps = set() for r in ruleSet: if self.checkDep(r): rule = self.ruleCache[r] # HashedRule rule = rule.rule log.info("rule [%s]" % (rule,)) for e in rule.extras: if hasattr(e, "rule_ref"): newDeps.add(e.rule_ref) self.dependencyRuleSet.update(newDeps) self.checkDeps(newDeps) def ready(self): return len(self.missing) == 0 def build(self): if self.dflyGrammar: # already built return buildStartTime = time.time() self.checkMissing() self.checkDeps(self.fullRullSet) self.checkMissing() # from here on we assume all deps are present all the way down seriesGroups = {} terminal = {} allRules = [] mergeStartTime = time.time() # Merge series and terminal rules, set independent rules aside self.fullName = [] for r in self.fullRullSet: rule = self.ruleCache[r].rule hash = self.ruleCache[r].hash if rule.ruleType == RuleType.SERIES: if rule.seriesMergeGroup not in seriesGroups: seriesGroups[rule.seriesMergeGroup] = {} x = seriesGroups[rule.seriesMergeGroup] elif rule.ruleType == RuleType.TERMINAL: x = terminal elif rule.ruleType == RuleType.INDEPENDENT: x = {} if "mapping" not in x: x["mapping"] = {} if "extras" not in x: x["extras"] = {} if "defaults" not in x: x["defaults"] = {} if "name" not in x: x["name"] = "" if "hash" not in x: x["hash"] = set() x["ruleType"] = rule.ruleType x["seriesMergeGroup"] = rule.seriesMergeGroup x["name"] = x["name"] + ("," if x["name"] else "") + rule.name x["mapping"].update(rule.mapping.items()) for e in rule.extras: x["extras"][e.name] = e x["defaults"].update(rule.defaults.items()) log.info("Adding hash [%s] to name [%s]" % (hash, x["name"])) x["hash"].add(hash) x["built"] = False x["exported"] = (rule.ruleType == RuleType.INDEPENDENT) # allRules will contain all the rules we have left # *after* merging. So only one series rule per merge # group and only one terminal rule. allRules.append(x) mergeEndTime = time.time() log.info("Grammar merge time: %ss" % (mergeEndTime - mergeStartTime)) # We really should be doing a topological sort, but this # isn't a frequent operation so this inefficiency should # be OK. Keep trying to link deps until they're all good. uniqueRules = [] for r in allRules: if r not in uniqueRules: uniqueRules.append(r) self.fullName.append(r["name"]) self.fullName = ",".join(self.fullName) allRules = uniqueRules # collapse the hashes for r in allRules: assert type(r["hash"]) == set assert len(r["hash"]) >= 1 if r["ruleType"] in (RuleType.SERIES, RuleType.TERMINAL): # We generate a composite hash for our new composite rules log.info("Multi-hash: [%s]" % r["hash"]) hashes = sorted(list(r["hash"])) x = hashlib.sha256() x.update("".join(sorted([h for h in hashes]))) hash = x.hexdigest()[:32] log.info("Composite: [%s]" % hash) else: # We just use the exising hash for a rule if it's not composite [hash] = r["hash"] log.info("Single hash: [%s]" % r["hash"]) r["hash"] = hash allPrototypes = { i["hash"] : i for i in allRules } self.concreteTime = 0 cleanupTime = 0 for k, v in allPrototypes.items(): if not v["built"]: cleanupStart = time.time() self.cleanupProtoRule(v, allPrototypes) cleanupEnd = time.time() cleanupTime += (cleanupEnd - cleanupStart) log.info("Total Cleanup time: %ss" % cleanupTime) log.info("Total Concrete time: %ss" % (self.concreteTime)) #log.info("made it out of loop") self.buildFinalMergedRule() buildEndTime = time.time() log.info("Grammar build time: %ss" % (buildEndTime - buildStartTime)) self.setupFinalDflyGrammar() def buildFinalMergedRule(self): #log.info("Building final merged rule.") if not self.seriesRules and not self.terminatorRule: return extras = [] seriesRefNames = [] for i, r in enumerate(self.seriesRules): name = "s" + str(i) seriesRefNames.append(name) ref = dfly.RuleRef(self.concreteRules[r], name) extras.append(ref) seriesPart = "[" + " | ".join([("<" + r + ">") for r in seriesRefNames]) + "]" terminatorPart = "" if self.terminatorRule: extras.append(dfly.RuleRef(self.concreteRules[self.terminatorRule], "terminator")) terminatorPart = " [<terminator>]" masterPhrase = seriesPart + terminatorPart mapping = { masterPhrase : ReportingAction(masterPhrase, self.client, self.hash) } log.info("Building master grammar rule with name [%s] mapping [%s] extras [%s] defaults [%s]" % (self.fullName, mapping, extras, {})) masterTimeStart = time.time() self.finalDflyRule = MappingRule(name=self.hash, mapping=mapping, extras=extras, defaults={}, exported=True) masterTimeEnd = time.time() log.info("Master rule construction time: %ss" % (masterTimeEnd - masterTimeStart)) def setupFinalDflyGrammar(self): log.info("Setting up final grammar.") assert not self.dflyGrammar self.dflyGrammar = Grammar(self.fullName + "Grammar") if self.finalDflyRule: self.dflyGrammar.add_rule(self.finalDflyRule) for r in self.independentRules: self.dflyGrammar.add_rule(self.concreteRules[r]) loadStart = time.time() self.dflyGrammar.load() loadEnd = time.time() log.info("Grammar load time: %ss" % (loadEnd - loadStart)) get_engine().set_exclusiveness(self.dflyGrammar, 1) # These should never be recognized on their own, only as part of the # master rule, quirk of dragonfly that you have to do this even though # they're only pulled in by ruleref. for r in self.seriesRules: self.concreteRules[r].disable() if self.terminatorRule: self.concreteRules[self.terminatorRule].disable() # independent rules only enabled via being a dependency need to have disable # called on their dragonfly version so that they don't get recognized by # themselves, same quirk. notEnabledRules = self.dependencyRuleSet - self.baseRuleSet for r in notEnabledRules: self.concreteRules[r].disable() # they're enabled by default, don't activate until explicitly made to self.dflyGrammar.disable() def active(self): #log.info("active check [%s %s %s]" % (self.dflyGrammar is None, self.dflyGrammar and self.dflyGrammar.loaded, self.dflyGrammar and self.dflyGrammar.enabled)) return self.dflyGrammar and self.dflyGrammar.loaded and self.dflyGrammar.enabled def activate(self): self.build() self.dflyGrammar.enable() log.info("Grammar activated: [%s]" % self.hash) def deactivate(self): # it's possible we never built successfully if self.dflyGrammar: self.dflyGrammar.disable() log.info("Grammar deactivated: [%s]" % self.hash) def unload(self): self.deactivate() if self.dflyGrammar: self.dflyGrammar.unload() def buildConcreteRule(self, r): # for independent rules we could use the plain # name, but it turns out Dragon crashes if your # names get too long, so for combined rules we # just use the hash as the name... hopefully # that's under the limit name = r["hash"] if r["ruleType"] == RuleType.SERIES: t = SeriesMappingRule elif r["ruleType"] == RuleType.TERMINAL: t = MappingRule else: t = MappingRule constructionStartTime = time.time() log.info("Building rule [%s] with size [%s] num extras [%s] num defaults [%s]" % (r["name"], len(r["mapping"]), len(r["extras"]), len(r["defaults"]))) rule = t(name=name, mapping=r["mapping"], extras=r["extras"], defaults=r["defaults"], exported=r["exported"]) constructionEndTime = time.time() log.info("Rule construction time: %ss" % (constructionEndTime - constructionStartTime)) self.concreteRules[r["hash"]] = rule if r["ruleType"] == RuleType.SERIES: self.seriesRules.add(r["hash"]) elif r["ruleType"] == RuleType.TERMINAL: self.terminatorRule = r["hash"] elif r["ruleType"] == RuleType.INDEPENDENT: self.independentRules.add(r["hash"]) else: assert False log.info("done building") def cleanupProtoRule(self, r, allPrototypes): # have to uniquify in this round about way because lists # aren't hashable and we need them for ListRef. if type(r["extras"]) == dict: r["extras"] = r["extras"].values() newExtras = [] for e in r["extras"]: if isinstance(e, protocol.Integer): newExtras.append(dfly.Integer(e.name, e.min, e.max)) elif isinstance(e, protocol.Dictation): newExtras.append(dfly.Dictation(e.name)) elif isinstance(e, protocol.Repetition): if e.rule_ref not in self.concreteRules: self.cleanupProtoRule(allPrototypes[e.rule_ref], allPrototypes) # Dragonfly wants RuleRef to take a RuleRef rather than an actual # Rule, so we just make one rather than forcing the server to # handle this, see protocol.py comments. concrete = self.concreteRules[e.rule_ref] log.info("concrete type: [%s]" % type(concrete)) newExtras.append(dfly.Repetition(dfly.RuleRef(rule=concrete), e.min, e.max, e.name)) elif isinstance(e, protocol.RuleRef): if e.rule_ref not in self.concreteRules: self.cleanupProtoRule(allPrototypes[e.rule_ref], allPrototypes) newExtras.append(dfly.RuleRef(self.concreteRules[e.rule_ref], e.name)) elif isinstance(e, protocol.ListRef): self.concreteWordLists[e.name] = List(e.name + "ConcreteList") # self.concreteWordLists[e.name].set(e.words) newExtras.append(dfly.ListRef(e.ref_name, self.concreteWordLists[e.name])) else: raise Exception("Unknown extra type: [%s]" % e) r["extras"] = newExtras self.concreteStartTime = time.time() self.buildConcreteRule(r) self.concreteEndTime = time.time() self.concreteTime += (self.concreteEndTime - self.concreteStartTime) r["built"] = True return True def updateWordList(self, name, words): if name not in self.concreteWordLists: # log.info("Word list [%s] not in grammar [%s], ignoring" % (name, self.hash)) return # We want to check if the value has actually changed because List's # set method will blindly tell Dragon to delete its old list and replace # it with this one and we don't want to disturb Dragon unless we have to # because Dragon is slow. if sorted(words) != sorted(self.concreteWordLists[name]): log.info("Updating word list [%s] on grammar [%s] with contents [%s]" % (name, self.hash, len(words))) log.info("old list: %s" % self.concreteWordLists[name]) # TODO: need to check existing load state, then send a loading message here, then restore # old state. This way we can see when word lists are taking a long time to load... updateStart = time.time() self.concreteWordLists[name].set(words) updateEnd = time.time() log.info("Word list update time: %ss" % (updateEnd - updateStart))
"table row": "tr", "TR": "tr", "track": "track", "unordered list": "ul", "variable": "var", "video": "video", "label": "label", }) ] # Code for initial setup of the HTML grammar htmlBootstrap = Grammar( "html bootstrap") # Create a grammar to contain the command rule. htmlBootstrap.add_rule(HTMLEnabler()) htmlBootstrap.load() htmlGrammar = Grammar("html grammar") htmlGrammar.add_rule(HTMLTestRule()) htmlGrammar.add_rule(HTMLDisabler()) htmlGrammar.add_rule(HTMLTags()) htmlGrammar.load() htmlGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global htmlGrammar if htmlGrammar: htmlGrammar.unload() htmlGrammar = None
Function(output_value), "<type_name> [<value_name>]": Function(output_type_annotation), "<type_name> [<value_name>] is constant": Function(output_type_annotation, is_constant=True), } extras = [ Dictation("value_name", default=""), type_name_choice("type_name") ] # The main Barney grammar rules are activated here barney_bootstrap = Grammar("barney bootstrap") barney_bootstrap.add_rule(BarneyEnabler()) barney_bootstrap.load() barney_grammar = Grammar("barney grammar") barney_grammar.add_rule(BarneyUtilities()) barney_grammar.add_rule(BarneyDisabler()) barney_grammar.load() barney_grammar.disable() def unload(): global barney_grammar if barney_grammar: barney_grammar.unload() barney_grammar = None
Dictation("module_name", default=""), Dictation("alias_name", default=""), Dictation("name", default=""), Dictation("binding", default=""), Dictation("comment", default=""), gen_server_command_choice("gen_server_command"), log_level_choice("log_level"), interactive_command_choice("interactive_command"), mix_command_choice("mix_command"), comment_choice("comment_type"), ] # The main Elixir grammar rules are activated here elixirBootstrap = Grammar("elixir bootstrap") elixirBootstrap.add_rule(ElixirEnabler()) elixirBootstrap.load() elixirGrammar = Grammar("elixir grammar") elixirGrammar.add_rule(ElixirUtilities()) elixirGrammar.add_rule(ElixirDisabler()) elixirGrammar.load() elixirGrammar.disable() def unload(): global elixirGrammar if elixirGrammar: elixirGrammar.unload() elixirGrammar = None
class DictationOffRule(MappingRule): mapping = { "<text>": Function(noop), } extras = [ Dictation("text"), ] defaults = {} dictationOffGrammar = Grammar("Dictation off") dictationOffGrammar.add_rule(DictationOffRule()) dictationOffGrammar.load() dictationOffGrammar.disable() dictation_enabled = True def dictation_off(): global dictation_enabled if dictation_enabled: print "Dictation now OFF." dictation_enabled = False dictationOffGrammar.enable() else: print "Dictation already off." def dictation_on():
"<text>": Function(illegal_command), }, extras=[ IntegerRef("n", 1, 100), Dictation("text"), ], defaults={ "n": 1 } ) grammarCommand = Grammar("Vim command grammar", context=GlobalDynamicContext()) grammarCommand.add_rule(commandMode) grammarCommand.load() grammarCommand.disable() insertMode = MappingRule( mapping={ # Commands and keywords: "(command mode|press escape)": Function(enable_command_mode), }, extras=[ IntegerRef("n", 1, 100), Dictation("text"), ], defaults={ "n": 1 } )
IntegerRef("pos7", 1, 10), IntegerRef("pos8", 1, 10), IntegerRef("pos9", 1, 10), Dictation("text"), Choice("action", actions), ], defaults={ "pos1": 1 } ) # Use global context, and activate/deactivate grammar dynamically. grammarNavigation = Grammar("Grid navigation", context=GlobalDynamicContext()) grammarNavigation.add_rule(navigate_rule) # Add the top-level rule. grammarNavigation.load() # Load the grammar. grammarNavigation.disable() def mouse_grid_start(pos1=None, pos2=None, pos3=None, pos4=None, pos5=None, pos6=None, pos7=None, pos8=None, pos9=None, action=None): if should_send_to_aenea(): lib.grid_base_x.set_grammar_reference(grammarNavigation) grammarNavigation.enable() lib.grid_base_x.mouse_grid(pos1, pos2, pos3, pos4, pos5, pos6, pos7, pos8, pos9, action) else: lib.grid_base_win.set_grammar_reference(grammarNavigation) grammarNavigation.enable() lib.grid_base_win.mouse_grid(pos1, pos2, pos3, pos4, pos5, pos6, pos7, pos8, pos9, action)
mapping = { "if": Text("if condition:") + Key("enter"), "while loop": Text("while condition:") + Key("enter"), "for loop": Text("for something in something:") + Key("enter"), "function": Text("def functionName():") + Key("enter"), "class": Text("class className(inheritance):") + Key("enter"), } # The main Python grammar rules are activated here pythonBootstrap = Grammar("python bootstrap") pythonBootstrap.add_rule(PythonEnabler()) pythonBootstrap.load() pythonGrammar = Grammar("python grammar") pythonGrammar.add_rule(PythonTestRule()) pythonGrammar.add_rule(PythonCommentsSyntax()) pythonGrammar.add_rule(PythonControlStructures()) pythonGrammar.add_rule(PythonDisabler()) pythonGrammar.load() pythonGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global pythonGrammar if pythonGrammar: pythonGrammar.unload() pythonGrammar = None
"escape carriage return": Text("\ ") + Key("left") + Text("r"), } CPPBootstrap = Grammar( "C++ bootstrap") # Create a grammar to contain the command rule. CPPBootstrap.add_rule(CPPEnabler()) CPPBootstrap.load() CPPGrammar = Grammar("C++ grammar") CPPGrammar.add_rule(CPPTestRule()) CPPGrammar.add_rule(CPPControlStructures()) CPPGrammar.add_rule(CPPCommentsSyntax()) CPPGrammar.add_rule(CPPUsefulFunctions()) CPPGrammar.add_rule(CPPPreprocessorDirectives()) CPPGrammar.add_rule(CPPOperators()) CPPGrammar.add_rule(CPPEscapeSequences()) CPPGrammar.add_rule(CPPFunctionsAndClassesSyntax()) CPPGrammar.add_rule(CPPDataTypes()) CPPGrammar.add_rule(CPPDisabler()) CPPGrammar.load() CPPGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global CPPGrammar if CPPGrammar: CPPGrammar.unload() CPPGrammar = None
Function(output_index_brackets), } extras = [ Dictation("name", default=""), Dictation("binding_name", default=""), visibility_attribute_choice("visibility_attribute"), type_name_choice("type_name"), type_name_choice("type_name2"), comparison_choice("comparison"), IntegerRef("index", min=0, max=9999999999), ] go_bootstrap = Grammar("go bootstrap") go_bootstrap.add_rule(GoEnabler()) go_bootstrap.load() go_grammar = Grammar("go grammar") go_grammar.add_rule(GoUtilities()) go_grammar.add_rule(GoDisabler()) go_grammar.load() go_grammar.disable() def unload(): global go_grammar if go_grammar: go_grammar.unload() go_grammar = None
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' ), # @IgnorePep8 # if conditions. }, extras=[ IntegerRef("n", 1, 100), Dictation("text"), Choice("element", htmlElements), Choice("attribute", htmlAttributes), ], defaults={"n": 1}) terminator_grammar = Grammar("Html grammar", context=GlobalDynamicContext()) terminator_grammar.add_rule(rules) terminator_grammar.load() terminator_grammar.disable() def dynamic_enable(): global terminator_grammar if grammar.enabled: return False else: grammar.enable() return True def dynamic_disable(): global terminator_grammar if grammar.enabled: grammar.disable()
phpBootstrap = Grammar( "php bootstrap") # Create a grammar to contain the command rule. phpBootstrap.add_rule(PHPEnabler()) phpBootstrap.load() phpGrammar = Grammar("php grammar") phpGrammar.add_rule(PHPTestRule()) phpGrammar.add_rule(PHPDataTypes()) phpGrammar.add_rule(PHPVariableDeclarations()) phpGrammar.add_rule(PHPCommentsSyntax()) phpGrammar.add_rule(PHPSuperGlobals()) phpGrammar.add_rule(PHPControlStructures()) phpGrammar.add_rule(PHPAccessModifiers()) phpGrammar.add_rule(PHPUsefulMethods()) phpGrammar.add_rule(PHPLogicalOperators()) phpGrammar.add_rule(PHPAssignmentOperators()) phpGrammar.add_rule(PHPArithmeticOperators()) phpGrammar.add_rule(PHPEscapeSequences()) phpGrammar.add_rule(PHPComparisonOperators()) phpGrammar.add_rule(PHPMiscellaneousStuff()) phpGrammar.add_rule(PHPDisabler()) phpGrammar.load() phpGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global phpGrammar if phpGrammar: phpGrammar.unload() phpGrammar = None
"escape carriage return": Text("\ ")+ Key("left") + Text("r"), } # The main Java grammar rules are activated here javaBootstrap = Grammar("java bootstrap") javaBootstrap.add_rule(JavaEnabler()) javaBootstrap.load() javaGrammar = Grammar("java grammar") javaGrammar.add_rule(JavaTestRule()) javaGrammar.add_rule(JavaCommentsSyntax()) javaGrammar.add_rule(JavaDataTypes()) javaGrammar.add_rule(JavaComparisonOperators()) javaGrammar.add_rule(JavaBooleanOperators()) javaGrammar.add_rule(JavaControlStructures()) javaGrammar.add_rule(JavaUsefulMethods()) javaGrammar.add_rule(JavaArithmeticOperators()) javaGrammar.add_rule(JavaAssignmentOperators()) javaGrammar.add_rule(JavaMiscellaneousStuff()) javaGrammar.add_rule(JavaAccessModifiers()) javaGrammar.add_rule(JavaEscapeSequences()) javaGrammar.add_rule(JavaDisabler()) javaGrammar.load() javaGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global javaGrammar if javaGrammar: javaGrammar.unload() javaGrammar = None
"plus equals": Text("+="), "minus equals": Text("-="), "multiply equals": Text("*="), "divide equals": Text("/="), "modulus equals": Text("%="), } JavaScriptBootstrap = Grammar("JavaScript bootstrap") # Create a grammar to contain the command rule. JavaScriptBootstrap.add_rule(JavaScriptEnabler()) JavaScriptBootstrap.load() JavaScriptGrammar = Grammar("JavaScript grammar") JavaScriptGrammar.add_rule(JavaScriptTestRule()) JavaScriptGrammar.add_rule(JavaScriptControlStructures()) JavaScriptGrammar.add_rule(JavaScriptCommentsSyntax()) JavaScriptGrammar.add_rule(JavaScriptMiscellaneousStuff()) JavaScriptGrammar.add_rule(JavaScriptComparisonOperators()) JavaScriptGrammar.add_rule(JavaScriptArithmeticOperators()) JavaScriptGrammar.add_rule(JavaScriptAssignmentOperators()) JavaScriptGrammar.add_rule(JavaScriptDisabler()) JavaScriptGrammar.load() JavaScriptGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global JavaScriptGrammar if JavaScriptGrammar: JavaScriptGrammar.unload() JavaScriptGrammar = None
"escape single quotes": Text("\ ")+ Key("left") + Text("\'") + Text("\ ")+ Key("left") + Text("\'"), "escape line": Text("\ ")+ Key("left") + Text("n"), "escape tab": Text("\ ")+ Key("left") + Text("t"), "escape carriage return": Text("\ ")+ Key("left") + Text("r"), } CPPBootstrap = Grammar("C++ bootstrap") # Create a grammar to contain the command rule. CPPBootstrap.add_rule(CPPEnabler()) CPPBootstrap.load() CPPGrammar = Grammar("C++ grammar") CPPGrammar.add_rule(CPPTestRule()) CPPGrammar.add_rule(CPPControlStructures()) CPPGrammar.add_rule(CPPCommentsSyntax()) CPPGrammar.add_rule(CPPUsefulFunctions()) CPPGrammar.add_rule(CPPPreprocessorDirectives()) CPPGrammar.add_rule(CPPOperators()) CPPGrammar.add_rule(CPPEscapeSequences()) CPPGrammar.add_rule(CPPFunctionsAndClassesSyntax()) CPPGrammar.add_rule(CPPDataTypes()) CPPGrammar.add_rule(CPPDisabler()) CPPGrammar.load() CPPGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global CPPGrammar if CPPGrammar: CPPGrammar.unload() CPPGrammar = None
"escape carriage return": Text("\ ")+ Key("left") + Text("r"), } # The main C# grammar rules are activated here csBootstrap = Grammar("C sharp bootstrap") csBootstrap.add_rule(CSEnabler()) csBootstrap.load() csGrammar = Grammar("C sharp grammar") csGrammar.add_rule(CSTestRule()) csGrammar.add_rule(CSCommentsSyntax()) csGrammar.add_rule(CSDataTypes()) csGrammar.add_rule(CSComparisonOperators()) csGrammar.add_rule(CSBooleanOperators()) csGrammar.add_rule(CSControlStructures()) csGrammar.add_rule(CSUsefulMethods()) csGrammar.add_rule(CSArithmeticOperators()) csGrammar.add_rule(CSAssignmentOperators()) csGrammar.add_rule(CSMiscellaneousStuff()) csGrammar.add_rule(CSAccessModifiers()) csGrammar.add_rule(CSEscapeSequences()) csGrammar.add_rule(CSDisabler()) csGrammar.load() csGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global csGrammar if csGrammar: csGrammar.unload() csGrammar = None
"minus equals": Text("-="), "multiply equals": Text("*="), "divide equals": Text("/="), "modulus equals": Text("%="), } JavaScriptBootstrap = Grammar( "JavaScript bootstrap") # Create a grammar to contain the command rule. JavaScriptBootstrap.add_rule(JavaScriptEnabler()) JavaScriptBootstrap.load() JavaScriptGrammar = Grammar("JavaScript grammar") JavaScriptGrammar.add_rule(JavaScriptTestRule()) JavaScriptGrammar.add_rule(JavaScriptControlStructures()) JavaScriptGrammar.add_rule(JavaScriptCommentsSyntax()) JavaScriptGrammar.add_rule(JavaScriptMiscellaneousStuff()) JavaScriptGrammar.add_rule(JavaScriptComparisonOperators()) JavaScriptGrammar.add_rule(JavaScriptArithmeticOperators()) JavaScriptGrammar.add_rule(JavaScriptAssignmentOperators()) JavaScriptGrammar.add_rule(JavaScriptDisabler()) JavaScriptGrammar.load() JavaScriptGrammar.disable() # Unload function which will be called by natlink at unload time. def unload(): global JavaScriptGrammar if JavaScriptGrammar: JavaScriptGrammar.unload() JavaScriptGrammar = None
comparison_choice("comparison"), visibility_attribute_choice("visibility_attribute"), typecast_choice("type_choice"), calling_convention_choice("calling_convention"), library_choice("library"), IntegerRef("start", 0, 10000000), IntegerRef("end", 0, 10000000), build_target_name_choice("build_target_name"), optimization_choice("optimization"), initialization_type_choice("initialization_type"), ] # The main Zig grammar rules are activated here zigBootstrap = Grammar("zig bootstrap") zigBootstrap.add_rule(ZigEnabler()) zigBootstrap.load() zigGrammar = Grammar("zig grammar") zigGrammar.add_rule(ZigUtilities()) zigGrammar.add_rule(ZigDisabler()) zigGrammar.load() zigGrammar.disable() def unload(): global zigGrammar if zigGrammar: zigGrammar.unload() zigGrammar = None
"S Q lite 3": Text("sqlite3"), "subprocess": Text("subprocess"), }, extras=[ IntegerRef("n", 1, 100), Dictation("text"), ], defaults={ "n": 1 } ) grammar = Grammar("Python grammar") grammar.add_rule(rules) grammar.load() grammar.disable() def dynamic_enable(): global grammar if grammar.enabled: return False else: grammar.enable() return True def dynamic_disable(): global grammar if grammar.enabled: grammar.disable()
extras = [ Dictation("name", default=""), Dictation("function_name", default=""), Dictation("import_name", default=""), Dictation("type_name", default=""), Dictation("comment", default=""), visibility_attribute_choice("visibility_attribute"), comparison_choice("comparison"), comment_choice("comment_type"), ] # The main Typescript grammar rules are activated here typescriptBootstrap = Grammar("typescript bootstrap") typescriptBootstrap.add_rule(TypescriptEnabler()) typescriptBootstrap.load() typescriptGrammar = Grammar("typescript grammar") typescriptGrammar.add_rule(TypescriptUtilities()) typescriptGrammar.add_rule(TypescriptDisabler()) typescriptGrammar.load() typescriptGrammar.disable() def unload(): global typescriptGrammar if typescriptGrammar: typescriptGrammar.unload() typescriptGrammar = None
Choice("hex1", hexValue), Choice("hex2", hexValue), Choice("hex3", hexValue), Choice("hex4", hexValue), Choice("hex5", hexValue), Choice("hex6", hexValue), ], defaults={ "n": 0 } ) grammar = Grammar("Css grammar", context=GlobalDynamicContext()) grammar.add_rule(rules) grammar.load() grammar.disable() def dynamic_enable(): global grammar if grammar.enabled: return False else: grammar.enable() return True def dynamic_disable(): global grammar if grammar.enabled: grammar.disable()
Function(enable_command_mode) + Key("u"), "yank [(line|lines)]": Key("d, d"), "<text>": Function(illegal_command), }, extras=[ IntegerRef("n", 1, 100), Dictation("text"), ], defaults={"n": 1}) grammarCommand = Grammar("Vim command grammar", context=GlobalDynamicContext()) grammarCommand.add_rule(commandMode) grammarCommand.load() grammarCommand.disable() insertMode = MappingRule( mapping={ # Commands and keywords: "(command mode|press escape)": Function(enable_command_mode), }, extras=[ IntegerRef("n", 1, 100), Dictation("text"), ], defaults={"n": 1}) grammarInsert = Grammar("Vim insert grammar", context=GlobalDynamicContext()) grammarInsert.add_rule(insertMode) grammarInsert.load()