From 1d907c4da043295f9270692cf3736e69e9a2308a Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Fri, 17 Apr 2020 18:18:36 +0300 Subject: [PATCH 01/45] Fixing problems with sub indexing strings volume 2, fixing typo and handling triple quoted strings Resolves #18 fixing a typo introduced in 0fcbc51877481349f38878509cb96068217c9694 And taking Care of triple quoted strings --- library/info.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/library/info.py b/library/info.py index 44f5c8d..6f204e4 100644 --- a/library/info.py +++ b/library/info.py @@ -667,28 +667,29 @@ def get_subparts_of_string(root,name_mode = False): start_position = 1 if not check_fake(root): x = root.first_token.string - # print("String:\n",x) y1 = x.find("'") y2 = x.find("\"") if y1>=0 and y2>=0: - z = mean(y1,y2) + z = min(y1,y2) elif y1>=0: z = y1 elif y2>=0: z = y2 else: raise Exception("problem with splitting a string , there is no beginning!") + try : + if x[z]==x[z+1]==x[z+2]: + z = z + 2 + except : + pass start_position += z start_position += root.first_token.startpos - # print("Start Position:\n",start_position) - # start_position = root.first_token.startpos + ( 1+(len(root.first_token.string) if root.first_token.type==tokenize.NAME else 0) if not name_mode else 0) original = root.s if not name_mode else root.id try : splitted = split_string(root.s if not name_mode else root.id,even_letters = False if name_mode else True) except : print(" exceptions were thrown") index = 0 - print("splitted ",splitted) for s in splitted: if not s: continue From 0007784b49387cce92e510e5bd45fd2cb22e4b57 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sat, 18 Apr 2020 01:19:09 +0300 Subject: [PATCH 02/45] Make fix_argument and fix_argument_list not call fix_definition on Lambdas This Temporaril address is part of the issue #17 Now the existence of lambda in the code has no effect! --- library/info.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/info.py b/library/info.py index 6f204e4..66304e1 100644 --- a/library/info.py +++ b/library/info.py @@ -1017,6 +1017,9 @@ def fix_alias(root,atok): def fix_argument(root,atok,token = None): if already_fixed(root): return token + # the following check was introduced to work around issue #17 + if not match_node(root.parent.parent,ast.FunctionDef): + return None if token is None: fix_definition(root.parent.parent,atok) if not already_fixed(root): @@ -1038,7 +1041,7 @@ def fix_argument(root,atok,token = None): def fix_argument_list(root,atok): if not match_node(root,ast.arguments): return False - if already_fixed(root) or fix_definition(root.parent,atok): + if already_fixed(root) or match_node(root.parent,(ast.FunctionDef)) and fix_definition(root.parent,atok): return True return False @@ -1046,7 +1049,6 @@ def fix_argument_list(root,atok): def fix_definition(root,atok): if already_fixed(root): return True - # there is a discrepancy between the 3.3 and 3.4 versions of the abstract syntax tree # in 3.3 the variable arguments and the variable keyboard arguments are stored in a little bit differently x = root.args From fe466db0c3840b66281eaddd2d754aa3e930afda Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sat, 18 Apr 2020 18:06:53 +0300 Subject: [PATCH 03/45] Small ROI support for identity,identity left, identity right --- library/info.py | 11 +++++++++++ queries/big_roi.py | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/library/info.py b/library/info.py index 66304e1..018bdc6 100644 --- a/library/info.py +++ b/library/info.py @@ -321,6 +321,17 @@ def get_container_check(root): def get_membership(root): return root if match_node(root,ast.Compare) and all([match_node(x,(ast.In,ast.NotIn)) for x in root.ops]) else None + +# Extracting Identity Left And Right +def get_identity_check_left(root): + return root.left if match_node(root,ast.Compare) and all([match_node(x,(ast.Is,ast.IsNot)) for x in root.ops]) else None + +def get_identity_check_right(root): + return root.comparators[-1] if match_node(root,ast.Compare) and all([match_node(x,(ast.Is,ast.IsNot)) for x in root.ops]) else None + +def get_identity_check(root): + return root if match_node(root,ast.Compare) and all([match_node(x,(ast.Is,ast.IsNot)) for x in root.ops]) else None + # Extract Left Middle And Right from numerical comparisons def get_comparison_left_side(root): return root.left if match_node(root,ast.Compare) else None diff --git a/queries/big_roi.py b/queries/big_roi.py index dd16b7c..0e19218 100644 --- a/queries/big_roi.py +++ b/queries/big_roi.py @@ -125,6 +125,10 @@ def standard(x): "container":((ast.Compare),(),get_container_check), "member":((ast.Compare),(),get_member_check), "membership":((ast.Compare),(),get_membership), + + "identity":((ast.Compare),(),get_identity_check), + "identity left":((ast.Compare),(),get_identity_check_left), + "identity right":((ast.Compare),(),get_identity_check_right), "left side":((ast.Compare),(),get_comparison_left_side), "right side":((ast.Compare),(),get_comparison_right_side), From c38e245aabd2a6abb719e96ddabc307c9f501876 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sun, 19 Apr 2020 20:31:15 +0300 Subject: [PATCH 04/45] Bug fix: repairing rejected valid lambda definitions If they started with * Definitions of the form `lambda *x,**k:x` are valid code but if there is a Error else where The repair module Would try to boot it dummy variable after lambda causing a syntax error --- library/repair.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/repair.py b/library/repair.py index afb078d..3420b6a 100644 --- a/library/repair.py +++ b/library/repair.py @@ -92,7 +92,7 @@ def finish_atom(t): def before_star(t): # of these does not check all cases return t[-1] is None or not ( - finish_atom(t[-1]) or t[-1].string in ["(","[","{",",","import","for"] or t[-1].type in [token.INDENT] + finish_atom(t[-1]) or t[-1].string in ["(","[","{",",","import","for","lambda"] or t[-1].type in [token.INDENT] ) From b767fec7270988499f0d3714892578f11d0e85fe Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Thu, 23 Apr 2020 02:01:07 +0300 Subject: [PATCH 05/45] Add supportFor repairing lambda Which is followed by comma --- library/repair.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/repair.py b/library/repair.py index 3420b6a..c5f5c48 100644 --- a/library/repair.py +++ b/library/repair.py @@ -151,7 +151,7 @@ def after_unary(t): def after_comma(t): return t[1] is None or t[1].string =="," def before_comma(t): - return t[ -1] is None or t[-1].string in ["(","[","{"] + return t[ -1] is None or t[-1].string in ["(","[","{","lambda"] def after_bracket(t): return t[1] is None or t[1].string in ["for","if","while","with"] or ( @@ -208,6 +208,7 @@ def after_else(t): start_atom(t[1]) or t[1].string in [":"] ) ''' + def handle_empty_compound(atok ,t,l,b,dummy): n = neighbors(atok, t) left,right = expand_to_line_or_statement(atok,t, l, b) From fef04cd14ff752640e2d11c692177dc1fc36090a Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Thu, 23 Apr 2020 15:54:01 +0300 Subject: [PATCH 06/45] Repair Change in after_star, remove special cases like surrounded by commas If I remember correctly those additional Special cases were added In order to prevent repairing use cases where * is used as a delimiter separate keyword only arguments from positional ones in function definitions. Nonetheless An additional dummy node does not really hurt, where is it missing prevents us from repairing things like lambda x,*,**k --- library/repair.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/repair.py b/library/repair.py index c5f5c48..2137ba9 100644 --- a/library/repair.py +++ b/library/repair.py @@ -100,7 +100,7 @@ def after_star(t): # of these does not check all cases return t[1] is None or not ( start_atom(t[1]) or t[-1] is not None and ( - (t[-1].string,t[1].string) in [('(',','),(',',","),(",",")")] or + # (t[-1].string,t[1].string) in [('(',','),(',',","),(",",")")] or t[-1].string in ["import"] ) From 7dc83f90cb468abca26981e6de951b03f118398b Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Fri, 24 Apr 2020 01:38:33 +0300 Subject: [PATCH 07/45] Fix exceptions raised from trying to obtain the node from cursor , When he does at the end of the file first attempt to resolve #19 and more code and cleanups are needed Remember "".isspace()==False --- library/selection_node.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/selection_node.py b/library/selection_node.py index 0d66085..36206fb 100644 --- a/library/selection_node.py +++ b/library/selection_node.py @@ -12,9 +12,9 @@ def nearest_node_from_offset(root,atok,offset): inside = lambda x,y: (y[0]<=x Date: Fri, 24 Apr 2020 01:59:53 +0300 Subject: [PATCH 08/45] nearest_note_from_offset rewrite In order to utilize the safer next_token Function and fix typo atok.next_token(orig_token) Can throw exception, Which the wrapper function handles. Some cleanups from For the solution to #19 Also fix the typo, which I accidentally introduced at 7dc83f9 Replacing root with step... --- library/selection_node.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/library/selection_node.py b/library/selection_node.py index 36206fb..57d869e 100644 --- a/library/selection_node.py +++ b/library/selection_node.py @@ -3,21 +3,24 @@ from PythonVoiceCodingPlugin.third_party.asttokens import asttokens -from PythonVoiceCodingPlugin.library import get_source_region +from PythonVoiceCodingPlugin.library import get_source_region,previous_token,next_token from PythonVoiceCodingPlugin.library.info import generic_fix,get_sub_index from PythonVoiceCodingPlugin.library.traverse import match_node def nearest_node_from_offset(root,atok,offset): converter = atok._line_numbers inside = lambda x,y: (y[0]<=x Date: Fri, 24 Apr 2020 18:43:32 +0300 Subject: [PATCH 09/45] Reuse note_from_range inside nearest_node_from_offset Yet another commit for #19 By using the range version, we get to redo use time complexity from O(nodes) to something closer to O(depth) We also alter the signature of node_from_range to remain backwards compatible With previous versions for obtaining note selection Finally, A small detail to notice Is that the inside function used for single car ets Is slightly changed --- library/selection_node.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/library/selection_node.py b/library/selection_node.py index 57d869e..74103d4 100644 --- a/library/selection_node.py +++ b/library/selection_node.py @@ -9,7 +9,6 @@ def nearest_node_from_offset(root,atok,offset): converter = atok._line_numbers - inside = lambda x,y: (y[0]<=x Date: Fri, 24 Apr 2020 19:14:09 +0300 Subject: [PATCH 10/45] Update 0.1.2.txt --- messages/0.1.2.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/0.1.2.txt b/messages/0.1.2.txt index f3ac99b..ce38675 100644 --- a/messages/0.1.2.txt +++ b/messages/0.1.2.txt @@ -2,7 +2,7 @@ CRITICAL UPDATE ===================== -My sincerest apologies but up to release 0.1.1 a subtle yet critical installation step was not documented, which may have prevented you from using the plug-in altogether! +My sincerest apologies but up to release 0.1.1 a subtle yet critical installation step was not documented, which may have prevented you from using the plug-in altogether! You can find more information at https://github.com/mpourmpoulis/PythonVoiceCodingPlugin/issues/15 but release 0.1.2 should make that installation step redundant for most users, so SIMPLY UPGRADING and replacing the grammar files should be enough without any further action on your part! From e1618406d41113c8c79ced053139df63435f9a26 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sat, 25 Apr 2020 02:47:44 +0300 Subject: [PATCH 11/45] Include ast.ExceptHandler in the big statements Technically it is not considered a statement in the Python AST But for our purposes it can serve such a role Resolves #20 --- queries/argument.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries/argument.py b/queries/argument.py index 927a67e..735d88a 100644 --- a/queries/argument.py +++ b/queries/argument.py @@ -50,7 +50,7 @@ def get_statement(self,origin,atok): print("\norigin\n",ast.dump(origin)) self.global_constrained_space = None candidate_statement = search_upwards(origin,ast.stmt) - big = (ast.If,ast.While,ast.For,ast.FunctionDef,ast.With,ast.ClassDef,ast.Try) + big = (ast.If,ast.While,ast.For,ast.FunctionDef,ast.With,ast.ClassDef,ast.Try,ast.ExceptHandler) if match_node(candidate_statement,big): candidate_statement = search_upwards_for_parent(origin,ast.stmt) candidate_statement = candidate_statement if candidate_statement else search_upwards(origin,ast.stmt) From dc86edc332806c3e370bd3fa7b3011759edab037 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sat, 25 Apr 2020 02:56:04 +0300 Subject: [PATCH 12/45] Add missing parent and parent field attributes in create fake in fixed_exception_handler Resolved #21 Without this addition, the default behavior of the create fake function is `fake_node.parent = root.parent if parent is None else parent` Causing the exception name to have that ast.Try node as a parent instead of the exception handler --- library/info.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/info.py b/library/info.py index 018bdc6..1de5a5b 100644 --- a/library/info.py +++ b/library/info.py @@ -1135,7 +1135,8 @@ def fix_exception_handler(root,atok): token = atok.find_token(next_token(atok,token),tokenize.NAME, root.name) f = root.type.first_token f = atok.find_token(previous_token(atok,f),tokenize.NAME, "except",reverse = True) - fake_name_node = create_fake(root,ast.Name,real_tokens = token,id = token.string,ctx = ast.Load()) + fake_name_node = create_fake(root,ast.Name,real_tokens = token,id = token.string,ctx = ast.Load(), + parent = root,parent_field = "name") set_fake(root,"name",fake_name_node) # root.first_token=root.type.first_token # root.last_token = token From 099e87fb101d28ba5e36a104b2359df51d3d632a Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sat, 25 Apr 2020 02:57:37 +0300 Subject: [PATCH 13/45] Remove some debugging stuff --- library/info.py | 2 +- queries/argument.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/info.py b/library/info.py index 1de5a5b..8f9aacc 100644 --- a/library/info.py +++ b/library/info.py @@ -1130,7 +1130,7 @@ def fix_exception_handler(root,atok): if not root.type or not root.name: mark_fixed(root) return True - print("Exception Handler:\n",[root.first_token,root.last_token]) + token = root.type.last_token token = atok.find_token(next_token(atok,token),tokenize.NAME, root.name) f = root.type.first_token diff --git a/queries/argument.py b/queries/argument.py index 735d88a..f2d6e03 100644 --- a/queries/argument.py +++ b/queries/argument.py @@ -26,7 +26,7 @@ class SelectArgument(SelectionQuery): multiple_in = True def get_information(self,query_description): - print(self,query_description) + # print(self,query_description) if "argument_index" in query_description: if query_description["argument_index"]==0: return make_information(get_argument_from_empty_call) @@ -47,7 +47,7 @@ def get_information(self,query_description): return identity(match_node,ast.Call) def get_statement(self,origin,atok): - print("\norigin\n",ast.dump(origin)) + # print("\norigin\n",ast.dump(origin)) self.global_constrained_space = None candidate_statement = search_upwards(origin,ast.stmt) big = (ast.If,ast.While,ast.For,ast.FunctionDef,ast.With,ast.ClassDef,ast.Try,ast.ExceptHandler) From abf08059ca731c8ef3011b72f07e7406c6ca3244 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sun, 26 Apr 2020 02:50:49 +0300 Subject: [PATCH 14/45] Fix a bug that rejected keywords following a : inside a single-line compound resolves #22 --- library/repair.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/library/repair.py b/library/repair.py index 2137ba9..8d99906 100644 --- a/library/repair.py +++ b/library/repair.py @@ -168,7 +168,13 @@ def after_double_dot(t): return t[1] is None or not( start_atom(t[1]) or t[1].string.isspace() or - t[1].string=="]" + t[1].string in [ + "]","assert","raise" + "break","continue","pass", + "return","yield","await","del", + "global","nonlocal", + "import","from" + ] ) def before_double_dot(t): From 41dedf9bb4376fb7c539fdbdffa8b730016f9f4f Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sun, 26 Apr 2020 16:08:41 +0300 Subject: [PATCH 15/45] Bug fix, odd quote = False so as to avoid escaping quotes escaping quotes was the root of #23 They should not be Resolved --- interface/common/actions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/common/actions.py b/interface/common/actions.py index f79ce57..d5ddab0 100644 --- a/interface/common/actions.py +++ b/interface/common/actions.py @@ -232,10 +232,11 @@ class PopUpErrorAction(InterfaceAction): """docstring for DisplayErrorAction""" def __init__(self, text): self.text = text + def execute(self,view,settings, sublime,**kwargs): if not settings.get("show_error",False): return - final_text = "

Something is off!" + "

" + html.escape(self.text) + "

" + final_text = "

Something is off!" + "

" + html.escape(self.text,quote = False) + "

" def on_hide(): view.show_popup(final_text,max_width=1024, max_height=10000, flags= sublime.HIDE_ON_MOUSE_MOVE_AWAY) view.show_popup(final_text,max_width=1024, max_height=10000, From 090043cd653880bd25cc9fd8262967c162da17b7 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Mon, 4 May 2020 20:05:48 +0300 Subject: [PATCH 16/45] stuff For pylint and travis --- .pylintrc | 10 ++++++++++ .travis.yml | 14 ++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 .pylintrc create mode 100644 .travis.yml diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..d676d5e --- /dev/null +++ b/.pylintrc @@ -0,0 +1,10 @@ +[TYPECHECK] +ignored-modules=sublime,sublime_plugin,package_control + +[MASTER] +# init-hook='import sys; sys.path.append("C:\\Users\\Admin\\AppData\\Roaming\\Sublime Text 3\\Packages")' +init-hook="from pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.dirname(os.path.dirname(find_pylintrc())))" + +[MESSAGES CONTROL] +disable=all +enable=E \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c939029 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: python +jobs: + include: + - name: "Windows Lint" + os: windows + language: sh + python: "3.7" + cache: pip + before_install: + - choco install python --version 3.7.3 + - export PATH="/c/Python37:/c/Python37/Scripts:$PATH" + - pip install pylint + script: + - pylint library && pylint queries && pylint application && pylint interface From 417185a728b8a5d7a0e26e9e650be218eaa04d42 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Mon, 4 May 2020 20:15:11 +0300 Subject: [PATCH 17/45] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c939029..4138ace 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,4 +11,4 @@ jobs: - export PATH="/c/Python37:/c/Python37/Scripts:$PATH" - pip install pylint script: - - pylint library && pylint queries && pylint application && pylint interface + - pylint library queries application interface python_voice_coding_plugin.py From 67f064715518770d9ab5634c8d3ce229ddaaa103 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 5 May 2020 01:47:13 +0300 Subject: [PATCH 18/45] Decorate handle_single,handle_multiple with @abc.abstractmethod to prevent pylint E1111 --- queries/abstract/collection_query.py | 5 ++++- queries/abstract/insertion_query.py | 5 +++++ queries/abstract/selection_query.py | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/queries/abstract/collection_query.py b/queries/abstract/collection_query.py index 8a82946..2b9f0b6 100644 --- a/queries/abstract/collection_query.py +++ b/queries/abstract/collection_query.py @@ -1,3 +1,4 @@ +import abc from copy import deepcopy from PythonVoiceCodingPlugin.library import get_source_region from PythonVoiceCodingPlugin.library.selection_node import nearest_node_from_offset,node_from_range @@ -13,9 +14,11 @@ class CollectionQuery(Query): select_insertion = True label = "Collection" + @abc.abstractmethod def handle_single(self,view_information,query_description,extra = {}): pass - + + @abc.abstractmethod def handle_multiple(self,view_information,query_description,extra = {}): pass diff --git a/queries/abstract/insertion_query.py b/queries/abstract/insertion_query.py index 7ac4ff9..68441cf 100644 --- a/queries/abstract/insertion_query.py +++ b/queries/abstract/insertion_query.py @@ -1,4 +1,6 @@ +import abc from copy import deepcopy + from PythonVoiceCodingPlugin.library import get_source_region from PythonVoiceCodingPlugin.library.modification import ModificationHandler from PythonVoiceCodingPlugin.queries.abstract.query import Query @@ -11,9 +13,12 @@ class InsertionQuery(Query): ################################################################ multiple_in = False select_insertion = True + + @abc.abstractmethod def handle_single(self,view_information,query_description,extra = {}): pass + @abc.abstractmethod def handle_multiple(self,view_information,query_description,extra = {}): pass diff --git a/queries/abstract/selection_query.py b/queries/abstract/selection_query.py index cd43b2c..c942a56 100644 --- a/queries/abstract/selection_query.py +++ b/queries/abstract/selection_query.py @@ -1,3 +1,4 @@ +import abc from copy import deepcopy from PythonVoiceCodingPlugin.library import get_source_region @@ -10,9 +11,12 @@ class SelectionQuery(Query): multiple_in = False initial_origin_force_update = False + @abc.abstractmethod def handle_single(self,view_information,query_description,extra = {}): pass + + @abc.abstractmethod def handle_multiple(self,view_information,query_description,extra = {}): pass From 00bdf01804057de77f820a1468c4ef6401b19cc3 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 5 May 2020 01:50:26 +0300 Subject: [PATCH 19/45] Fixed missing self In modification handler --- library/modification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/modification.py b/library/modification.py index cd38e99..3b88b95 100644 --- a/library/modification.py +++ b/library/modification.py @@ -58,7 +58,7 @@ def add_modification_from(self,timestamp, origin, destination,original_code = return self.add_modification(origin, destination, original_code, destination_code,comment) def add_modification_updated(self, origin, destination,original_code = None,destination_code = "", comment= None): - return add_modification_from(self.current_time, origin, destination,original_code ,destination_code , comment) + return self.add_modification_from(self.current_time, origin, destination,original_code ,destination_code , comment) From f8a842aee68b8b7bbb4495a9878ffa6d529e2bf4 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 5 May 2020 02:05:57 +0300 Subject: [PATCH 20/45] Fix various small mistakes --- library/info.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/library/info.py b/library/info.py index 8f9aacc..bf524f3 100644 --- a/library/info.py +++ b/library/info.py @@ -129,8 +129,9 @@ def fake_attribute_from_tokens(root,tokens,**kwargs): def is_store(root): return match_node(root,ast.Store) or (match_node(root,ast.Name) and match_node(root.ctx,ast.Store)) + def single(root): - return match_parent(node,(),ast.Attribute) + return match_parent(root,(),ast.Attribute) def name(root): return match_node(root,ast.Name) @@ -207,8 +208,6 @@ def get_weak_header(root,atok): root.items if match_node(root,(ast.With)) else root.type if match_node(root,(ast.ExceptHandler)) else None ) -def get_body(root): - return root.body if match_node(root,(ast.IfExp, ast.If ,ast.For,ast.While, ast.Try)) else None @@ -255,12 +254,12 @@ def get_return_value(root): # need to revisit def get_elements(root): return ( - root.elts if hasattr(root,elts) else None + root.elts if hasattr(root,"elts") else None ) def get_context(root): return ( - root.ctx if hasattr(root,ctx) else None + root.ctx if hasattr(root,"ctx") else None ) def get_key_value(root): From d9cd502999290111dba1b910970dcd61e2dc435f Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 5 May 2020 02:32:43 +0300 Subject: [PATCH 21/45] Fix error in calling line_partial and support for Single-point select_part The Main news are Argument queries into sub indexing queries were calling line_partial Missing an argument(the code) ( from the age of the dinosaurs 5f6fc5a5 and More recently d9a049ed respectively) . With this fixed,As long as the code tokenize correctly, If there is a syntax error somewhere else in the code that is unrecoverable, those queries can parse only the current logical line instead --- library/selection_node.py | 4 ++-- queries/argument.py | 10 +++++----- queries/select_part.py | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/library/selection_node.py b/library/selection_node.py index 74103d4..d7cda9a 100644 --- a/library/selection_node.py +++ b/library/selection_node.py @@ -7,7 +7,7 @@ from PythonVoiceCodingPlugin.library.info import generic_fix,get_sub_index from PythonVoiceCodingPlugin.library.traverse import match_node -def nearest_node_from_offset(root,atok,offset): +def nearest_node_from_offset(root,atok,offset,special=False): converter = atok._line_numbers original_token = atok.get_token_from_offset(offset) token = original_token @@ -21,7 +21,7 @@ def nearest_node_from_offset(root,atok,offset): if following: token = following s = token.startpos - return node_from_range(root,atok,(s,s),special= False,lenient = True) + return node_from_range(root,atok,(s,s),special= special,lenient = True) def node_from_range_old(root,atok, r ): inside = lambda x,y: (y[0]<=x[0] argument ############################################################### selection = self._get_selection(view_information,extra) - build = self.general_build if self.general_build else line_partial(selection[0]) + build = self.general_build if self.general_build else line_partial(self.code,selection[0]) if not build or not build[0] : return None,None root,atok,m,r = build @@ -208,7 +208,7 @@ def case_two(self,view_information,query_description, extra = {}): ndir = 0 - build = self.general_build if self.general_build else line_partial(selection[0]) + build = self.general_build if self.general_build else line_partial(self.code,selection[0]) if not build or not build[0] : return None,None root,atok,m,r = build @@ -259,7 +259,7 @@ def case_three(self,view_information,query_description, extra = {}): # inside argument ############################################################### selection = self._get_selection(view_information,extra) - build = self.general_build if self.general_build else line_partial(selection[0]) + build = self.general_build if self.general_build else line_partial(self.code,selection[0]) if not build or not build[0] : return None,None root,atok,m,r = build @@ -315,7 +315,7 @@ def case_four(self,view_information,query_description, extra = {}): # [] (argument |caller []) ############################################################### selection = self._get_selection(view_information,extra) - build = self.general_build if self.general_build else line_partial(selection[0]) + build = self.general_build if self.general_build else line_partial(self.code,selection[0]) if not build or not build[0] : return None,None root,atok,m,r = build @@ -371,7 +371,7 @@ def case_five(self,view_information,query_description, extra = {}): # [] (argument |caller []) ############################################################### selection = self._get_selection(view_information,extra) - build = self.general_build if self.general_build else line_partial(selection[0]) + build = self.general_build if self.general_build else line_partial(self.code,selection[0]) if not build or not build[0] : return None,None root,atok,m,r = build diff --git a/queries/select_part.py b/queries/select_part.py index ec90762..b36e5dc 100644 --- a/queries/select_part.py +++ b/queries/select_part.py @@ -21,14 +21,15 @@ class SelectPart(SelectionQuery): def handle_single(self,view_information,query_description,extra = {}): # print(" inside here selection where he parked ") selection = self._get_selection(view_information,extra) - build = self.general_build if self.general_build else line_partial(selection[0]) + build = self.general_build if self.general_build else line_partial(self.code,selection[0]), if not build or not build[0] : return None,None root,atok,m,r = build selection = m.forward(selection) origin = nearest_node_from_offset(root,atok, selection[0],special = True) if selection[0]==selection[1] else node_from_range(root,atok, selection,special = True) if selection[0]==selection[1]: - return None,None + # return None,None + pass second_origin = origin if "nth" in query_description: # print(" hello world ") From 4e66b2d10291ebadc56b60d8cd2f94b0ae5fe2b8 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 5 May 2020 02:36:55 +0300 Subject: [PATCH 22/45] Small cleanup --- library/traverse.py | 4 +- queries/old_argument.py | 117 ---------------------------------------- 2 files changed, 2 insertions(+), 119 deletions(-) delete mode 100644 queries/old_argument.py diff --git a/library/traverse.py b/library/traverse.py index a6cd16b..9e96160 100644 --- a/library/traverse.py +++ b/library/traverse.py @@ -94,6 +94,6 @@ def select_from_up(node, target, attribute, outside_level, index = None): return None -def select_region_from_node_up(root, atok, node, target, attribute, outside_level, index = None): - return get_source_region(select_from_node(root, atok, node, target, attribute, outside_level, index)) +# def select_region_from_node_up(root, atok, node, target, attribute, outside_level, index = None): +# return get_source_region(select_from_node(root, atok, node, target, attribute, outside_level, index)) diff --git a/queries/old_argument.py b/queries/old_argument.py deleted file mode 100644 index f5fa3a9..0000000 --- a/queries/old_argument.py +++ /dev/null @@ -1,117 +0,0 @@ -import ast - -from PythonVoiceCodingPlugin.library import nearest_node_from_offset,sorted_by_source_region,get_source_region,node_from_range -from PythonVoiceCodingPlugin.library.info import identity,get_argument_from_call -import PythonVoiceCodingPlugin.library.info as info -from PythonVoiceCodingPlugin.library.level_info import LevelVisitor -from PythonVoiceCodingPlugin.library.partial import partially_parse, line_partial -from PythonVoiceCodingPlugin.library.traverse import search_upwards,search_upwards_log, find_matching,match_node, find_all_nodes - -from PythonVoiceCodingPlugin.queries.abstract import SelectionQuery -from PythonVoiceCodingPlugin.queries.tiebreak import tiebreak_on_lca -from PythonVoiceCodingPlugin.queries.strategies import adjective_strategy - -def obtain_result(result, alternatives): - if result: - return result, alternatives if alternatives is not None else [] - else: - if alternatives is None or len( alternatives )==0: - return None,None - else: - return alternatives[0], alternatives[1:] - - - - -class SelectArgument(SelectionQuery): - """docstring for SelectArgument""" - # def __init__(self): - # super(SelectArgument, self).__init__() - - - - def handle_single_point(self,view_information,query_description): - f = query_description["format"] - possibilities = { - 1: self.case_one, - } - return possibilities[f](view_information,query_description) - - def case_one(self,v,q): - """ - argument - """ - selection = v["selection"] - build = self.general_build if self.general_build else line_partial(selection[0]) - print(build) - if not build: - return None,None - root,atok,m,r = build - selection = m.forward(selection) - - # after build we set up some variables - result = None - alternatives = None - - origin = nearest_node_from_offset(root,atok, selection[0]) - calling_node = search_upwards(origin,ast.Call) - statement_node, callers = search_upwards_log(origin,ast.stmt,log_targets = ast.Call) - information = lambda x: info.get_argument_from_call(x,q["argument_index"]-1) - candidates = sorted_by_source_region(atok, find_matching(statement_node, info.identity(information))) - every_caller = find_all_nodes(statement_node,(ast.Call)) - - - - ################################################################ - # if no adjective is given - ################################################################ - if q["adjective"] == "None": - if calling_node: - result = information(calling_node) - candidates = [information(x) for x in tiebreak_on_lca(statement_node,origin, candidates) if x != calling_node] - result,alternatives = obtain_result(result,candidates) - - ################################################################ - # adjective is even - ################################################################ - if q["adjective"] != "None": - additional_parameters = {} - if selection[0]!=selection[1]: - small_root = node_from_range(root,atok,selection) - additional_parameters["small_root"]=small_root - print("dumping the small root\n",ast.dump(small_root)) - additional_parameters["special"] = [calling_node] - if calling_node: - print(ast.dump(calling_node)) - additional_parameters["penalized"] = [calling_node] - result, alternatives = adjective_strategy( - atok=atok, - root = root, - adjective_word = q["adjective"], - level_nodes = every_caller, - information_nodes = candidates, - **additional_parameters - ) - result = information(result) if result else m.forward(v["selection"]) - alternatives =[ information(x) for x in alternatives] if alternatives else [] - - - - # translate those nodes back to offsets and forward them through the modification under - print("\n\nnow finally printing result and alternatives\n\n") - print( result ) - print(ast.dump( result ) if isinstance( result, ast.AST ) else " not known node") - print( alternatives ) - result = m.backward(get_source_region(atok, result)) - alternatives = [m.backward(get_source_region(atok,x)) for x in alternatives] - return result,alternatives - - - - - - - - - - From f662883faf8714b8be8557a8ebf021fc032efa24 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Thu, 7 May 2020 01:39:20 +0300 Subject: [PATCH 23/45] Temporary --- application/application.py | 1 + library/selection_node.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/application/application.py b/application/application.py index 8565726..44d1e07 100644 --- a/application/application.py +++ b/application/application.py @@ -77,6 +77,7 @@ def respond_to_query(self,interface,query_description,secondary=False): except Exception as e: # check if there are exceptions with parsing if s.exceptions_raised: + # traceback.print_tb(s.exceptions_raised) interface.clear_actions() interface.push_action(PopUpErrorAction(str(s.exceptions_raised))) return False diff --git a/library/selection_node.py b/library/selection_node.py index d7cda9a..954d210 100644 --- a/library/selection_node.py +++ b/library/selection_node.py @@ -20,8 +20,12 @@ def nearest_node_from_offset(root,atok,offset,special=False): following = next_token(atok,original_token) if following: token = following + raise Exception("boom") s = token.startpos - return node_from_range(root,atok,(s,s),special= special,lenient = True) + r = node_from_range(root,atok,(s,s),special= special,lenient = True) + print("r",r,ast.dump(r)) + raise Exception("boom") + return r def node_from_range_old(root,atok, r ): inside = lambda x,y: (y[0]<=x[0] Date: Thu, 7 May 2020 20:58:08 +0300 Subject: [PATCH 24/45] Neighbor should be none instead of end of file token And additional check for none resolves #26 A check for none was missingAce but more importantly most of the functions expected none values When at the end of file But received EOF token instead --- library/repair.py | 3 ++- library/selection_node.py | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/library/repair.py b/library/repair.py index 8d99906..4c321b0 100644 --- a/library/repair.py +++ b/library/repair.py @@ -18,6 +18,7 @@ def get_dummy(atok): def neighbors(atok,t): x = next_token(atok,t) + x = x if x and x.type != 0 else None y = next_token(atok,x) if x else None z = previous_token(atok,t) w = previous_token(atok,z) if z else None @@ -123,7 +124,7 @@ def after_both_sides(t): return t[1] is None or not( start_atom(t[1]) or t[1].string in STARTING_UNARY or - (t[1].string,t[2].string) in STARTING_UNARY + (t[2] is not None and (t[1].string,t[2].string) in STARTING_UNARY) ) def before_both_sides(t): diff --git a/library/selection_node.py b/library/selection_node.py index 954d210..bbf1c56 100644 --- a/library/selection_node.py +++ b/library/selection_node.py @@ -17,14 +17,11 @@ def nearest_node_from_offset(root,atok,offset,special=False): following = next_token(atok,original_token) while following and following.string.isspace(): token = following - following = next_token(atok,original_token) + following = next_token(atok,token) if following: token = following - raise Exception("boom") s = token.startpos r = node_from_range(root,atok,(s,s),special= special,lenient = True) - print("r",r,ast.dump(r)) - raise Exception("boom") return r def node_from_range_old(root,atok, r ): From 8666dbccce19001c106c04801540f43283c8b766 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Fri, 8 May 2020 20:02:39 +0300 Subject: [PATCH 25/45] Bug fix. add check To prevent off by one errorsThese are the boundaries of functions While normally, if on an empty line origin is going to bound to the line below, On the boundaries between functions It will bound upwards by design. Unfortunately, These caused An issue because to prevent all my one errors When going upwards When the statements spread over multiple lines, there were checks if we were below its beginning but not thief we were above its ending( because otherwise Origin would normally bound to the linee below!). These commit Add those checks and resolve #28 --- queries/big_roi.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/queries/big_roi.py b/queries/big_roi.py index 0e19218..9563b06 100644 --- a/queries/big_roi.py +++ b/queries/big_roi.py @@ -226,7 +226,11 @@ def case_three(self,view_information,query_description, extra = {}): test_result = decode_abstract_vertical(root,atok,targets,row+1, 1,direction,True, temporary_information,want_alternatives = False) l = search_upwards_log(origin,ast.stmt) - if test_result in [l[0]] + l[1] and row + 1>=test_result.first_token.start[0]: + if (test_result in [l[0]] + l[1] and + row + 1>=test_result.first_token.start[0] and + row + 1<=test_result.last_token.end[0] + ): + ndir = ndir + 1 From bc3c542dfa859e9d7af79be93b59f4c5afa0b5ff Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sat, 9 May 2020 18:26:58 +0300 Subject: [PATCH 26/45] Restructure priority reestablishing and allow for an object of strategy to be completely crossed out Implements #27 while the same time making reestablishing priority function more readable. At the same time, penalizing now happens Within the result accumulateor --- queries/strategies/primitives.py | 7 ++--- queries/utility.py | 53 +++++++++++++++++--------------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/queries/strategies/primitives.py b/queries/strategies/primitives.py index 4ae130c..76bd473 100644 --- a/queries/strategies/primitives.py +++ b/queries/strategies/primitives.py @@ -10,7 +10,7 @@ def root_level_order(accumulator,root,level,index,only_information,priority,pena else: first_option = None if not only_information or True: - accumulator.push(second_option,priority if not first_option else priority + penalty) + accumulator.push(second_option,priority,penalty = 0 if not first_option else penalty) def root_lexical_order(accumulator,root,level_nodes,information_nodes,index, only_information,priority,penalty,lca = None,constrained_space = None): @@ -30,8 +30,7 @@ def root_lexical_order(accumulator,root,level_nodes,information_nodes,index, else: first_option = None if not only_information or True: - accumulator.push(second_option,priority if not first_option else priority + penalty) - + accumulator.push(second_option,priority,penalty = 0 if not first_option else penalty) def child_level_older(accumulator,child_list,level,index,only_information,priority): for i, child in enumerate(child_list) : @@ -41,7 +40,7 @@ def child_level_older(accumulator,child_list,level,index,only_information,priori # print("rejected_candidate", candidate, "from child", child) if candidate in level.special and (only_information == False or y==True): # from - accumulator.push(candidate,priority + i + counter) + accumulator.push(candidate,priority,penalty = i + counter) counter += 1 diff --git a/queries/utility.py b/queries/utility.py index aaf9576..d0560ca 100644 --- a/queries/utility.py +++ b/queries/utility.py @@ -1,21 +1,21 @@ -import ast - def reestablish_priority(initial,adjusted): - z = {initial[v]:v for v in initial} - w = {adjusted[v]:v for v in adjusted} - x = sorted(z.keys()) - y = sorted(w.keys()) - s = set(y) - if len(y)!=len(s): - return initial - output=adjusted - index = 1 - for i in x: - if z[i] not in output: - while index in s: - index += 1 - output[z[i]] = index - s.add(index) + output={} + to_be_removed = {k for k,v in adjusted.items() if v<0} + initial_order = sorted(initial.items(),key=lambda x:x[1]) + adjusted_order = sorted(adjusted.items(),key=lambda x:x[1]) + already_assigned_values = set(adjusted.values()) + for k,v in adjusted_order: + output[k] = v + for k,v in initial_order: + if k not in output: + while v in already_assigned_values: + v = v + 1 + output[k] = v + already_assigned_values.add(v) + + if len(set(adjusted.keys())-to_be_removed)!=len(set(adjusted.values()))-(1 if to_be_removed else 0): + raise Exception("you cannot assign the same priority for two strategies",adjusted) + return output @@ -29,21 +29,26 @@ def __init__(self,penalized=[], penalty=0): self.penalty = penalty self.history = [] - def push(self,node,priority): + def push(self,node,priority,penalty = 0): self.history.append((node,priority)) - # print(" pushing", priority ) - # if not isinstance( node,ast.AST ) and not node is None: - # for x in node: - # print(ast.dump(x)) if not node: return None if node in self.penalized: - priority = priority + self.penalty - if priority not in self.accumulator: + priority = self.penalize(priority,self.penalty) + priority = self.penalize(priority,penalty) + if priority < 0: + return + elif priority not in self.accumulator: self.accumulator[priority] = [node] else: self.accumulator[priority].append(node) + def penalize(self,priority,penalty): + if priority<0: + return priority + else: + return priority+penalty + def get_result(self): visited = set() finalists = [] From 4cea12941afbe75bc8b1a929670e4df5725bc299 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sun, 10 May 2020 17:34:52 +0300 Subject: [PATCH 27/45] Add check So that selection With an offset of 0 Does not result in a node like ast.Store these came up during the Re-factoring for issue #19 --- library/selection_node.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/selection_node.py b/library/selection_node.py index bbf1c56..f517c19 100644 --- a/library/selection_node.py +++ b/library/selection_node.py @@ -37,10 +37,11 @@ def node_from_range_old(root,atok, r ): def node_from_range_new(root,atok,r,special = False,lenient = False): - # print(" inside the new note from range\n",root) - inside = lambda x,y: (y[0]<=x[0] Date: Sun, 10 May 2020 17:45:17 +0300 Subject: [PATCH 28/45] Remove pop-up error message for installation of 0.1.2 --- python_voice_coding_plugin.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/python_voice_coding_plugin.py b/python_voice_coding_plugin.py index 74288ef..fcaf3a4 100644 --- a/python_voice_coding_plugin.py +++ b/python_voice_coding_plugin.py @@ -21,17 +21,6 @@ def plugin_loaded(): settings = sublime.load_settings("python_voice_coding_plugin.sublime-settings") try : from package_control import events - if events.post_upgrade("PythonVoiceCodingPlugin"): - sublime.error_message( -""" -CRITICAL UPDATE PythonVoiceCodingPlugin -Up to release 0.1.1 a subtle yet critical installation step regarding communication between sublime and Caster was not documented, which may have prevented you from using the plug-in altogether! - -You can find more information at https://github.com/mpourmpoulis/PythonVoiceCodingPlugin/issues/15 but simply upgrading your Caster grammar should be enough! -For Caster 1.x.x users Preferences > Package Settings > PythonVoiceCodingPlugin >Quick 1.0.0 Install may make these process faster! - -My sincerest apologies! -""") except : pass From 1973b449229645781bef6051869558414f4b69f3 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sun, 10 May 2020 20:10:52 +0300 Subject: [PATCH 29/45] Remove accidental comma I must have fixed this blog at least three times and Then stashed the changes --- queries/select_part.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries/select_part.py b/queries/select_part.py index b36e5dc..a25159c 100644 --- a/queries/select_part.py +++ b/queries/select_part.py @@ -21,7 +21,7 @@ class SelectPart(SelectionQuery): def handle_single(self,view_information,query_description,extra = {}): # print(" inside here selection where he parked ") selection = self._get_selection(view_information,extra) - build = self.general_build if self.general_build else line_partial(self.code,selection[0]), + build = self.general_build if self.general_build else line_partial(self.code,selection[0]) if not build or not build[0] : return None,None root,atok,m,r = build From d576bd4cd5028ec7444a25933588141cd29d66bc Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sun, 10 May 2020 20:12:54 +0300 Subject: [PATCH 30/45] Revert "Remove accidental comma" This reverts commit 1973b449229645781bef6051869558414f4b69f3. --- queries/select_part.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries/select_part.py b/queries/select_part.py index a25159c..b36e5dc 100644 --- a/queries/select_part.py +++ b/queries/select_part.py @@ -21,7 +21,7 @@ class SelectPart(SelectionQuery): def handle_single(self,view_information,query_description,extra = {}): # print(" inside here selection where he parked ") selection = self._get_selection(view_information,extra) - build = self.general_build if self.general_build else line_partial(self.code,selection[0]) + build = self.general_build if self.general_build else line_partial(self.code,selection[0]), if not build or not build[0] : return None,None root,atok,m,r = build From c56568238467c299980f582f3d4fdb80933d54c7 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sun, 10 May 2020 20:13:12 +0300 Subject: [PATCH 31/45] Revert "Revert "Remove accidental comma"" This reverts commit d576bd4cd5028ec7444a25933588141cd29d66bc. --- queries/select_part.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries/select_part.py b/queries/select_part.py index b36e5dc..a25159c 100644 --- a/queries/select_part.py +++ b/queries/select_part.py @@ -21,7 +21,7 @@ class SelectPart(SelectionQuery): def handle_single(self,view_information,query_description,extra = {}): # print(" inside here selection where he parked ") selection = self._get_selection(view_information,extra) - build = self.general_build if self.general_build else line_partial(self.code,selection[0]), + build = self.general_build if self.general_build else line_partial(self.code,selection[0]) if not build or not build[0] : return None,None root,atok,m,r = build From 0cf75183d2169d60b26b40d0ec9f38b3736c421d Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Sun, 10 May 2020 22:20:26 +0300 Subject: [PATCH 32/45] Bug fix: make node_from_range Correctly yielded decorator when the cursor is at the beginning of the line or the whole line is selected resolves #30 --- library/selection_node.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/library/selection_node.py b/library/selection_node.py index f517c19..fc94dea 100644 --- a/library/selection_node.py +++ b/library/selection_node.py @@ -24,16 +24,6 @@ def nearest_node_from_offset(root,atok,offset,special=False): r = node_from_range(root,atok,(s,s),special= special,lenient = True) return r -def node_from_range_old(root,atok, r ): - inside = lambda x,y: (y[0]<=x[0] Date: Mon, 11 May 2020 14:43:16 +0300 Subject: [PATCH 33/45] Make LCA tie-breaking Aware of keyvalue pairs Implements #31 --- library/LCA.py | 9 ++++++--- queries/tiebreak.py | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/library/LCA.py b/library/LCA.py index 5d3bbc2..cfe4117 100644 --- a/library/LCA.py +++ b/library/LCA.py @@ -37,7 +37,7 @@ def visit(self, node): def get_depth(self, node): return self.sequence[self.visits[node][0]][0] - def __call__(self,first_node,second_node,include_depth = False): + def __call__(self,first_node,second_node,only_depth = False,node_and_depth = True): try : x,y = self.visits[first_node] w,v = self.visits[second_node] @@ -52,9 +52,12 @@ def __call__(self,first_node,second_node,include_depth = False): r = max(y,v) ancestor = self.tree.query(l,r,"min") - if include_depth: + if node_and_depth: + return ancestor + elif only_depth: return ancestor[0] - return ancestor[1] + else: + return ancestor[1] def get_field_with_respect_to(self,node,parent_node): index = bisect.bisect_left(self.field_history[parent_node],(self.visits[node][0],)) diff --git a/queries/tiebreak.py b/queries/tiebreak.py index f2ba972..03ce016 100644 --- a/queries/tiebreak.py +++ b/queries/tiebreak.py @@ -2,7 +2,7 @@ from PythonVoiceCodingPlugin.library.LCA import LCA from PythonVoiceCodingPlugin.library.level_info import LevelVisitor - +from PythonVoiceCodingPlugin.library.traverse import match_node @@ -21,8 +21,18 @@ def tiebreak_on_lca(root,origin,candidates): TYPE: Description """ lca = LCA(root) - k = lambda x: (-1 * lca(x, origin,True),lca.get_depth(x),abs(x.first_token.start[0] - origin.first_token.start[0])) - return sorted(candidates, key = k) + def tiebreaker(x): + depth,node = lca(x, origin,node_and_depth = True) + v = 3 + if match_node(node,ast.Dict): + if node is not x and node is not origin: + field,field_index = lca.get_field_with_respect_to(x,node) + ofield,ofield_index = lca.get_field_with_respect_to(origin,node) + v = abs(field_index - ofield_index) + v = v if v<3 else 3 + return (-1 * depth,v,lca.get_depth(x),abs(x.first_token.start[0] - origin.first_token.start[0])) + + return sorted(candidates, key = tiebreaker) From 38a05605da3adc710bb7790cd3e73e808f68ae10 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Mon, 20 Jul 2020 17:15:19 +0300 Subject: [PATCH 34/45] Minor cleanup selection_node --- library/selection_node.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/library/selection_node.py b/library/selection_node.py index fc94dea..ca4e761 100644 --- a/library/selection_node.py +++ b/library/selection_node.py @@ -33,7 +33,6 @@ def node_from_range_new(root,atok,r,special = False,lenient = False): if lenient: inside = lambda x,y: (y[0]<=x[0]<=y[1] and y[0]<=x[1]<=y[1] and not y[0]==y[1]==0) generic_fix(root,atok) - # print(" the fields are now",root._fields) for child in ast.iter_child_nodes(root): # print(" just to check something out",child,atok.get_text_range(child)) # print(" and the child fields are ",child._fields) @@ -80,10 +79,8 @@ def node_from_range_old(root,atok, r ): inside = lambda x,y: (y[0]<=x[0] Date: Mon, 20 Jul 2020 18:43:26 +0300 Subject: [PATCH 35/45] Update Main.sublime-menu to point To the new readthedocs documentation --- Main.sublime-menu | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Main.sublime-menu b/Main.sublime-menu index 1181340..295587c 100644 --- a/Main.sublime-menu +++ b/Main.sublime-menu @@ -35,49 +35,49 @@ "caption": "Argument Queries", "command": "open_url", "args":{ - "url": "http://github.com/mpourmpoulis/PythonVoiceCodingPlugin/blob/master/doc/SelectArgument.md" + "url": "https://pythonvoicecodingplugin.readthedocs.io/en/latest/SelectArgument/" } }, { "caption": "Big Roi Queries", "command": "open_url", "args":{ - "url":"https://github.com/mpourmpoulis/PythonVoiceCodingPlugin/blob/master/doc/SelectBigROI.md" + "url":"https://pythonvoicecodingplugin.readthedocs.io/en/latest/SelectBigROI/" } }, { "caption": "General Documentation", "command": "open_url", "args":{ - "url":"https://github.com/mpourmpoulis/PythonVoiceCodingPlugin/blob/master/doc/README.md" + "url":"https://pythonvoicecodingplugin.readthedocs.io/en/latest/" } }, { "caption": "Operations", "command": "open_url", "args":{ - "url": "https://github.com/mpourmpoulis/PythonVoiceCodingPlugin/blob/master/doc/Operations.md" + "url": "https://pythonvoicecodingplugin.readthedocs.io/en/latest/Operations/" } }, { "caption": "Sub Indexing", "command": "open_url", "args":{ - "url": "https://github.com/mpourmpoulis/PythonVoiceCodingPlugin/blob/master/doc/SubIndexing.md" + "url": "https://pythonvoicecodingplugin.readthedocs.io/en/latest/SubIndexing/" } }, { "caption": "CollectionQueries", "command": "open_url", "args":{ - "url": "https://github.com/mpourmpoulis/PythonVoiceCodingPlugin/blob/master/doc/CollectionQueries.md" + "url": "https://pythonvoicecodingplugin.readthedocs.io/en/latest/CollectionQueries/" } }, { "caption": "Unofficial", "command": "open_url", "args":{ - "url": "https://github.com/mpourmpoulis/PythonVoiceCodingPlugin/blob/master/doc/README.md#experiment-or-unofficial-and-so-on-features-you-need-to-enable-manually" + "url": "https://pythonvoicecodingplugin.readthedocs.io/en/latest/#experiment-or-unofficial-and-so-on-features-you-need-to-enable-manually" } } @@ -125,7 +125,7 @@ "caption": "Grammar Installation Doc", "command": "open_url", "args":{ - "url": "https://github.com/mpourmpoulis/PythonVoiceCodingPlugin/blob/master/bundles/README.md" + "url": "https://pythonvoicecodingplugin.readthedocs.io/en/latest/Installation/" } }, { From acbf56e073f8864f2b02b0e4907b2d9ccdb76a44 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Mon, 20 Jul 2020 20:48:23 +0300 Subject: [PATCH 36/45] Prompt the user for the quick installation utility right after install! --- quick_install_python_voice_coding_plugin.py | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/quick_install_python_voice_coding_plugin.py b/quick_install_python_voice_coding_plugin.py index 5a881ba..800d3ed 100644 --- a/quick_install_python_voice_coding_plugin.py +++ b/quick_install_python_voice_coding_plugin.py @@ -4,6 +4,33 @@ import sublime import sublime_plugin +greeting = ''' +Thanks for trying out PythonVoiceCodingPlugin! + +To complete your installation, you need to copy the bundled grammar for your version of Caster into your appropriate Caster user directory. Afterwards reboot Caster and if needed enable the grammar by saying + +enable python voice coding plugin + +You can retrieve those grammars under + +Preferences > Package Settings > PythonVoiceCodingPlugin + +where you will also find links to documentation with lots of examples and my gitter chatroom for questions and troubleshooting. + +To make your life easier with the copy pasting, if you're on windows and using Caster 1.x.x, there is also utility to handle this process automatically for you! Do you want to run it? +''' + + +def plugin_loaded(): + window = sublime.active_window() + try : + from package_control import events + if events.install("PythonVoiceCodingPlugin"): + if sublime.yes_no_cancel_dialog(greeting)!=sublime.DIALOG_YES: + return + window.run_command("quick_install_python_voice_coding_plugin",{}) + except : + pass From bebe6f1f19ed6d01afc90db7a94db362481879ab Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 21 Jul 2020 01:08:29 +0300 Subject: [PATCH 37/45] Version bump --- bundles/Caster/python_voice_coding_plugin_caster_v0-5-11.py | 2 +- bundles/Caster/python_voice_coding_plugin_caster_v0-6-11.py | 2 +- bundles/Caster/python_voice_coding_plugin_caster_v1-0-0.py | 2 +- python_voice_coding_plugin.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bundles/Caster/python_voice_coding_plugin_caster_v0-5-11.py b/bundles/Caster/python_voice_coding_plugin_caster_v0-5-11.py index d7b1b9d..6287b5c 100644 --- a/bundles/Caster/python_voice_coding_plugin_caster_v0-5-11.py +++ b/bundles/Caster/python_voice_coding_plugin_caster_v0-5-11.py @@ -37,7 +37,7 @@ ######################################################################################### -GRAMMAR_VERSION = (0,1,2) +GRAMMAR_VERSION = (0,1,3) ######################################################################################### diff --git a/bundles/Caster/python_voice_coding_plugin_caster_v0-6-11.py b/bundles/Caster/python_voice_coding_plugin_caster_v0-6-11.py index 7a0c115..9229d03 100644 --- a/bundles/Caster/python_voice_coding_plugin_caster_v0-6-11.py +++ b/bundles/Caster/python_voice_coding_plugin_caster_v0-6-11.py @@ -37,7 +37,7 @@ ######################################################################################### -GRAMMAR_VERSION = (0,1,2) +GRAMMAR_VERSION = (0,1,3) ######################################################################################### diff --git a/bundles/Caster/python_voice_coding_plugin_caster_v1-0-0.py b/bundles/Caster/python_voice_coding_plugin_caster_v1-0-0.py index f89cfaf..315f82a 100644 --- a/bundles/Caster/python_voice_coding_plugin_caster_v1-0-0.py +++ b/bundles/Caster/python_voice_coding_plugin_caster_v1-0-0.py @@ -37,7 +37,7 @@ ######################################################################################### -GRAMMAR_VERSION = (0,1,2) +GRAMMAR_VERSION = (0,1,3) ######################################################################################### diff --git a/python_voice_coding_plugin.py b/python_voice_coding_plugin.py index fcaf3a4..bc20c8e 100644 --- a/python_voice_coding_plugin.py +++ b/python_voice_coding_plugin.py @@ -11,7 +11,7 @@ from PythonVoiceCodingPlugin.interface.interface import Interface -PLUGIN_VERSION = (0,1,2) +PLUGIN_VERSION = (0,1,3) settings = {} already_message = False From cb0fb87fed53422d040c29b440d43975c822c6ba Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 21 Jul 2020 01:09:06 +0300 Subject: [PATCH 38/45] application: add staticmethod decorator --- application/application.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/application/application.py b/application/application.py index 44d1e07..2961ecf 100644 --- a/application/application.py +++ b/application/application.py @@ -30,10 +30,12 @@ def __init__(self,vid): self.ui_controller = None self.vid = vid + @staticmethod def create_application_for_view(vid): if vid not in Application.active_applications: Application.active_applications[vid] = Application(vid) + @staticmethod def get_application(vid): Application.create_application_for_view(vid) return Application.active_applications[vid] From 2861fc72cf1aa0372cb903eb4ea811b207a05432 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 21 Jul 2020 16:00:48 +0300 Subject: [PATCH 39/45] Fix problem with not checking None values in a nearest_node_from_offset relevant to their factoring going on due to #19 The loop was not checking if the token produced is None which caused problems when the cursor Was at the beginning of the file in an empty line --- library/selection_node.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/selection_node.py b/library/selection_node.py index ca4e761..764c5a8 100644 --- a/library/selection_node.py +++ b/library/selection_node.py @@ -11,9 +11,9 @@ def nearest_node_from_offset(root,atok,offset,special=False): converter = atok._line_numbers original_token = atok.get_token_from_offset(offset) token = original_token - while token.string.isspace() or not token.string: + while token and (not token.string or token.string.isspace()): token = previous_token(atok,token) - if converter.offset_to_line(offset)[0] != converter.offset_to_line(token.startpos)[0]: + if not token or converter.offset_to_line(offset)[0] != converter.offset_to_line(token.startpos)[0]: following = next_token(atok,original_token) while following and following.string.isspace(): token = following From b43492ab83d800b833fbadbddbdc3c18183c2d1c Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 21 Jul 2020 16:56:59 +0300 Subject: [PATCH 40/45] minor cleanup --- queries/abstract/selection_query.py | 1 - 1 file changed, 1 deletion(-) diff --git a/queries/abstract/selection_query.py b/queries/abstract/selection_query.py index c942a56..839c19e 100644 --- a/queries/abstract/selection_query.py +++ b/queries/abstract/selection_query.py @@ -44,7 +44,6 @@ def _backward_result(self,result,alternatives,build,individually = False): if build and build[0]: m = build[2] atok = build[1] - print("\n\n",self,result,alternatives,build,individually) if individually: result = [m.backward(get_source_region(atok, x)) if x else None for x in result] else: From e4a6b571fa1e3c65f99dc782dadcf1b3858a9a80 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 21 Jul 2020 17:05:52 +0300 Subject: [PATCH 41/45] Modify tiebreak_on_lca to accept an optional pre-build LCA These issue helps resolve #36 because inside queries needed to run a whole bunch of tie-breaking runs on smaller collections of data and the overhead of recomputing the LCA tree every time was skyrocketing their response time --- queries/argument.py | 5 ++--- queries/tiebreak.py | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/queries/argument.py b/queries/argument.py index 4a9f6ca..eed783c 100644 --- a/queries/argument.py +++ b/queries/argument.py @@ -303,7 +303,7 @@ def inverse_transformation(node): atok = atok, origin = origin, select_node = origin if selection[0]!=selection[1] else None, - tiebreaker = lambda x: tiebreak_on_lca(statement_node,origin,x), + tiebreaker = lambda x: tiebreak_on_lca(statement_node,origin,x,lca), transformation = transformation, inverse_transformation = inverse_transformation, @@ -356,7 +356,7 @@ def inverse_transformation(node): atok = atok, origin = origin, select_node = origin if selection[0]!=selection[1] else None, - tiebreaker = lambda x: tiebreak_on_lca(statement_node,origin,x), + tiebreaker = lambda x: tiebreak_on_lca(statement_node,origin,x,lca), transformation = transformation, inverse_transformation = inverse_transformation, @@ -383,7 +383,6 @@ def case_five(self,view_information,query_description, extra = {}): query_description["level_index"] = -1 _,calling_parents = search_upwards_log(origin,targets=ast.stmt,log_targets=(ast.Call)) index = query_description["level_index"] - print("the Dixie's ",index,len(calling_parents),"\n") if index Date: Tue, 21 Jul 2020 17:39:36 +0300 Subject: [PATCH 42/45] add invert_then_tiebreak argument to process_line Argument Queries This addition was neededSo the queries of the form "inside nth argument" would work properly. In particular, for these type of queries tiebreaking Needs to happen after inversion because we need to pick the closest call that satisfies the nth description with respect to its (local) parent. Otherwise, the result produced would not be even deterministic,as helpful will not be ordered!!! --- queries/argument.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/queries/argument.py b/queries/argument.py index eed783c..eacf987 100644 --- a/queries/argument.py +++ b/queries/argument.py @@ -62,7 +62,7 @@ def get_statement(self,origin,atok): def process_line(self,q, root ,atok, origin = None, select_node = None,tiebreaker = lambda x: x, line = None, transformation = None,inverse_transformation = None, priority = {}, - constrained_space = (), second_tiebreaker = None + constrained_space = (), second_tiebreaker = None,invert_then_tiebreak = True ): result = None alternatives = None @@ -131,7 +131,10 @@ def process_line(self,q, root ,atok, origin = None, select_node = None,tiebreak helpful = [result] if result else [] if alternatives: helpful.extend(alternatives) - temporary = make_flat([tiebreaker(inverse_transformation(x)) for x in helpful]) + if invert_then_tiebreak: + temporary = make_flat([tiebreaker(inverse_transformation(x)) for x in helpful]) + else: + temporary = tiebreaker(make_flat([inverse_transformation(x) for x in helpful])) result, alternatives = obtain_result(None,temporary) ################################################################ @@ -144,7 +147,7 @@ def process_line(self,q, root ,atok, origin = None, select_node = None,tiebreak temporary = [x[1] for x in temporary] result,alternatives = obtain_result(None,temporary) - if second_tiebreaker: + if result and second_tiebreaker: alternatives = second_tiebreaker(result,alternatives) if self.global_constrained_space: @@ -359,7 +362,7 @@ def inverse_transformation(node): tiebreaker = lambda x: tiebreak_on_lca(statement_node,origin,x,lca), transformation = transformation, inverse_transformation = inverse_transformation, - + invert_then_tiebreak = False ) return self._backward_result(result, alternatives,build) From 278985b6aee2c84f3da00de52d2dac1b5d249290 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 21 Jul 2020 17:47:02 +0300 Subject: [PATCH 43/45] Remove print() causing crashes in correspond_to_index_in_call These left over print statement were causing crashes if x was None, as may be the case for instance in queries of the form "inside 2 argument 1" --- library/info.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/info.py b/library/info.py index bf524f3..8ed8036 100644 --- a/library/info.py +++ b/library/info.py @@ -892,12 +892,11 @@ def get_raw(root): def correspond_to_index_in_call(root, index,field,field_index): x = get_argument_from_call(root,index) - print("entering index taking \n",ast.dump(x)) if not x: return False if x.parent_field=="value": x = x.parent - print("inside checking for index ",(x.parent_field,x.parent_field_index),(field,field_index)) + # print("inside checking for index ",(x.parent_field,x.parent_field_index),(field,field_index)) return (field, field_index)==(x.parent_field,x.parent_field_index) if x else False From d57845079b72731472e2992409d3e3d0f8bd2801 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 21 Jul 2020 18:22:38 +0300 Subject: [PATCH 44/45] Inside nth argument: replace query_description with deepcopy that is missing nth for these kind of queries nth decoding Should happen inside the transformation function not inside process_line. These was causing problems, because queries that they don't specify an inside index("inside first argument 1" As opposed to "inside 1 first argument 1") Were not searching All of the arguments of the parent call But only the one with index 1 --- queries/argument.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/queries/argument.py b/queries/argument.py index eacf987..564bda2 100644 --- a/queries/argument.py +++ b/queries/argument.py @@ -1,9 +1,12 @@ import ast +from copy import deepcopy + +import PythonVoiceCodingPlugin.library.info as info + from PythonVoiceCodingPlugin.library import sorted_by_source_region,get_source_region,make_flat from PythonVoiceCodingPlugin.library.selection_node import nearest_node_from_offset,node_from_range from PythonVoiceCodingPlugin.library.info import identity,get_argument_from_call,get_keyword_argument, make_information ,correspond_to_index_in_call,get_caller,get_sub_index,get_weak_header,get_argument_from_empty_call -import PythonVoiceCodingPlugin.library.info as info from PythonVoiceCodingPlugin.library.LCA import LCA from PythonVoiceCodingPlugin.library.level_info import LevelVisitor from PythonVoiceCodingPlugin.library.partial import partially_parse, line_partial @@ -99,7 +102,7 @@ def process_line(self,q, root ,atok, origin = None, select_node = None,tiebreak if "nth" not in q: if origin and calling_node: result = calling_node if calling_node in information_nodes else None - information_nodes = [x for x in tiebreaker(information_nodes) if x != calling_node] + information_nodes = [x for x in tiebreaker(information_nodes) if x is not calling_node] else: result = None information_nodes = [x for x in tiebreaker(information_nodes)] @@ -352,9 +355,9 @@ def inverse_transformation(node): - + q = deepcopy(query_description); del q["nth"] result, alternatives = self.process_line( - q = query_description, + q = q, root = statement_node, atok = atok, origin = origin, From 76e49b05f39a5e0590505154fd4342689dbd6df7 Mon Sep 17 00:00:00 2001 From: mpourmpoulis <35875229+mpourmpoulis@users.noreply.github.com> Date: Tue, 21 Jul 2020 18:53:10 +0300 Subject: [PATCH 45/45] Bump version messages --- messages.json | 1 + messages/0.1.3.txt | 22 ++++++++++++++++++++++ messages/install.txt | 7 ++++--- 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 messages/0.1.3.txt diff --git a/messages.json b/messages.json index a7d4843..f24ab15 100644 --- a/messages.json +++ b/messages.json @@ -2,5 +2,6 @@ "0.1.0": "messages/0.1.0.txt", "0.1.1": "messages/0.1.1.txt", "0.1.2": "messages/0.1.2.txt", + "0.1.3": "messages/0.1.3.txt", "install": "messages/install.txt" } \ No newline at end of file diff --git a/messages/0.1.3.txt b/messages/0.1.3.txt new file mode 100644 index 0000000..56bd6ba --- /dev/null +++ b/messages/0.1.3.txt @@ -0,0 +1,22 @@ +Thanks for upgrading to the latest version v0.1.3! + +This is a small patch + +- refactoring some old code from the age of the dinosaurs + +- Introduces a variety of bug fixes, especially certain edge cases with the cursor position at the beginning or the end of the file and stabilizing the behavior of argument queries using the "inside" keyword + +- improves code coverage most notably by allowing "partial parsing", so that ArgumentQueries and dedicated sub indexing queries (eg,"delete part 2") can now run within the current logical line even if there are unrecoverable syntax errors in other parts of the code, so long as tokenization is still possible, a requirement I hope to remove in the future + +- ports the documentation to readthedocs + +If all things go according to plan, the next release will be 0.2.0 and will go public around mid August + +=============================================================== +CRITICAL UPDATE FOR THOSE UPGRADING FROM 0.1.1 +================================================================ + +My sincerest apologies but up to release 0.1.1 a subtle yet critical installation step was not documented, which may have prevented you from using the plug-in altogether! + +You can find more information at https://github.com/mpourmpoulis/PythonVoiceCodingPlugin/issues/15 but release 0.1.2 should make that installation step redundant for most users, so SIMPLY UPGRADING and replacing the grammar files should be enough without any further action on your part! + diff --git a/messages/install.txt b/messages/install.txt index d1dd69b..2dbdccd 100644 --- a/messages/install.txt +++ b/messages/install.txt @@ -1,4 +1,4 @@ -Thanks for downloading the latest 0.1.1 version of PythonVoiceCodingPlugin! +Thanks for downloading the latest 0.1.3 version of PythonVoiceCodingPlugin! Should you face any problems or have any questions regarding the installation process, feel free to contact me in the dedicated gitter channel @@ -12,7 +12,7 @@ From there you can also retrieve the Caster grammars that are necessary for usin Quick 1.0.0 Install -utility. It supports all version of Caster 0.5, 0.6, 1.x but please upgrade as support for older versions will soon be dropped! As a note if you're using any version above 1.0.0 you must also enable it by saying +utility. It supports all version of Caster 0.5, 0.6, 1.x but please upgrade as support for older versions will soon be dropped, most probably with release 0.2.0 when it comes out hopefully around mid August! As a note if you're using any version above 1.0.0 you must also enable it by saying enable python voice coding plugin @@ -24,7 +24,8 @@ Finally you should be aware that there are some experimental/unofficial features NOTE FOR MAC Installers ################################# -Honestly you caught me a little bit unprepared,I am releasing these for Windows and Linux so i didn't expect anyone to download on Mac:P Firstly the core plug-in has not been tested on Mac. Secondly currently the grammar is written to be used with Caster which does not yet officially support Mac, though https://github.com/dmakarov/Caster is an attempt to do so. So you might want to give it a try with that or adapt it to standalone dragonfly or what ever suits your system. +Honestly you caught me a little bit unprepared,I am releasing these for Windows and Linux so i didn't expect anyone to download on Mac and lacking Mac hardware, the core plug-in has not been tested on Mac. Nonetheless it is pure python I believe it should generally work and with Caster now supporting Mac it is probably worth your while to give it a try! + Finally if you are using Talon and Jetbrains, an alternative you might want to check out is https://github.com/dwiel/talon_community/blob/master/apps/jetbrains_psi.py