From 5364b18dc355bfb3ee7cc9817bbe18c1df8f78ee Mon Sep 17 00:00:00 2001 From: "Walk H. Admin" Date: Mon, 6 Mar 2017 00:02:06 -0600 Subject: [PATCH 01/14] Made two fixes to history.py, one to handle sequences with slashes and the other to remove Unicode characters when naming the sequence. --- caster/lib/ccr/recording/history.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/caster/lib/ccr/recording/history.py b/caster/lib/ccr/recording/history.py index 65050d98c..a165ef707 100644 --- a/caster/lib/ccr/recording/history.py +++ b/caster/lib/ccr/recording/history.py @@ -46,7 +46,8 @@ def add_recorded_macro(self, data): word_sequences = [] # word_sequences is a list of lists of strings for i in data["selected_indices"]: - single_sequence = self.nexus.preserved[i] + # Convert from a tuple to a list because we may need to modify it. + single_sequence = list(self.nexus.preserved[i]) # clean the results for k in range(0,len(single_sequence)): if "\\" in single_sequence[k]: @@ -72,8 +73,14 @@ def refresh(self, *args): utilities.save_json_file(recorded_macros, settings.SETTINGS["paths"]["RECORDED_MACROS_PATH"]) mapping = {} for spec in recorded_macros: + # Create a copy of the string without Unicode characters. + ascii_str = str(spec) sequences = recorded_macros[spec] - mapping[spec] = R(Playback([(sequence, 0.0) for sequence in sequences])*Repeat(extra="n"), rdescript="Recorded Macro: "+spec) + # It appears that the associative string (ascii_str) must be ascii, but the sequences within Playback must be Unicode. + # Further, I changed the delay from 0.0 to 1.0. The delay of 0.0 generally did not work for me. We may want to consider + # exposing this as a configurable setting. + mapping[ascii_str] = R(Playback([(sequence, 1.0) for sequence in sequences]), rdescript="Recorded Macro: " + ascii_str) + print("14.") mapping["record from history"] = R(Function(self.record_from_history), rdescript="Record From History") mapping["delete recorded macros"] = R(Function(self.delete_recorded_macros), rdescript="Delete Recorded Macros") # reload with new mapping From f53508d18b7c3e022697a2c723aa2b8be1a26878 Mon Sep 17 00:00:00 2001 From: "Walk H. Admin" Date: Mon, 6 Mar 2017 00:14:22 -0600 Subject: [PATCH 02/14] Removed a lingering debug statement. --- caster/lib/ccr/recording/history.py | 1 - 1 file changed, 1 deletion(-) diff --git a/caster/lib/ccr/recording/history.py b/caster/lib/ccr/recording/history.py index a165ef707..72e8e0faf 100644 --- a/caster/lib/ccr/recording/history.py +++ b/caster/lib/ccr/recording/history.py @@ -80,7 +80,6 @@ def refresh(self, *args): # Further, I changed the delay from 0.0 to 1.0. The delay of 0.0 generally did not work for me. We may want to consider # exposing this as a configurable setting. mapping[ascii_str] = R(Playback([(sequence, 1.0) for sequence in sequences]), rdescript="Recorded Macro: " + ascii_str) - print("14.") mapping["record from history"] = R(Function(self.record_from_history), rdescript="Record From History") mapping["delete recorded macros"] = R(Function(self.delete_recorded_macros), rdescript="Delete Recorded Macros") # reload with new mapping From 749ff5db4827e9a4ffb1fa09a52fe3daaf78400e Mon Sep 17 00:00:00 2001 From: "Walk H. Admin" Date: Fri, 10 Mar 2017 09:11:00 -0600 Subject: [PATCH 03/14] Added a setting for the delay when playing back a recorded history. --- caster/lib/ccr/recording/history.py | 5 ++--- caster/lib/settings.py | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/caster/lib/ccr/recording/history.py b/caster/lib/ccr/recording/history.py index 72e8e0faf..811ccf468 100644 --- a/caster/lib/ccr/recording/history.py +++ b/caster/lib/ccr/recording/history.py @@ -76,10 +76,9 @@ def refresh(self, *args): # Create a copy of the string without Unicode characters. ascii_str = str(spec) sequences = recorded_macros[spec] + delay = settings.SETTINGS["miscellaneous"]["history_playback_delay_secs"] # It appears that the associative string (ascii_str) must be ascii, but the sequences within Playback must be Unicode. - # Further, I changed the delay from 0.0 to 1.0. The delay of 0.0 generally did not work for me. We may want to consider - # exposing this as a configurable setting. - mapping[ascii_str] = R(Playback([(sequence, 1.0) for sequence in sequences]), rdescript="Recorded Macro: " + ascii_str) + mapping[ascii_str] = R(Playback([(sequence, delay) for sequence in sequences]), rdescript="Recorded Macro: " + ascii_str) mapping["record from history"] = R(Function(self.record_from_history), rdescript="Record From History") mapping["delete recorded macros"] = R(Function(self.delete_recorded_macros), rdescript="Delete Recorded Macros") # reload with new mapping diff --git a/caster/lib/settings.py b/caster/lib/settings.py index 4574baef0..d813664c8 100644 --- a/caster/lib/settings.py +++ b/caster/lib/settings.py @@ -212,7 +212,8 @@ def init_default_values(): ("rdp_mode", False), ("integer_remap_opt_in", False), ("integer_remap_crash_fix", False), - ("print_rdescripts", False) + ("print_rdescripts", False), + ("history_playback_delay_secs", 1.0) ]) # pronunciations section From b90b583562ad90a16a0f11a5520e8fae462dc2f3 Mon Sep 17 00:00:00 2001 From: Logan Girard Date: Fri, 10 Nov 2017 14:04:58 -0800 Subject: [PATCH 04/14] fixing lambda in c sharp --- caster/lib/ccr/csharp/csharp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/caster/lib/ccr/csharp/csharp.py b/caster/lib/ccr/csharp/csharp.py index 17a04ffb8..d350e5e68 100644 --- a/caster/lib/ccr/csharp/csharp.py +++ b/caster/lib/ccr/csharp/csharp.py @@ -75,7 +75,7 @@ class CSharp(MergeRule): "array": R(Mimic("brackets"), rdescript="C#: Array"), "list": R(Text("List<>")+Key("left"), rdescript="C# List"), "var": R(Text("var TOKEN = TOKEN;"), rdescript="C# variable"), - "(lambda|goes to)": R(Text("->"), rdescript="C#: lambda"), + "(lambda|goes to)": R(Text("=>"), rdescript="C#: lambda"), From 73c1e1cfa10d8c21bc48b29889640b405d51e52e Mon Sep 17 00:00:00 2001 From: Logan Girard Date: Fri, 10 Nov 2017 19:28:27 -0800 Subject: [PATCH 05/14] add build and test commands to Visual Studio --- caster/apps/visualstudio.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/caster/apps/visualstudio.py b/caster/apps/visualstudio.py index d34ffab7a..06994bb85 100644 --- a/caster/apps/visualstudio.py +++ b/caster/apps/visualstudio.py @@ -15,16 +15,16 @@ class VisualStudioRule(MergeRule): "next tab []": R(Key("ca-pgdown"), rdescript="Visual Studio: Next Tab") * Repeat(extra="n"), "prior tab []": R(Key("ca-pgup"), rdescript="Visual Studio: Previous Tab") * Repeat(extra="n"), "close tab []": R(Key("c-f4/20"), rdescript="Visual Studio: Close Tab") * Repeat(extra="n"), - + "(list | show) documents": R(Key("a-w, w"), rdescript="Visual Studio: List Documents"), "[focus] document (window | pane)": R(Key("a-w, w, enter"), rdescript="Visual Studio: Focus Document Pane"), "solution explorer": R(Key("ca-l"), rdescript="Visual Studio: Solution Explorer"), "team explorer": R(Key("c-backslash, c-m"), rdescript="Visual Studio: Team Explorer"), "source control explorer": R(Key("c-q") + Text("Source Control Explorer") + Key("enter"), rdescript="Visual Studio: Source Control Explorer"), - + "quick launch": R(Key("c-q"), rdescript="Visual Studio: Quick Launch"), "go to line": R(Key("c-g"), rdescript="Visual Studio: Go To Line"), - + "comment line": R(Key("c-k, c-c"), rdescript="Visual Studio: Comment Selection"), "comment block": R(Key("c-k, c-c"), rdescript="Visual Studio: Comment Block"), "(un | on) comment line": R(Key("c-k/50, c-u"), rdescript="Visual Studio: Uncomment Selection"), @@ -36,18 +36,23 @@ class VisualStudioRule(MergeRule): "collapse to definitions": R(Key("c-m, c-o"), rdescript="Visual Studio: Collapse To Definitions"), "toggle [section] outlining": R(Key("c-m, c-m"), rdescript="Visual Studio: Toggle Section Outlining"), "toggle all outlining": R(Key("c-m, c-l"), rdescript="Visual Studio: Toggle All Outlining"), - + "[toggle] breakpoint": R(Key("f9"), rdescript="Visual Studio: Breakpoint"), "step over []": R(Key("f10/50") * Repeat(extra="n"), rdescript="Visual Studio: Step Over"), "step into": R(Key("f11"), rdescript="Visual Studio: Step Into"), "step out [of]": R(Key("s-f11"), rdescript="Visual Studio: Step Out"), "resume": R(Key("f5"), rdescript="Visual Studio: Resume"), - + + "run tests": R(Key("c-r, t"), rdescript="Visual Studio: Run test(s)"), + "run all tests": R(Key("c-r, a"), rdescript="Visual Studio: Run all tests"), + + "build solution": R(Key("cs-b"), rdescript="Visual Studio: Build solution"), + "get latest [version]": R(Key("a-f, r, l"), rdescript="Visual Studio: Get Latest"), "(show | view) history": R(Key("a-f, r, h"), rdescript="Visual Studio: Show History"), "compare (files | versions)": R(Key("a-f, r, h"), rdescript="Visual Studio: Compare..."), "undo (checkout | pending changes)": R(Key("a-f, r, u"), rdescript="Visual Studio: Undo Pending Changes"), - + "[open] [go to] work item": R(Key("a-m, g"), rdescript="Visual Studio: Open Work Item"), "[add] [new] linked work item": R(Key("sa-l"), rdescript="Visual Studio: New Linked Work Item"), } From ff4b2a0d377cd16470b701cd18262c45ced79dd7 Mon Sep 17 00:00:00 2001 From: Jacques Favreau Date: Sat, 18 Nov 2017 14:48:02 -0800 Subject: [PATCH 06/14] Removes the try/catch around startup. --- _caster.py | 70 +++++++++++++++++++++++------------------------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/_caster.py b/_caster.py index 94a74c3e8..84c9b8e81 100644 --- a/_caster.py +++ b/_caster.py @@ -24,46 +24,36 @@ def _wait_for_wsr_activation(): _NEXUS = None -try: - from caster.lib import settings# requires nothing - settings.WSR = __name__ == "__main__" - from caster.lib import utilities# requires settings - if settings.WSR: - _wait_for_wsr_activation() - SymbolSpecs.set_cancel_word("escape") - from caster.lib import control - _NEXUS = control.nexus() - - from caster.apps import * - from caster.asynch import * - from caster.lib import context - import caster.lib.dev.dev - from caster.asynch.sikuli import sikuli - from caster.lib import navigation - navigation.initialize_clipboard(_NEXUS) - from caster.lib.dfplus.state.short import R - from caster.lib.dfplus.additions import IntegerRefST - - from caster.lib.dfplus.merge.mergepair import MergeInf - from caster.lib.ccr import * - from caster.lib.ccr.recording.again import Again - from caster.lib.ccr.recording.alias import VanillaAlias - from caster.lib.ccr.recording import history - from caster.lib.dev import dev - from caster.lib.dfplus.hint.nodes import css - from caster.user.filters.examples import scen4, modkeysup - from caster import user - from caster.lib.dfplus.merge.mergerule import MergeRule - from caster.lib.dfplus.merge import gfilter - -except: - print("\nAttempting to load CCR anyway...") - from caster.lib import utilities - from caster.lib import control - _NEXUS = control.nexus() - - utilities.simple_log() - +from caster.lib import settings# requires nothing +settings.WSR = __name__ == "__main__" +from caster.lib import utilities# requires settings +if settings.WSR: + _wait_for_wsr_activation() + SymbolSpecs.set_cancel_word("escape") +from caster.lib import control +_NEXUS = control.nexus() + +from caster.apps import * +from caster.asynch import * +from caster.lib import context +import caster.lib.dev.dev +from caster.asynch.sikuli import sikuli +from caster.lib import navigation +navigation.initialize_clipboard(_NEXUS) +from caster.lib.dfplus.state.short import R +from caster.lib.dfplus.additions import IntegerRefST + +from caster.lib.dfplus.merge.mergepair import MergeInf +from caster.lib.ccr import * +from caster.lib.ccr.recording.again import Again +from caster.lib.ccr.recording.alias import VanillaAlias +from caster.lib.ccr.recording import history +from caster.lib.dev import dev +from caster.lib.dfplus.hint.nodes import css +from caster.user.filters.examples import scen4, modkeysup +from caster import user +from caster.lib.dfplus.merge.mergerule import MergeRule +from caster.lib.dfplus.merge import gfilter From 895a5ca9d02cba4afae0377aab7b36ae8e595e2b Mon Sep 17 00:00:00 2001 From: Jacques Favreau Date: Mon, 20 Nov 2017 13:11:47 -0800 Subject: [PATCH 07/14] Add .gitattributes file --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..333f6a17d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto \ No newline at end of file From 63e33e51fd1f9c0008b51f32b4a7dfd40cd17b94 Mon Sep 17 00:00:00 2001 From: Jacques Favreau Date: Mon, 20 Nov 2017 23:03:46 -0800 Subject: [PATCH 08/14] Fix existing files with CRLF encoding. --- caster/apps/explorer.py | 80 ++++---- caster/apps/foxitreader.py | 74 ++++---- caster/doc/CONTRIBUTING.md | 98 +++++----- .../readthedocs/examples/Rule Construction.MD | 6 +- .../examples/rules/Old Sample File.MD | 178 +++++++++--------- 5 files changed, 218 insertions(+), 218 deletions(-) diff --git a/caster/apps/explorer.py b/caster/apps/explorer.py index 03c2e2654..dc5f51c0a 100644 --- a/caster/apps/explorer.py +++ b/caster/apps/explorer.py @@ -1,41 +1,41 @@ -from dragonfly import (Grammar, AppContext, MappingRule, - Dictation, IntegerRef, - Key, Text, Repeat, Pause) - -from caster.lib import control -from caster.lib import settings -from caster.lib.dfplus.additions import IntegerRefST -from caster.lib.dfplus.merge import gfilter -from caster.lib.dfplus.merge.mergerule import MergeRule -from caster.lib.dfplus.state.short import R - - -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"), - } - extras = [ - Dictation("text"), - IntegerRefST("n", 1, 1000), - - ] - defaults = {"n": 1} - -#--------------------------------------------------------------------------- - -context = AppContext(executable="explorer") -grammar = Grammar("Windows Explorer", context=context) - -if settings.SETTINGS["apps"]["explorer"]: - if settings.SETTINGS["miscellaneous"]["rdp_mode"]: - control.nexus().merger.add_global_rule(IERule()) - else: - rule = IERule(name="explorer") - gfilter.run_on(rule) - grammar.add_rule(rule) +from dragonfly import (Grammar, AppContext, MappingRule, + Dictation, IntegerRef, + Key, Text, Repeat, Pause) + +from caster.lib import control +from caster.lib import settings +from caster.lib.dfplus.additions import IntegerRefST +from caster.lib.dfplus.merge import gfilter +from caster.lib.dfplus.merge.mergerule import MergeRule +from caster.lib.dfplus.state.short import R + + +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"), + } + extras = [ + Dictation("text"), + IntegerRefST("n", 1, 1000), + + ] + defaults = {"n": 1} + +#--------------------------------------------------------------------------- + +context = AppContext(executable="explorer") +grammar = Grammar("Windows Explorer", context=context) + +if settings.SETTINGS["apps"]["explorer"]: + if settings.SETTINGS["miscellaneous"]["rdp_mode"]: + control.nexus().merger.add_global_rule(IERule()) + else: + rule = IERule(name="explorer") + gfilter.run_on(rule) + grammar.add_rule(rule) grammar.load() \ No newline at end of file diff --git a/caster/apps/foxitreader.py b/caster/apps/foxitreader.py index 1ae0790bf..f49ad1cd4 100644 --- a/caster/apps/foxitreader.py +++ b/caster/apps/foxitreader.py @@ -1,38 +1,38 @@ -from dragonfly import (Grammar, AppContext, Dictation, Key, Repeat) - -from caster.lib import control -from caster.lib import settings -from caster.lib.dfplus.additions import IntegerRefST -from caster.lib.dfplus.merge import gfilter -from caster.lib.dfplus.merge.mergerule import MergeRule -from caster.lib.dfplus.state.short import R - - -class FoxitRule(MergeRule): - pronunciation = "fox it reader" - - mapping = { - "next tab []": R(Key("c-tab"), rdescript="Foxit Reader: Next Tab") * Repeat(extra="n"), - "prior tab []": R(Key("cs-tab"), rdescript="Foxit Reader: Previous Tab") * Repeat(extra="n"), - "close tab []": R(Key("c-f4/20"), rdescript="Foxit Reader: Close Tab") * Repeat(extra="n"), - } - extras = [ - Dictation("text"), - Dictation("mim"), - IntegerRefST("n", 1, 1000), - ] - defaults = {"n": 1, "mim":""} - -#--------------------------------------------------------------------------- - -context = AppContext(executable="Foxit Reader") -grammar = Grammar("Foxit Reader", context=context) - -if settings.SETTINGS["apps"]["foxitreader"]: - if settings.SETTINGS["miscellaneous"]["rdp_mode"]: - control.nexus().merger.add_global_rule(FoxitRule()) - else: - rule = FoxitRule(name="Foxit Reader") - gfilter.run_on(rule) - grammar.add_rule(rule) +from dragonfly import (Grammar, AppContext, Dictation, Key, Repeat) + +from caster.lib import control +from caster.lib import settings +from caster.lib.dfplus.additions import IntegerRefST +from caster.lib.dfplus.merge import gfilter +from caster.lib.dfplus.merge.mergerule import MergeRule +from caster.lib.dfplus.state.short import R + + +class FoxitRule(MergeRule): + pronunciation = "fox it reader" + + mapping = { + "next tab []": R(Key("c-tab"), rdescript="Foxit Reader: Next Tab") * Repeat(extra="n"), + "prior tab []": R(Key("cs-tab"), rdescript="Foxit Reader: Previous Tab") * Repeat(extra="n"), + "close tab []": R(Key("c-f4/20"), rdescript="Foxit Reader: Close Tab") * Repeat(extra="n"), + } + extras = [ + Dictation("text"), + Dictation("mim"), + IntegerRefST("n", 1, 1000), + ] + defaults = {"n": 1, "mim":""} + +#--------------------------------------------------------------------------- + +context = AppContext(executable="Foxit Reader") +grammar = Grammar("Foxit Reader", context=context) + +if settings.SETTINGS["apps"]["foxitreader"]: + if settings.SETTINGS["miscellaneous"]["rdp_mode"]: + control.nexus().merger.add_global_rule(FoxitRule()) + else: + rule = FoxitRule(name="Foxit Reader") + gfilter.run_on(rule) + grammar.add_rule(rule) grammar.load() \ No newline at end of file diff --git a/caster/doc/CONTRIBUTING.md b/caster/doc/CONTRIBUTING.md index 9c3952c78..6c93cd6e9 100644 --- a/caster/doc/CONTRIBUTING.md +++ b/caster/doc/CONTRIBUTING.md @@ -1,49 +1,49 @@ -# Contributing - -*How can I help?* - -1. **Write code.** There is [a lot which needs to be done](https://github.com/synkarius/caster/issues). If you can program in Python, please write some code. Note that all pull requests should be sent to the "develop" branch (see the [Caster GitHub Workflow](#caster-github-workflow) section below). -2. **Write documentation.** The [ReadTheDocs page](http://caster.readthedocs.org/en/latest/) is pretty sparse. (Everything on [the wiki](https://github.com/synkarius/caster/wiki) will be getting moved to the ReadTheDocs, so create new docs as .MD files.) -3. **Speak.** Tell others who might be interested in Caster. Join our discussions on the issues page and [Gitter](https://gitter.im/synkarius/caster). The more the merrier, and your thoughts are welcome and encouraged. - - -## Caster GitHub Workflow - -Pull requests for Caster need to be submitted against the `develop` branch, which requires a slightly modified workflow from PRs submitted against a repository's `main` branch. It is recommended that you review one of the many online tutorials (for example, [this one](http://yangsu.github.io/pull-request-tutorial/)) to familiarize yourself with the standard GitHub workflow. - -This guide assumes that you have already forked the Caster repository, cloned your copy locally, and setup a remote pointing to the upstream (synkarius) repository. This setup process is identical to the standard workflow, covered [here](https://help.github.com/articles/fork-a-repo/), but essentially consists of creating a fork on GitHub, followed by something like the following sequence of commands to make a local copy of the repository and link it back to the upstream (synkarius) fork: - - cd C:\MyProjects - git clone https://github.com/{YOUR-USER-NAME}/caster/ - cd caster - git remote add upstream https://github.com/synkarius/caster/ - - -### Prepare a feature branch for your pull request - -Fetch the latest from the upstream (synkarius) repo: - - git fetch upstream - -Create a new branch for your PR: - - git checkout --no-track -b pr-feature-name upstream/develop - -Where **`pr-feature-name`** is the name you want to give to your new feature branch. - - -### Make your changes and commit them to your PR branch: - - edit somefile.txt - edit anotherfile.cpp - git commit -a -m "Made some changes..." - - -### Push your PR branch up to your GitHub fork: - - git push origin pr-feature-name - - -### Open a pull request - -When you navigate to your fork on GitHub, you will be asked if you want to open a pull request for the branch you just pushed. Click the button to open a new pull request, enter a title and description for the PR, and make sure you select the `develop` branch on the base (synkarius) fork. +# Contributing + +*How can I help?* + +1. **Write code.** There is [a lot which needs to be done](https://github.com/synkarius/caster/issues). If you can program in Python, please write some code. Note that all pull requests should be sent to the "develop" branch (see the [Caster GitHub Workflow](#caster-github-workflow) section below). +2. **Write documentation.** The [ReadTheDocs page](http://caster.readthedocs.org/en/latest/) is pretty sparse. (Everything on [the wiki](https://github.com/synkarius/caster/wiki) will be getting moved to the ReadTheDocs, so create new docs as .MD files.) +3. **Speak.** Tell others who might be interested in Caster. Join our discussions on the issues page and [Gitter](https://gitter.im/synkarius/caster). The more the merrier, and your thoughts are welcome and encouraged. + + +## Caster GitHub Workflow + +Pull requests for Caster need to be submitted against the `develop` branch, which requires a slightly modified workflow from PRs submitted against a repository's `main` branch. It is recommended that you review one of the many online tutorials (for example, [this one](http://yangsu.github.io/pull-request-tutorial/)) to familiarize yourself with the standard GitHub workflow. + +This guide assumes that you have already forked the Caster repository, cloned your copy locally, and setup a remote pointing to the upstream (synkarius) repository. This setup process is identical to the standard workflow, covered [here](https://help.github.com/articles/fork-a-repo/), but essentially consists of creating a fork on GitHub, followed by something like the following sequence of commands to make a local copy of the repository and link it back to the upstream (synkarius) fork: + + cd C:\MyProjects + git clone https://github.com/{YOUR-USER-NAME}/caster/ + cd caster + git remote add upstream https://github.com/synkarius/caster/ + + +### Prepare a feature branch for your pull request + +Fetch the latest from the upstream (synkarius) repo: + + git fetch upstream + +Create a new branch for your PR: + + git checkout --no-track -b pr-feature-name upstream/develop + +Where **`pr-feature-name`** is the name you want to give to your new feature branch. + + +### Make your changes and commit them to your PR branch: + + edit somefile.txt + edit anotherfile.cpp + git commit -a -m "Made some changes..." + + +### Push your PR branch up to your GitHub fork: + + git push origin pr-feature-name + + +### Open a pull request + +When you navigate to your fork on GitHub, you will be asked if you want to open a pull request for the branch you just pushed. Click the button to open a new pull request, enter a title and description for the PR, and make sure you select the `develop` branch on the base (synkarius) fork. diff --git a/caster/doc/readthedocs/examples/Rule Construction.MD b/caster/doc/readthedocs/examples/Rule Construction.MD index c37a1fd7a..8e578fff7 100644 --- a/caster/doc/readthedocs/examples/Rule Construction.MD +++ b/caster/doc/readthedocs/examples/Rule Construction.MD @@ -1,3 +1,3 @@ -#Rule Construction - -This section discusses how to get started making Dragonfly and Caster rules. +#Rule Construction + +This section discusses how to get started making Dragonfly and Caster rules. diff --git a/caster/doc/readthedocs/examples/rules/Old Sample File.MD b/caster/doc/readthedocs/examples/rules/Old Sample File.MD index e7ecfecae..1ab69dcae 100644 --- a/caster/doc/readthedocs/examples/rules/Old Sample File.MD +++ b/caster/doc/readthedocs/examples/rules/Old Sample File.MD @@ -1,89 +1,89 @@ -#Sample.py - -This is the old complete sample python rule file. The comments explain a lot of things which beginners might struggle with. - -``` -# These lines that start with the # are called comments. They don't affect the way the code runs. -# In this tutorial file, I put comments above the relevant lines. - - -# Before we begin, it's worth noting that the name of this file, sample.py, will cause it to never run. -# You will have to rename it to "_sample.py". -# Putting an underscore as the first character of a grammar Python file will tell dragonfly -# that you want this file to run all the time. Grammars that run all the time are good way to start. -# The alternative is making grammars for specific programs that only trigger when the programs are active. - - - -# You can skip down to the next comment, none of this stuff is really important... - -from dragonfly import (BringApp, Key, Function, Grammar, Playback, - IntegerRef, Dictation, Choice, WaitWindow, MappingRule, Text) - -def my_function(n, text): - print("put some Python logic here: "+str(text)) - -class MainRule(MappingRule): - - - mapping = { - # it is this section that you want to fiddle around with if you're new: mapping, extras, and defaults - - - # in the next line, there are two things to observe: - # the first is the use of parentheses and the pipe symbol (|) - # --this lets me use either "lock dragon" or "deactivate" to trigger that command. - # The next is the playback action, which lets me tell Dragon to simulate me speaking some words. - '(lock Dragon | deactivate)': Playback([(["go", "to", "sleep"], 0.0)]), - - # Here I'm using BringApp-- this is the same as typing what goes in between the parentheses - # into the Windows command prompt, without the quotes and commas, like: - # explorer C:\NatLink\NatLink\MacroSystem - # -- (which would open Windows Explorer at the specified location). Anything you can do with the command line can be done this way - # IMPORTANT: If you don't have Dragonfly 6.6 or later, lines 40 and 46 will cause this file to crash and should be commented out - "open natlink folder": BringApp("explorer", r"C:\NatLink\NatLink\MacroSystem"), - - # here I'm using the Key action to press some keys -- see the documentation here: http://dragonfly.readthedocs.org/en/latest/actions.html?highlight=key#module-dragonfly.actions.action_key - "remax": Key("a-space/10,r/10,a-space/10,x"), - - # here I'm chaining a bunch of different actions together to do a complex task - "(show | open) documentation": BringApp('C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe') + WaitWindow(executable="chrome.exe") + Key('c-t') + WaitWindow(title="New Tab") + Text('http://dragonfly.readthedocs.org/en/latest') + Key('enter'), - - # here I'm just saying one word to trigger some other words - "hotel": Text("hotels are not cheap"), - - # If you need to do more complicated tasks, or use external resources, a function might be what you need. - # note that here, I'm using extras: "n" and "text" - # The angle brackets <> meaning I'm using an extra, and the square brackets [] mean that I don't have to speak that word, it's optional. - # Advice: if you use an optional extra, like I am with "text", you should set a default value in the defaults section down below. - # To trigger the following command, you would have to say the word "function" followed by a number between 1 and 1000. - '[use] function []': Function(my_function, extra={'n', 'text'}), - - - - } - extras = [ - IntegerRef("n", 1, 1000), - Dictation("text"), - Choice("choice", - {"alarm": "alarm", "custom grid": "CustomGrid", "element": "e" - }), - ] - defaults = {"n": 1, - "text": "", - } - -# this stuff is required too-- where I have the word "sample" below, each grammar file should have external unique -grammar = Grammar('sample') -grammar.add_rule(MainRule()) -grammar.load() - -if __name__ == "__main__": - import pythoncom, time - # Ignore this if you're using Dragon - print("Windows Speech Recognition / Dragonfly Test Running...") - while True: - pythoncom.PumpWaitingMessages() # @UndefinedVariable - time.sleep(.1) - -``` +#Sample.py + +This is the old complete sample python rule file. The comments explain a lot of things which beginners might struggle with. + +``` +# These lines that start with the # are called comments. They don't affect the way the code runs. +# In this tutorial file, I put comments above the relevant lines. + + +# Before we begin, it's worth noting that the name of this file, sample.py, will cause it to never run. +# You will have to rename it to "_sample.py". +# Putting an underscore as the first character of a grammar Python file will tell dragonfly +# that you want this file to run all the time. Grammars that run all the time are good way to start. +# The alternative is making grammars for specific programs that only trigger when the programs are active. + + + +# You can skip down to the next comment, none of this stuff is really important... + +from dragonfly import (BringApp, Key, Function, Grammar, Playback, + IntegerRef, Dictation, Choice, WaitWindow, MappingRule, Text) + +def my_function(n, text): + print("put some Python logic here: "+str(text)) + +class MainRule(MappingRule): + + + mapping = { + # it is this section that you want to fiddle around with if you're new: mapping, extras, and defaults + + + # in the next line, there are two things to observe: + # the first is the use of parentheses and the pipe symbol (|) + # --this lets me use either "lock dragon" or "deactivate" to trigger that command. + # The next is the playback action, which lets me tell Dragon to simulate me speaking some words. + '(lock Dragon | deactivate)': Playback([(["go", "to", "sleep"], 0.0)]), + + # Here I'm using BringApp-- this is the same as typing what goes in between the parentheses + # into the Windows command prompt, without the quotes and commas, like: + # explorer C:\NatLink\NatLink\MacroSystem + # -- (which would open Windows Explorer at the specified location). Anything you can do with the command line can be done this way + # IMPORTANT: If you don't have Dragonfly 6.6 or later, lines 40 and 46 will cause this file to crash and should be commented out + "open natlink folder": BringApp("explorer", r"C:\NatLink\NatLink\MacroSystem"), + + # here I'm using the Key action to press some keys -- see the documentation here: http://dragonfly.readthedocs.org/en/latest/actions.html?highlight=key#module-dragonfly.actions.action_key + "remax": Key("a-space/10,r/10,a-space/10,x"), + + # here I'm chaining a bunch of different actions together to do a complex task + "(show | open) documentation": BringApp('C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe') + WaitWindow(executable="chrome.exe") + Key('c-t') + WaitWindow(title="New Tab") + Text('http://dragonfly.readthedocs.org/en/latest') + Key('enter'), + + # here I'm just saying one word to trigger some other words + "hotel": Text("hotels are not cheap"), + + # If you need to do more complicated tasks, or use external resources, a function might be what you need. + # note that here, I'm using extras: "n" and "text" + # The angle brackets <> meaning I'm using an extra, and the square brackets [] mean that I don't have to speak that word, it's optional. + # Advice: if you use an optional extra, like I am with "text", you should set a default value in the defaults section down below. + # To trigger the following command, you would have to say the word "function" followed by a number between 1 and 1000. + '[use] function []': Function(my_function, extra={'n', 'text'}), + + + + } + extras = [ + IntegerRef("n", 1, 1000), + Dictation("text"), + Choice("choice", + {"alarm": "alarm", "custom grid": "CustomGrid", "element": "e" + }), + ] + defaults = {"n": 1, + "text": "", + } + +# this stuff is required too-- where I have the word "sample" below, each grammar file should have external unique +grammar = Grammar('sample') +grammar.add_rule(MainRule()) +grammar.load() + +if __name__ == "__main__": + import pythoncom, time + # Ignore this if you're using Dragon + print("Windows Speech Recognition / Dragonfly Test Running...") + while True: + pythoncom.PumpWaitingMessages() # @UndefinedVariable + time.sleep(.1) + +``` From 96f8525d430b7e8d5b9e2e6f3f9382de9a0d3b67 Mon Sep 17 00:00:00 2001 From: Jacques Favreau Date: Tue, 21 Nov 2017 14:55:55 -0800 Subject: [PATCH 09/14] Change get_name to get_pronunciation to clarify what's being used. --- caster/apps/eclipse.py | 2 +- caster/apps/flashdevelop.py | 2 +- .../readthedocs/examples/rules/Caster Rules.MD | 6 +++--- caster/lib/dfplus/hint/hintnode.py | 2 +- caster/lib/dfplus/merge/ccrmerger.py | 16 ++++++++-------- caster/lib/dfplus/merge/mergerule.py | 8 ++++---- caster/lib/tests/complexity.py | 2 +- caster/lib/tests/unit/merger.py | 2 +- caster/user/filters/examples/modkeysup.py | 2 +- caster/user/filters/examples/scen4.py | 6 +++--- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/caster/apps/eclipse.py b/caster/apps/eclipse.py index fbca431d5..409c319c2 100644 --- a/caster/apps/eclipse.py +++ b/caster/apps/eclipse.py @@ -170,7 +170,7 @@ class EclipseRule(MergeRule): class EclipseCCR(MergeRule): pronunciation = "eclipse jump" - mwith = [Navigation().get_name()] + mwith = [Navigation().get_pronunciation()] mapping = { #Line Ops diff --git a/caster/apps/flashdevelop.py b/caster/apps/flashdevelop.py index bf04dde26..974b3eb39 100644 --- a/caster/apps/flashdevelop.py +++ b/caster/apps/flashdevelop.py @@ -57,7 +57,7 @@ class FlashDevelopRule(MergeRule): class FlashDevelopCCR(MergeRule): pronunciation = "flash develop test" - mwith = [Navigation().get_name()] + mwith = [Navigation().get_pronunciation()] mapping = { "[go to] line ": R(Key("c-g") + Pause("50") + Text("%(n)d") + Key("enter"), diff --git a/caster/doc/readthedocs/examples/rules/Caster Rules.MD b/caster/doc/readthedocs/examples/rules/Caster Rules.MD index 387e892d2..5a9791f96 100644 --- a/caster/doc/readthedocs/examples/rules/Caster Rules.MD +++ b/caster/doc/readthedocs/examples/rules/Caster Rules.MD @@ -341,9 +341,9 @@ def update_python(rule): def replace_python_else_action(mp): if mp.time == MergeInf.RUN and mp.type == MergeInf.GLOBAL: - if mp.rule1 is not None and mp.rule1.get_name() == "Python": + if mp.rule1 is not None and mp.rule1.get_pronunciation() == "Python": update_python(mp.rule1) - if mp.rule2.get_name() == "Python": + if mp.rule2.get_pronunciation() == "Python": update_python(mp.rule2) control.nexus().merger.add_filter(replace_python_else_action) @@ -359,7 +359,7 @@ from caster.lib.dfplus.merge.mergepair import MergeInf from caster.lib.dfplus.state.short import R def add_is_to_python(rule): - if rule.get_name() == "Python": + if rule.get_pronunciation() == "Python": rule.mapping_actual()["identity is"] = R(Text(" is "), rdescript="Python: Is") def add_is_to_python_filter(mp): diff --git a/caster/lib/dfplus/hint/hintnode.py b/caster/lib/dfplus/hint/hintnode.py index f1fadbabc..23b0e22d4 100644 --- a/caster/lib/dfplus/hint/hintnode.py +++ b/caster/lib/dfplus/hint/hintnode.py @@ -91,7 +91,7 @@ def __init__(self, node, nexus, is_reset=False): self.refresh(node, first, is_reset) - def get_name(self): + def get_pronunciation(self): return self.master_node.spec def refresh(self, *args): diff --git a/caster/lib/dfplus/merge/ccrmerger.py b/caster/lib/dfplus/merge/ccrmerger.py index 0ff41578f..795ba0e16 100644 --- a/caster/lib/dfplus/merge/ccrmerger.py +++ b/caster/lib/dfplus/merge/ccrmerger.py @@ -100,14 +100,14 @@ def update_config(self): '''setup: adding rules and filters''' def add_global_rule(self, rule): - assert rule.get_context() is None, "global rules may not have contexts, "+rule.get_name()+" has a context: "+str(rule.get_context()) + assert rule.get_context() is None, "global rules may not have contexts, "+rule.get_pronunciation()+" has a context: "+str(rule.get_context()) assert isinstance(rule, MergeRule) and not hasattr(rule, "set_merger"), \ "only MergeRules may be added as global rules; use add_selfmodrule() or add_app_rule()" self._add_to(rule, self._global_rules) def add_app_rule(self, rule, context=None): if context is not None and rule.get_context() is None: rule.set_context(context) - assert rule.get_context() is not None, "app rules must have contexts, "+rule.get_name()+" has no context" - assert rule.get_merge_with() is not None, "app rules must define mwith, "+rule.get_name()+" has no mwith" + assert rule.get_context() is not None, "app rules must have contexts, "+rule.get_pronunciation()+" has no context" + assert rule.get_merge_with() is not None, "app rules must define mwith, "+rule.get_pronunciation()+" has no mwith" self._add_to(rule, self._app_rules) def add_selfmodrule(self, rule): assert hasattr(rule, "set_merger"), "only SelfModifyingRules may be added by add_selfmodrule()" @@ -118,15 +118,15 @@ def add_filter(self, filter): if not filter in self._filters: self._filters.append(filter) def _add_to(self, rule, group): - if rule.get_name() in \ + if rule.get_pronunciation() in \ self.global_rule_names()+\ self.app_rule_names()+\ self.selfmod_rule_names(): - raise Exception("Rule Naming Conflict: "+rule.get_name()) + raise Exception("Rule Naming Conflict: "+rule.get_pronunciation()) if isinstance(rule, MergeRule): for name in group.keys(): group[name].compatibility_check(rule) # calculate compatibility for uncombined rules at boot time - group[rule.get_name()] = rule + group[rule.get_pronunciation()] = rule '''getters''' def global_rule_names(self): @@ -293,10 +293,10 @@ def merge(self, time, name=None, enable=True, save=False): '''save if necessary''' if time in [MergeInf.RUN, MergeInf.SELFMOD] and save: # everything in base composite is active, everything in selfmod is active, update the config as such - active_global_names = [rule.get_name() for rule in active_global] + active_global_names = [rule.get_pronunciation() for rule in active_global] for rule_name in self._global_rules: self._config[CCRMerger._GLOBAL][rule_name] = rule_name in active_global_names - active_selfmod_names = [name3 for name3 in self._config[CCRMerger._SELFMOD] if self._config[CCRMerger._SELFMOD][name3]]#[rule.get_name() for rule in selfmod] + active_selfmod_names = [name3 for name3 in self._config[CCRMerger._SELFMOD] if self._config[CCRMerger._SELFMOD][name3]]#[rule.get_pronunciation() for rule in selfmod] for rule_name in self._self_modifying_rules: self._config[CCRMerger._SELFMOD][rule_name] = rule_name in active_selfmod_names self.save_config() diff --git a/caster/lib/dfplus/merge/mergerule.py b/caster/lib/dfplus/merge/mergerule.py index 3b8b4366c..8b5e625f5 100644 --- a/caster/lib/dfplus/merge/mergerule.py +++ b/caster/lib/dfplus/merge/mergerule.py @@ -46,7 +46,7 @@ def get_merge_name(): # returns unique str(int) for procedural rule names '''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''' + CCR copies; mwith is a list of get_pronunciation()s''' mwith = None def __init__(self, name=None, mapping=None, extras=None, defaults=None, @@ -94,12 +94,12 @@ def merge(self, other): 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], + 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_name(self): - return self.name if self.pronunciation is None else self.pronunciation + 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) diff --git a/caster/lib/tests/complexity.py b/caster/lib/tests/complexity.py index 892a00956..07f47a63b 100644 --- a/caster/lib/tests/complexity.py +++ b/caster/lib/tests/complexity.py @@ -144,7 +144,7 @@ def test(specs, choices, ccr_max): '''activate everything except the heavy rule''' merger_ccr_activator = merger.global_rule_changer() for rule in core_and_python(): - merger_ccr_activator(rule.get_name(), True, False) + merger_ccr_activator(rule.get_pronunciation(), True, False) print("..") merger.selfmod_rule_changer()("css", True, False) print("...") diff --git a/caster/lib/tests/unit/merger.py b/caster/lib/tests/unit/merger.py index c6285a85b..83e9e8b74 100644 --- a/caster/lib/tests/unit/merger.py +++ b/caster/lib/tests/unit/merger.py @@ -16,7 +16,7 @@ def demo_filter(_): ''' delete conflicting specs out of the base rule ''' if _.type == MergeInf.GLOBAL and _.time != MergeInf.BOOT \ - and _.rule1 is not None and _.rule2.get_name()=="Bash": + and _.rule1 is not None and _.rule2.get_pronunciation()=="Bash": for spec in _.rule1.mapping_actual().keys(): if spec in _.rule2.mapping_actual().keys(): del _.rule1.mapping_actual()[spec] diff --git a/caster/user/filters/examples/modkeysup.py b/caster/user/filters/examples/modkeysup.py index 08c85285b..bc6fc9563 100644 --- a/caster/user/filters/examples/modkeysup.py +++ b/caster/user/filters/examples/modkeysup.py @@ -13,7 +13,7 @@ def add_modkeys(rule): release = R(Key("shift:up, ctrl:up, alt:up"), rdescript = "Mod Keys Up") if not hasattr(rule, "marked") and\ - rule.get_name()[0:6] != "Merged": # don't augment merged rules-- they'd get it twice + rule.get_pronunciation()[0:6] != "Merged": # don't augment merged rules-- they'd get it twice for spec in rule.mapping_actual().keys(): rule.mapping_actual()[spec] = release + rule.mapping_actual()[spec] + release rule.marked = True diff --git a/caster/user/filters/examples/scen4.py b/caster/user/filters/examples/scen4.py index 31d132712..ac33f2da7 100644 --- a/caster/user/filters/examples/scen4.py +++ b/caster/user/filters/examples/scen4.py @@ -50,15 +50,15 @@ def scenario_3(mp): if mp.time == MergeInf.RUN and mp.type == MergeInf.GLOBAL: # Inf.RUN means any time except boot or SelfModifyingRule updates # Ing.GLOBAL means during global rule de/activation - if mp.rule1 is not None and mp.rule1.get_name() == "Python": + if mp.rule1 is not None and mp.rule1.get_pronunciation() == "Python": update_python(mp.rule1) - if mp.rule2.get_name() == "Python": + if mp.rule2.get_pronunciation() == "Python": update_python(mp.rule2) # control.nexus().merger.add_filter(scenario_3) def add_is_to_python(rule): - if rule.get_name() == "Python": + if rule.get_pronunciation() == "Python": rule.mapping_actual()["identity is"] = R(Text(" is "), rdescript="Python: Is") def scenario_4(mp): From 2ba48f712dcbaab359db851a6ffb222fb580ef67 Mon Sep 17 00:00:00 2001 From: Jacques Favreau Date: Sat, 25 Nov 2017 22:32:09 -0800 Subject: [PATCH 10/14] Remove unused settings --- caster/lib/settings.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/caster/lib/settings.py b/caster/lib/settings.py index d813664c8..4686402ec 100644 --- a/caster/lib/settings.py +++ b/caster/lib/settings.py @@ -11,7 +11,6 @@ SOFTWARE_VERSION_NUMBER = "0.5.8" SOFTWARE_NAME = "Caster v " + SOFTWARE_VERSION_NUMBER HOMUNCULUS_VERSION = "HMC v " + SOFTWARE_VERSION_NUMBER -HMC_TITLE_VOCABULARY = " :: Vocabulary Manager" HMC_TITLE_RECORDING = " :: Recording Manager" HMC_TITLE_DIRECTORY = " :: Directory Selector" HMC_TITLE_CONFIRM = " :: Confirm" @@ -93,9 +92,7 @@ def init_default_values(): values_change_count += update_values(SETTINGS["paths"], [ # DATA ("DLL_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/lib/dll/"), - ("SETTINGS_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/settings.json"), ("CCR_CONFIG_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/ccr.json"), - ("S_LIST_JSON_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/s_list.json"), ("SAVED_CLIPBOARD_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/clipboard.json"), ("RECORDED_MACROS_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/recorded_macros.json"), ("ALIAS_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/aliases.json."), @@ -125,10 +122,6 @@ def init_default_values(): # CCR ("CONFIGDEBUGTXT_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/configdebug.txt"), - # MISC - ("ALARM_SOUND_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/media/49685__ejfortin__nano-blade-loop.wav"), - ("MEDIA_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/media"), - # PYTHON ("WXPYTHON_PATH" , "C:/Python27/Lib/site-packages/wx-3.0-msw"), @@ -190,24 +183,12 @@ def init_default_values(): # node rules values_change_count += update_values(SETTINGS, [("nodes", {})]) - # passwords section - values_change_count += update_values(SETTINGS, [("password", {})]) - values_change_count += update_values(SETTINGS["password"], [ - ("seed1", "change these"), - ("seed2", "if you use"), - ("seed3", "password"), - ("seed4", "generation") - ]) - # miscellaneous section values_change_count += update_values(SETTINGS, [("miscellaneous", {})]) - values_change_count += update_values(SETTINGS["miscellaneous"], [ - ("debug_speak", False), ("dev_commands", False), ("sikuli_enabled", False), ("keypress_wait", 50), # milliseconds ("max_ccr_repetitions", 16), - ("enable_match_logging", False), ("atom_palette_wait", "30"), ("rdp_mode", False), ("integer_remap_opt_in", False), From 0bef9e0571e4f24a77cf9677b177b40bcc9e469c Mon Sep 17 00:00:00 2001 From: Jacques Favreau Date: Sat, 25 Nov 2017 22:49:36 -0800 Subject: [PATCH 11/14] Re-work settings.py. --- caster/lib/settings.py | 320 ++++++++++++++++++++--------------------- 1 file changed, 160 insertions(+), 160 deletions(-) diff --git a/caster/lib/settings.py b/caster/lib/settings.py index 4686402ec..f9130cc20 100644 --- a/caster/lib/settings.py +++ b/caster/lib/settings.py @@ -1,10 +1,10 @@ import json import os import sys +import collections -SETTINGS = None -BAD_LOAD = False -INISETPATH = os.path.realpath(__file__).split("lib")[0]+"bin\\data\\settings.json" +SETTINGS = {} +_SETTINGS_PATH = os.path.realpath(__file__).split("lib")[0]+"bin\\data\\settings.json" BASE_PATH = os.path.realpath(__file__).split("\\lib")[0].replace("\\", "/") # title @@ -31,11 +31,126 @@ WSR = False +def _find_natspeak(): + '''Tries to find the natspeak engine.''' + possible_locations = [ + "C:/Program Files (x86)/Nuance/NaturallySpeaking14/Program/natspeak.exe", + "C:/Program Files (x86)/Nuance/NaturallySpeaking13/Program/natspeak.exe", + "C:/Program Files (x86)/Nuance/NaturallySpeaking12/Program/natspeak.exe", + ] + for location in possible_locations: + if os.path.isfile(location): + return location + print "Cannot find default dragon engine path" + return "" + +# The defaults for every setting. Could be moved out into its own file. +_DEFAULT_SETTINGS = { + "paths": { + "BASE_PATH": BASE_PATH, + + # DATA + "ALIAS_PATH": BASE_PATH + "/bin/data/aliases.json.", + "CCR_CONFIG_PATH": BASE_PATH + "/bin/data/ccr.json", + "DLL_PATH": BASE_PATH + "/lib/dll/", + "FILTER_DEFS_PATH": BASE_PATH + "/user/words.txt", + "LOG_PATH": BASE_PATH + "/bin/data/log.txt", + "RECORDED_MACROS_PATH": BASE_PATH + "/bin/data/recorded_macros.json", + "SAVED_CLIPBOARD_PATH": BASE_PATH + "/bin/data/clipboard.json", + "SIKULI_SCRIPTS_FOLDER_PATH": BASE_PATH + "/asynch/sikuli/scripts", + + # REMOTE_DEBUGGER_PATH is the folder in which pydevd.py can be found + "REMOTE_DEBUGGER_PATH": "", + + # EXECUTABLES + "DEFAULT_BROWSER_PATH": "C:/Program Files (x86)/Mozilla Firefox/firefox.exe", + "DOUGLAS_PATH": BASE_PATH + "/asynch/mouse/grids.py", + "ENGINE_PATH": _find_natspeak(), + "HOMUNCULUS_PATH": BASE_PATH + "/asynch/hmc/h_launch.py", + "LEGION_PATH": BASE_PATH + "/asynch/mouse/legion.py", + "MEDIA_PATH": BASE_PATH + "/bin/media", + "RAINBOW_PATH": BASE_PATH + "/asynch/mouse/grids.py", + "REBOOT_PATH": BASE_PATH + "/bin/reboot.bat", + "REBOOT_PATH_WSR": BASE_PATH + "/bin/reboot_wsr.bat", + "SETTINGS_WINDOW_PATH": BASE_PATH + "/asynch/settingswindow.py", + "SIKULI_COMPATIBLE_JAVA_EXE_PATH": "", + "SIKULI_IDE_JAR_PATH": "", + "SIKULI_SCRIPTS_JAR_PATH": "", + "SIKULI_SERVER_PATH": BASE_PATH + "/asynch/sikuli/scripts/xmlrpc_server.sikuli", + "WSR_PATH": "C:/Windows/Speech/Common/sapisvr.exe", + + # CCR + "CONFIGDEBUGTXT_PATH": BASE_PATH + "/bin/data/configdebug.txt", + + # PYTHON + "WXPYTHON_PATH": "C:/Python27/Lib/site-packages/wx-3.0-msw" + }, + + # Apps Section + "apps": { + "atom": True, + "chrome": True, + "cmd": True, + "dragon": True, + "eclipse": True, + "emacs": True, + "explorer": True, + "firefox": True, + "flashdevelop": True, + "foxitreader": True, + "gitbash": True, + "kdiff3": True, + "douglas": True, + "legion": True, + "rainbow": True, + "ssms": True, + "jetbrains": True, + "msvc": True, + "notepadplusplus": True, + "sqldeveloper": True, + "sublime": True, + "visualstudio": True, + "winword": True, + "wsr": True, + }, + + # feature switches + "feature_rules": { + "hmc": True, + "again": True, + "alias": True, + "chainalias": True, + }, + + # node rules + "nodes": {}, + + # miscellaneous section + "miscellaneous": { + "dev_commands": False, + "sikuli_enabled": False, + "keypress_wait": 50, # milliseconds + "max_ccr_repetitions": 16, + "atom_palette_wait": "30", + "rdp_mode": False, + "integer_remap_opt_in": False, + "integer_remap_crash_fix": False, + "print_rdescripts": False, + "history_playback_delay_secs": 1.0, + }, + "pronunciations": { + "c++": "C plus plus", + "jquery": "J query", + }, + "one time warnings": {} +} + + +# Internal Methods def _save(data, path): '''only to be used for settings file''' try: - formatted_data = json.dumps(data, sort_keys=True, indent=4, - ensure_ascii=False) + formatted_data = json.dumps(data, sort_keys=True, indent=4, ensure_ascii=False) if not os.path.exists(path): f = open(path, "w") f.close() @@ -43,173 +158,51 @@ def _save(data, path): f.write(formatted_data) f.close() except Exception: - print("error saving json file: " + path) + print "Error saving json file: " + path -def _load(path): - '''only to be used for settings file''' +def _init(path): result = {} try: f = open(path, "r") result = json.loads(f.read()) f.close() except ValueError: - global BAD_LOAD - BAD_LOAD = True print("\n\nValueError while loading settings file: " + path + "\n\n") print(sys.exc_info()) except IOError: print("\n\nIOError: Could not find settings file: " + path + "\nInitializing file...\n\n") + result, num_default_added = _deep_merge_defaults(result, _DEFAULT_SETTINGS) + if num_default_added > 0: + print "Default settings values added: %d " % num_default_added + _save(result, _SETTINGS_PATH) return result -def save_config(): - global SETTINGS - global SETTINGS_PATH - global INISETPATH - _save(SETTINGS, INISETPATH if SETTINGS is None or not "SETTINGS" in SETTINGS.keys() else SETTINGS["SETTINGS_PATH"]) -def load_config(): - global SETTINGS - global SETTINGS_PATH - global INISETPATH - SETTINGS = _load(INISETPATH if SETTINGS is None else SETTINGS["SETTINGS_PATH"]) - init_default_values() - -def update_values(d, key_values): - values_change_count = 0 - for key, value in key_values: - if not key in d: - d[key] = value - values_change_count += 1 - return values_change_count - -def init_default_values(): - global SETTINGS, BASE_PATH - values_change_count = 0 - - # paths section - values_change_count += update_values(SETTINGS, [("paths", {})]) - values_change_count += update_values(SETTINGS["paths"], [("BASE_PATH", BASE_PATH)]) - values_change_count += update_values(SETTINGS["paths"], [ - # DATA - ("DLL_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/lib/dll/"), - ("CCR_CONFIG_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/ccr.json"), - ("SAVED_CLIPBOARD_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/clipboard.json"), - ("RECORDED_MACROS_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/recorded_macros.json"), - ("ALIAS_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/aliases.json."), - ("LOG_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/log.txt"), - ("SIKULI_SCRIPTS_FOLDER_PATH", SETTINGS["paths"]["BASE_PATH"] + "/asynch/sikuli/scripts"), - ("FILTER_DEFS_PATH", SETTINGS["paths"]["BASE_PATH"] + "/user/words.txt"), - - # REMOTE_DEBUGGER_PATH is the folder in which pydevd.py can be found - ("REMOTE_DEBUGGER_PATH" , "C:/PROG/alt ec/eclipse/plugins/org.python.pydev_3.9.2.201502050007/pysrc"), - - # EXECUTABLES - ("WSR_PATH", "C:/Windows/Speech/Common/sapisvr.exe"), - ("LEGION_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/asynch/mouse/legion.py"), - ("RAINBOW_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/asynch/mouse/grids.py"), - ("DOUGLAS_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/asynch/mouse/grids.py"), - ("HOMUNCULUS_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/asynch/hmc/h_launch.py"), - ("DEFAULT_BROWSER_PATH", "C:/Program Files (x86)/Mozilla Firefox/firefox.exe"), - ("SIKULI_IDE_JAR_PATH", ""), - ("SIKULI_SCRIPTS_JAR_PATH", ""), - ("SIKULI_SERVER_PATH", SETTINGS["paths"]["BASE_PATH"] + "/asynch/sikuli/scripts/xmlrpc_server.sikuli"), - ("SIKULI_COMPATIBLE_JAVA_EXE_PATH", ""), - ("ENGINE_PATH", "C:/Program Files (x86)/Nuance/NaturallySpeaking14/Program/natspeak.exe"), - ("REBOOT_PATH", SETTINGS["paths"]["BASE_PATH"] + "/bin/reboot.bat"), - ("REBOOT_PATH_WSR", SETTINGS["paths"]["BASE_PATH"] + "/bin/reboot_wsr.bat"), - ("SETTINGS_WINDOW_PATH", SETTINGS["paths"]["BASE_PATH"] + "/asynch/settingswindow.py"), - - # CCR - ("CONFIGDEBUGTXT_PATH" , SETTINGS["paths"]["BASE_PATH"] + "/bin/data/configdebug.txt"), - - # PYTHON - ("WXPYTHON_PATH" , "C:/Python27/Lib/site-packages/wx-3.0-msw"), - - ]) - if not SETTINGS["paths"]["REMOTE_DEBUGGER_PATH"] in sys.path and os.path.isdir(SETTINGS["paths"]["REMOTE_DEBUGGER_PATH"]): - sys.path.append(SETTINGS["paths"]["REMOTE_DEBUGGER_PATH"]) - if not SETTINGS["paths"]["WXPYTHON_PATH"] in sys.path and os.path.isdir(SETTINGS["paths"]["WXPYTHON_PATH"]): - sys.path.append(SETTINGS["paths"]["WXPYTHON_PATH"]) - - # detect the version of Dragon - if not os.path.isfile(SETTINGS["paths"]["ENGINE_PATH"]): - dragon_13_path = "C:/Program Files (x86)/Nuance/NaturallySpeaking13/Program/natspeak.exe" - dragon_12_path = "C:/Program Files (x86)/Nuance/NaturallySpeaking12/Program/natspeak.exe" - if os.path.isfile(dragon_13_path): - SETTINGS["paths"]["ENGINE_PATH"] = dragon_13_path - elif os.path.isfile(dragon_12_path): - SETTINGS["paths"]["ENGINE_PATH"] = dragon_12_path +def _deep_merge_defaults(data, defaults): + ''' + Recursivly merge data and defaults, preferring data. + Only handles nested dicts and scalar values. + Modifies `data` in place. + ''' + changes = 0 + for key, default_value in defaults.iteritems(): + # If the key is in the data, use that, but call recursivly if it's a dict. + if(key in data): + if(isinstance(data[key], collections.Mapping)): + child_data, child_changes = _deep_merge_defaults(data[key], default_value) + data[key] = child_data + changes += child_changes else: - print("Cannot find default dragon engine path") - - # apps section - values_change_count += update_values(SETTINGS, [("apps", {})]) - values_change_count += update_values(SETTINGS["apps"], [ - ("atom", True), - ("chrome", True), - ("cmd", True), - ("dragon", True), - ("eclipse", True), - ("emacs", True), - ("explorer", True), - ("firefox", True), - ("flashdevelop", True), - ("foxitreader", True), - ("gitbash", True), - ("kdiff3", True), - ("douglas", True), - ("legion", True), - ("rainbow", True), - ("ssms", True), - ("jetbrains", True), - ("msvc", True), - ("notepadplusplus", True), - ("sqldeveloper", True), - ("sublime", True), - ("visualstudio", True), - ("winword", True), - ("wsr", True), - ]) - - # feature switches - values_change_count += update_values(SETTINGS, [("feature_rules", {})]) - values_change_count += update_values(SETTINGS["feature_rules"], [ - ("hmc", True), - ("again", True), - ("alias", True), - ("chainalias", True), - ]) - - # node rules - values_change_count += update_values(SETTINGS, [("nodes", {})]) - - # miscellaneous section - values_change_count += update_values(SETTINGS, [("miscellaneous", {})]) - ("dev_commands", False), - ("sikuli_enabled", False), - ("keypress_wait", 50), # milliseconds - ("max_ccr_repetitions", 16), - ("atom_palette_wait", "30"), - ("rdp_mode", False), - ("integer_remap_opt_in", False), - ("integer_remap_crash_fix", False), - ("print_rdescripts", False), - ("history_playback_delay_secs", 1.0) - ]) - - # pronunciations section - values_change_count += update_values(SETTINGS, [("pronunciations", {})]) - values_change_count += update_values(SETTINGS["pronunciations"], [ - ("c++", "C plus plus"), - ("jquery", "J query"), - ]) - - values_change_count += update_values(SETTINGS, [("one time warnings", {})]) - - global BAD_LOAD - if values_change_count > 0 and not BAD_LOAD: - print("settings values changed: "+ str(values_change_count)) - save_config() + data[key] = default_value + changes += 1 + return data, changes + + + +# Public interface: +def save_config(): + '''Save the current in-memory settings to disk''' + _save(SETTINGS, _SETTINGS_PATH) def get_settings(): global SETTINGS @@ -220,11 +213,18 @@ def get_default_browser_executable(): return SETTINGS["paths"]["DEFAULT_BROWSER_PATH"].split("/")[-1] def report_to_file(message, path=None): - global SETTINGS _path = SETTINGS["paths"]["LOG_PATH"] if path is not None: _path = path - f = open(_path, 'a') + f = open(_path, 'a') f.write(str(message) + "\n") f.close() -load_config() + +## Kick everything off. +SETTINGS = _init(_SETTINGS_PATH) +for path in [ + SETTINGS["paths"]["REMOTE_DEBUGGER_PATH"], + SETTINGS["paths"]["WXPYTHON_PATH"] + ]: + if not path in sys.path and os.path.isdir(path): + sys.path.append(path) \ No newline at end of file From 8cdc576de02cb1bb9506c35cf0991f5dcfa8a10c Mon Sep 17 00:00:00 2001 From: Jacques Favreau Date: Tue, 28 Nov 2017 20:38:25 -0800 Subject: [PATCH 12/14] Remove unused auto property --- caster/lib/ccr/cpp/cpp.py | 1 - caster/lib/ccr/csharp/csharp.py | 1 - caster/lib/ccr/haxe/haxe.py | 1 - caster/lib/ccr/java/java.py | 1 - caster/lib/ccr/javascript/javascript.py | 1 - caster/lib/ccr/python/python.py | 1 - caster/lib/ccr/rust/rust.py | 1 - 7 files changed, 7 deletions(-) diff --git a/caster/lib/ccr/cpp/cpp.py b/caster/lib/ccr/cpp/cpp.py index 2e58e2931..acc237d44 100644 --- a/caster/lib/ccr/cpp/cpp.py +++ b/caster/lib/ccr/cpp/cpp.py @@ -12,7 +12,6 @@ class CPP(MergeRule): - auto = [".h",".cpp"] pronunciation = "C plus plus" mapping = { diff --git a/caster/lib/ccr/csharp/csharp.py b/caster/lib/ccr/csharp/csharp.py index d350e5e68..49404c4af 100644 --- a/caster/lib/ccr/csharp/csharp.py +++ b/caster/lib/ccr/csharp/csharp.py @@ -13,7 +13,6 @@ class CSharp(MergeRule): - auto = [".cs", ".cshtml"] pronunciation = "C sharp" mapping = { diff --git a/caster/lib/ccr/haxe/haxe.py b/caster/lib/ccr/haxe/haxe.py index 2484883a1..f7bd6488e 100644 --- a/caster/lib/ccr/haxe/haxe.py +++ b/caster/lib/ccr/haxe/haxe.py @@ -8,7 +8,6 @@ class Haxe(MergeRule): - auto = [".hx"] pronunciation = "hacks" mapping = { diff --git a/caster/lib/ccr/java/java.py b/caster/lib/ccr/java/java.py index b3d2aca07..c865bfc16 100644 --- a/caster/lib/ccr/java/java.py +++ b/caster/lib/ccr/java/java.py @@ -18,7 +18,6 @@ class JavaNon(MappingRule): ncdefaults = {} class Java(MergeRule): - auto = [".java"] non = JavaNon mapping = { diff --git a/caster/lib/ccr/javascript/javascript.py b/caster/lib/ccr/javascript/javascript.py index 80e8a2d4b..b088147ec 100644 --- a/caster/lib/ccr/javascript/javascript.py +++ b/caster/lib/ccr/javascript/javascript.py @@ -13,7 +13,6 @@ class Javascript(MergeRule): - auto = [".js"] mapping = { diff --git a/caster/lib/ccr/python/python.py b/caster/lib/ccr/python/python.py index e8bfc2fab..ee97caf16 100644 --- a/caster/lib/ccr/python/python.py +++ b/caster/lib/ccr/python/python.py @@ -21,7 +21,6 @@ class PythonNon(MappingRule): } class Python(MergeRule): - auto = [".py"] non = PythonNon mapping = { diff --git a/caster/lib/ccr/rust/rust.py b/caster/lib/ccr/rust/rust.py index 92598bed0..145bb843f 100644 --- a/caster/lib/ccr/rust/rust.py +++ b/caster/lib/ccr/rust/rust.py @@ -25,7 +25,6 @@ class RustNon(MappingRule): } class Rust(MergeRule): - auto = [".rs"] non = RustNon mapping = { From e852c608076232dc4c8b7b4dcd258dd89383ee8c Mon Sep 17 00:00:00 2001 From: Jacques Favreau Date: Tue, 28 Nov 2017 20:39:08 -0800 Subject: [PATCH 13/14] Remove unused TokenSet feature --- caster/lib/ccr/cpp/cpp.py | 21 +------------------- caster/lib/ccr/java/java.py | 18 +---------------- caster/lib/ccr/javascript/javascript.py | 26 ++----------------------- caster/lib/ccr/python/python.py | 10 +--------- caster/lib/dfplus/merge/mergerule.py | 10 ---------- 5 files changed, 5 insertions(+), 80 deletions(-) diff --git a/caster/lib/ccr/cpp/cpp.py b/caster/lib/ccr/cpp/cpp.py index acc237d44..3623f7866 100644 --- a/caster/lib/ccr/cpp/cpp.py +++ b/caster/lib/ccr/cpp/cpp.py @@ -7,7 +7,7 @@ from caster.lib import control from caster.lib.ccr.standard import SymbolSpecs -from caster.lib.dfplus.merge.mergerule import MergeRule, TokenSet +from caster.lib.dfplus.merge.mergerule import MergeRule from caster.lib.dfplus.state.short import R @@ -90,24 +90,5 @@ class CPP(MergeRule): extras = [] defaults = {} - - token_set = TokenSet(["alignas", "alignof", "and", "and_eq", "asm", "auto", - "bitand", "bitor", "bool", "break", "case", "catch", - "char", "char16_t", "char32_t", "class", "compl", - "concept", "const", "constexpr", "const_cast", "continue", - "decltype", "default", "delete", "do", "double", - "dynamic_cast", "else", "enum", "explicit", "export", - "extern", "false", "float", "for", "friend", "goto", "if", - "inline", "int", "long", "mutable", "namespace", "new", - "noexcept", "not", "not_eq", "nullptr", "operator", "or", - "or_eq", "private", "protected", "public", "register", - "reinterpret_cast", "requires", "return", "short", "signed", - "sizeof", "static", "static_assert", "static_cast", "struct", - "switch", "template", "this", "thread_local", "throw", "true", - "try", "typedef", "typeid", "typename", "union", "unsigned", - "using", "virtual", "void", "volatile", "wchar_t", "while", - "xor", "xor_eq" ], - "//", - ["/*", "*/"]) control.nexus().merger.add_global_rule(CPP()) \ No newline at end of file diff --git a/caster/lib/ccr/java/java.py b/caster/lib/ccr/java/java.py index c865bfc16..5ab9bd738 100644 --- a/caster/lib/ccr/java/java.py +++ b/caster/lib/ccr/java/java.py @@ -2,7 +2,7 @@ from caster.lib import control from caster.lib.ccr.standard import SymbolSpecs -from caster.lib.dfplus.merge.mergerule import MergeRule, TokenSet +from caster.lib.dfplus.merge.mergerule import MergeRule from caster.lib.dfplus.state.short import R @@ -103,21 +103,5 @@ class Java(MergeRule): extras = [] defaults = {} - - token_set = TokenSet(["abstract", "continue", "for", "new", "switch", "assert", - "default", "goto", "package", "synchronized", "boolean", - "do", "if", "private", "this", "break", "double", - "implements", "protected", "throw", "byte", "else", - "import", "public", "throws", "case", "enum", - "instanceof", "return", "transient", "catch", "extends", - "int", "short", "try", "char", "final", "interface", - "static", "void", "class", "finally", "long", "strictfp", - "volatile", "const", "float", "native", "super", "while"], - "//", - ["/*", "*/"]) - - - - control.nexus().merger.add_global_rule(Java()) \ No newline at end of file diff --git a/caster/lib/ccr/javascript/javascript.py b/caster/lib/ccr/javascript/javascript.py index b088147ec..04a8fd350 100644 --- a/caster/lib/ccr/javascript/javascript.py +++ b/caster/lib/ccr/javascript/javascript.py @@ -8,7 +8,7 @@ from caster.lib import control from caster.lib.ccr.standard import SymbolSpecs from caster.lib.dfplus.additions import SelectiveAction -from caster.lib.dfplus.merge.mergerule import MergeRule, TokenSet +from caster.lib.dfplus.merge.mergerule import MergeRule from caster.lib.dfplus.state.short import R @@ -92,27 +92,5 @@ class Javascript(MergeRule): extras = [] defaults = {} - - token_set = TokenSet(["abstract", "arguments", "boolean", "break", "byte", - "case", "catch", "char", "class", "const", "continue", - "debugger", "default", "delete", "do", "double", "else", - "enum", "eval", "export", "extends", "false", "final", - "finally", "float", "for", "function", "goto", "if", - "implements", "import", "in", "instanceof", "int", - "interface", "let", "long", "native", "new", "null", - "package", "private", "protected", "public", "return", - "short", "static", "super", "switch", "synchronized", - "this", "throw", "throws", "transient", "true", "try", - "typeof", "var", "void", "volatile", "while", "with", - "yield"], - "//", - ["/*", "*/"]) - - - - - - - - + control.nexus().merger.add_global_rule(Javascript(ID=200)) diff --git a/caster/lib/ccr/python/python.py b/caster/lib/ccr/python/python.py index ee97caf16..0f672502e 100644 --- a/caster/lib/ccr/python/python.py +++ b/caster/lib/ccr/python/python.py @@ -7,7 +7,7 @@ from caster.lib import control from caster.lib.ccr.standard import SymbolSpecs -from caster.lib.dfplus.merge.mergerule import MergeRule, TokenSet +from caster.lib.dfplus.merge.mergerule import MergeRule from caster.lib.dfplus.state.short import R @@ -90,13 +90,5 @@ class Python(MergeRule): extras = [Dictation("text"),] defaults = {} - - token_set = TokenSet(["and", "del", "from", "not", "while", "as", "elif", - "global", "or", "with", "assert", "else", "if", "pass", - "yield", "break", "except", "import", "print", "class", - "exec", "in", "raise", "continue", "finally", "is", - "return", "def", "for", "lambda", "try"], - "#", - ["'''", '"""']) control.nexus().merger.add_global_rule(Python(ID=100)) \ No newline at end of file diff --git a/caster/lib/dfplus/merge/mergerule.py b/caster/lib/dfplus/merge/mergerule.py index 8b5e625f5..ceba5927a 100644 --- a/caster/lib/dfplus/merge/mergerule.py +++ b/caster/lib/dfplus/merge/mergerule.py @@ -3,18 +3,8 @@ @author: synkarius ''' -import re - from dragonfly import MappingRule, Pause, Function - -class TokenSet(object): - SYMBOL_PATTERN = re.compile("([A-Za-z0-9_]+)") - def __init__(self, keywords, line_comment, long_comment): - self.keywords = keywords - self.line_comment = line_comment - self.long_comment = long_comment - class MergeRule(MappingRule): @staticmethod def _get_next_id(): From 2fc19b551df9b144afb08e08ffde9d9824f88181 Mon Sep 17 00:00:00 2001 From: Eric Paulson Date: Mon, 15 Jan 2018 23:39:11 -0800 Subject: [PATCH 14/14] Minor version bump. --- caster/lib/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/caster/lib/settings.py b/caster/lib/settings.py index f9130cc20..d755263df 100644 --- a/caster/lib/settings.py +++ b/caster/lib/settings.py @@ -8,7 +8,7 @@ BASE_PATH = os.path.realpath(__file__).split("\\lib")[0].replace("\\", "/") # title -SOFTWARE_VERSION_NUMBER = "0.5.8" +SOFTWARE_VERSION_NUMBER = "0.5.9" SOFTWARE_NAME = "Caster v " + SOFTWARE_VERSION_NUMBER HOMUNCULUS_VERSION = "HMC v " + SOFTWARE_VERSION_NUMBER HMC_TITLE_RECORDING = " :: Recording Manager" @@ -227,4 +227,4 @@ def report_to_file(message, path=None): SETTINGS["paths"]["WXPYTHON_PATH"] ]: if not path in sys.path and os.path.isdir(path): - sys.path.append(path) \ No newline at end of file + sys.path.append(path)