Skip to content

Commit 065f98a

Browse files
saidelikeCedric Halbronnpokeypre-commit-ci-lite[bot]
authored
Migrate python scope "value" to new scope handler (#1877)
## Checklist - [ ] I have executed the existing tests but they seem to fail for whatever reason. Not sure why (e.g. `takeValue.yml` from a quick glance - [x] I have tested the `visualize value` command and all the `take value` from this file and they all work fine ![image](https://github.com/cursorless-dev/cursorless/assets/387346/22206d81-a41b-4b2d-b949-fa8760692be0) If anyone has ideas why the unit tests don't work. NOTES: - I haven't included the assignment symbols like ".", "=", "/=" as I don't think they are needed when using the tree-sitter but let me know if you think otherwise. - the "return" in the "return_statement" is something that was ignored too as not relevant anymore afaict --------- Co-authored-by: Cedric Halbronn <[email protected]> Co-authored-by: Pokey Rule <[email protected]> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent 5789094 commit 065f98a

File tree

8 files changed

+252
-25
lines changed

8 files changed

+252
-25
lines changed

data/playground/python/values.py

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Useful commands:
2+
# "visualize value"
3+
# "visualize value iteration"
4+
# "take value"
5+
# "chuck value"
6+
# "chuck every value"
7+
8+
# the argument value "True" that is part of "b=True"
9+
# is "value" scope
10+
def func(b=True, c=True):
11+
# the returned value "1" that is part of "return 1"
12+
# is "value" scope
13+
if b is True:
14+
return 1
15+
else:
16+
return 0
17+
18+
# the argument value "False" that is part of "b=False"
19+
# is "value" scope
20+
func(b=False)
21+
# but here, there is no "value" scope for "False" since no argument
22+
func(False)
23+
24+
# both "1.5" and "25" are "value" scope
25+
val = 1.5
26+
val /= 25
27+
28+
val1, val2 = 0, 5
29+
val1 = 0, val2 = 5
30+
val1 = val2
31+
32+
def my_funk(value: str) -> str:
33+
print(value)
34+
35+
def my_funk(value: str = "hello", other: bool=False) -> str:
36+
print(value)
37+
38+
# we can say "change every value" to allow modifying all the values in one go
39+
def foo():
40+
a = 0
41+
b = 1
42+
c = 2
43+
44+
# But we don't support outside of a function yet
45+
a = 0
46+
b = 1
47+
c = 2
48+
49+
# values of a Python "dictionary" are "value" scope
50+
# we can say "chuck every value" to convert the dict into a set
51+
d1 = {"a": 1, "b": 2, "c": 3}
52+
53+
_ = {value: key for (key, value) in d1.items()}
54+
55+
# complex ones
56+
_ = {{"a": 1, "b": 2, "c": 3}: 1, d1: 2}
57+
_ = {{1, 2, 3}: 1, {2, 3, 4}: 2}
58+
59+
# we don't want the access to a a Python "dictionary"
60+
# value to be of "value" scope so we have it here
61+
# to be sure we ignore it
62+
d1["a"]
63+
64+
value = "hello world"

packages/cursorless-engine/src/languages/python.ts

-22
Original file line numberDiff line numberDiff line change
@@ -80,28 +80,6 @@ const nodeMatchers: Partial<
8080
"parameters.identifier!",
8181
"*[name]",
8282
],
83-
value: cascadingMatcher(
84-
leadingMatcher(
85-
["assignment[right]", "augmented_assignment[right]", "~subscript[value]"],
86-
[
87-
":",
88-
"=",
89-
"+=",
90-
"-=",
91-
"*=",
92-
"/=",
93-
"%=",
94-
"//=",
95-
"**=",
96-
"&=",
97-
"|=",
98-
"^=",
99-
"<<=",
100-
">>=",
101-
],
102-
),
103-
patternMatcher("return_statement.~return!"),
104-
),
10583
argumentOrParameter: cascadingMatcher(
10684
argumentMatcher("parameters", "argument_list"),
10785
matcher(patternFinder("call.generator_expression!"), childRangeSelector()),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
languageId: python
2+
command:
3+
version: 6
4+
spokenForm: change value
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: value}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |-
15+
if (x := 0) < 1:
16+
pass
17+
selections:
18+
- anchor: {line: 0, character: 4}
19+
active: {line: 0, character: 4}
20+
marks: {}
21+
finalState:
22+
documentContents: |-
23+
if (x := ) < 1:
24+
pass
25+
selections:
26+
- anchor: {line: 0, character: 9}
27+
active: {line: 0, character: 9}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
languageId: python
2+
command:
3+
version: 6
4+
spokenForm: change value
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: value}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |-
15+
match aaa:
16+
case {"bbb": ccc}:
17+
pass
18+
selections:
19+
- anchor: {line: 1, character: 10}
20+
active: {line: 1, character: 10}
21+
marks: {}
22+
finalState:
23+
documentContents: |-
24+
match aaa:
25+
case {"bbb": }:
26+
pass
27+
selections:
28+
- anchor: {line: 1, character: 17}
29+
active: {line: 1, character: 17}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
languageId: python
2+
command:
3+
version: 6
4+
spokenForm: chuck value
5+
action:
6+
name: remove
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: value}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |-
15+
if (x := 0) < 1:
16+
pass
17+
selections:
18+
- anchor: {line: 0, character: 4}
19+
active: {line: 0, character: 4}
20+
marks: {}
21+
finalState:
22+
documentContents: |-
23+
if (x) < 1:
24+
pass
25+
selections:
26+
- anchor: {line: 0, character: 4}
27+
active: {line: 0, character: 4}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
languageId: python
2+
command:
3+
version: 6
4+
spokenForm: chuck value
5+
action:
6+
name: remove
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: value}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |-
15+
match aaa:
16+
case {"bbb": ccc}:
17+
pass
18+
selections:
19+
- anchor: {line: 1, character: 10}
20+
active: {line: 1, character: 10}
21+
marks: {}
22+
finalState:
23+
documentContents: |-
24+
match aaa:
25+
case {"bbb"}:
26+
pass
27+
selections:
28+
- anchor: {line: 1, character: 10}
29+
active: {line: 1, character: 10}

pyproject.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
[tool.black]
22
target-version = ["py39"]
3+
force-exclude = ["vendor", "data/playground"]
34

45
[tool.ruff]
56
select = ["E", "F", "C4", "I001", "UP", "SIM"]
67
ignore = ["E501", "SIM105", "UP035"]
78
target-version = "py39"
8-
extend-exclude = ["vendor"]
9+
extend-exclude = ["vendor", "data/playground/**/*.py"]

queries/python.scm

+74-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,58 @@
2727
(with_statement)
2828
] @statement
2929

30+
;;!! a = 25
31+
;;! ^^
32+
;;! xxxxx
33+
;;! ------
34+
(assignment
35+
(_) @_.leading.start.endOf
36+
.
37+
right: (_) @value @_.leading.end.startOf
38+
) @_.domain
39+
40+
;;!! a /= 25
41+
;;! ^^
42+
;;! xxxxxx
43+
;;! -------
44+
(augmented_assignment
45+
(_) @_.leading.start.endOf
46+
.
47+
right: (_) @value @_.leading.end.startOf
48+
) @_.domain
49+
50+
;;!! d = {"a": 1234}
51+
;;! ^^^^
52+
;;! xxxxxx
53+
;;! ---------
54+
;;!! {value: key for (key, value) in d1.items()}
55+
;;! ^^^
56+
;;! xxxxx
57+
;;! ----------
58+
;;!! def func(value: str = ""):
59+
;;! ^^
60+
;;! xxxxx
61+
;;! ---------------
62+
(
63+
(_
64+
(_) @_.leading.start.endOf
65+
.
66+
value: (_) @value @_.leading.end.startOf
67+
) @_.domain
68+
(#not-type? @_.domain subscript)
69+
)
70+
71+
;;!! return 1
72+
;;! ^
73+
;;! xx
74+
;;! --------
75+
;;
76+
;; NOTE: in tree-sitter, both "return" and the "1" are children of `return_statement`
77+
;; but "return" is anonymous whereas "1" is named node, so no need to exclude explicitly
78+
(return_statement
79+
(_) @value
80+
) @_.domain
81+
3082
(comment) @comment @textFragment
3183

3284
(string
@@ -77,6 +129,26 @@
77129
(module) @statement.iteration
78130
(module) @namedFunction.iteration @functionName.iteration
79131
(class_definition) @namedFunction.iteration @functionName.iteration
80-
(_
81-
body: (_) @statement.iteration
132+
133+
;;!! def foo():
134+
;;!! a = 0
135+
;;! <*****
136+
;;!! b = 1
137+
;;! *****
138+
;;!! c = 2
139+
;;! *****>
140+
(block) @statement.iteration @value.iteration
141+
142+
;;!! {"a": 1, "b": 2, "c": 3}
143+
;;! **********************
144+
(dictionary
145+
"{" @value.iteration.start.endOf
146+
"}" @value.iteration.end.startOf
147+
)
148+
149+
;;!! def func(a=0, b=1):
150+
;;! ********
151+
(parameters
152+
"(" @value.iteration.start.endOf
153+
")" @value.iteration.end.startOf
82154
)

0 commit comments

Comments
 (0)