Skip to content

Commit b70e87e

Browse files
Migrate python scopes (#2045)
## Checklist - [-] I have added [tests](https://www.cursorless.org/docs/contributing/test-case-recorder/) - [-] I have updated the [docs](https://github.com/cursorless-dev/cursorless/tree/main/docs) and [cheatsheet](https://github.com/cursorless-dev/cursorless/tree/main/cursorless-talon/src/cheatsheet) - [-] I have not broken the cheatsheet
1 parent 2af63fd commit b70e87e

File tree

8 files changed

+239
-42
lines changed

8 files changed

+239
-42
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
1-
import { Selection } from "@cursorless/common";
1+
import { Selection, SimpleScopeTypeType } from "@cursorless/common";
22
import type { SyntaxNode } from "web-tree-sitter";
3-
import { SimpleScopeTypeType } from "@cursorless/common";
43
import { NodeFinder, NodeMatcherAlternative } from "../typings/Types";
54
import { argumentNodeFinder, patternFinder } from "../util/nodeFinders";
65
import {
76
argumentMatcher,
87
cascadingMatcher,
9-
conditionMatcher,
108
createPatternMatchers,
11-
leadingMatcher,
129
matcher,
13-
patternMatcher,
14-
trailingMatcher,
1510
} from "../util/nodeMatchers";
1611
import {
1712
argumentSelectionExtractor,
1813
childRangeSelector,
1914
} from "../util/nodeSelectors";
20-
import { branchMatcher } from "./branchMatcher";
21-
import { ternaryBranchMatcher } from "./ternaryBranchMatcher";
2215

2316
export const getTypeNode = (node: SyntaxNode) =>
2417
node.children.find((child) => child.type === "type") ?? null;
@@ -55,38 +48,10 @@ const nodeMatchers: Partial<
5548
argumentSelectionExtractor(),
5649
),
5750
),
58-
collectionKey: trailingMatcher(["pair[key]"], [":"]),
59-
ifStatement: "if_statement",
60-
anonymousFunction: "lambda?.lambda",
61-
functionCall: "call",
62-
functionCallee: "call[function]",
63-
condition: cascadingMatcher(
64-
conditionMatcher("*[condition]"),
65-
66-
// Comprehensions and match statements
67-
leadingMatcher(["*.if_clause![0]"], ["if"]),
68-
69-
// Ternaries
70-
patternMatcher("conditional_expression[1]"),
71-
),
7251
argumentOrParameter: cascadingMatcher(
7352
argumentMatcher("parameters", "argument_list"),
7453
matcher(patternFinder("call.generator_expression!"), childRangeSelector()),
7554
),
76-
branch: cascadingMatcher(
77-
patternMatcher("case_clause"),
78-
branchMatcher("if_statement", ["else_clause", "elif_clause"]),
79-
branchMatcher("while_statement", ["else_clause"]),
80-
branchMatcher("for_statement", ["else_clause"]),
81-
branchMatcher("try_statement", [
82-
"except_clause",
83-
"finally_clause",
84-
"else_clause",
85-
"except_group_clause",
86-
]),
87-
ternaryBranchMatcher("conditional_expression", [0, 2]),
88-
),
89-
["private.switchStatementSubject"]: "match_statement[subject]",
9055
};
9156

9257
export default createPatternMatchers(nodeMatchers);

packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/python/changeName2.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,10 @@ initialState:
1818
- anchor: {line: 1, character: 4}
1919
active: {line: 1, character: 4}
2020
marks: {}
21-
thrownError: {name: NoContainingScopeError}
21+
finalState:
22+
documentContents: |-
23+
for in bbb:
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,27 @@
1+
languageId: python
2+
command:
3+
version: 6
4+
spokenForm: change name
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: name}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: |-
15+
for name in value:
16+
pass
17+
selections:
18+
- anchor: {line: 1, character: 4}
19+
active: {line: 1, character: 4}
20+
marks: {}
21+
finalState:
22+
documentContents: |-
23+
for in value:
24+
pass
25+
selections:
26+
- anchor: {line: 0, character: 4}
27+
active: {line: 0, character: 4}

packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/python/changeValue4.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,10 @@ initialState:
1818
- anchor: {line: 1, character: 4}
1919
active: {line: 1, character: 4}
2020
marks: {}
21-
thrownError: {name: NoContainingScopeError}
21+
finalState:
22+
documentContents: |-
23+
for aaa in :
24+
pass
25+
selections:
26+
- anchor: {line: 0, character: 11}
27+
active: {line: 0, character: 11}
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+
for name in value:
16+
pass
17+
selections:
18+
- anchor: {line: 1, character: 4}
19+
active: {line: 1, character: 4}
20+
marks: {}
21+
finalState:
22+
documentContents: |-
23+
for name in :
24+
pass
25+
selections:
26+
- anchor: {line: 0, character: 12}
27+
active: {line: 0, character: 12}

packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/python/clearCondition6.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ initialState:
2121
finalState:
2222
documentContents: |-
2323
match 0:
24-
case a if :
24+
case :
2525
pass
2626
selections:
27-
- anchor: {line: 1, character: 14}
28-
active: {line: 1, character: 14}
27+
- anchor: {line: 1, character: 9}
28+
active: {line: 1, character: 9}

packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/python/ditchCondition2.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ initialState:
2121
finalState:
2222
documentContents: |-
2323
match 0:
24-
case a :
24+
case:
2525
pass
2626
selections:
2727
- anchor: {line: 2, character: 8}

queries/python.scm

+166
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,169 @@
230230
"(" @value.iteration.start.endOf @name.iteration.start.endOf @type.iteration.start.endOf
231231
")" @value.iteration.end.startOf @name.iteration.end.startOf @type.iteration.end.startOf
232232
)
233+
234+
;;!! if true: pass
235+
;;! ^^^^^^^^^^^^^
236+
(if_statement) @ifStatement
237+
238+
;;!! foo()
239+
;;! ^^^^^
240+
(call) @functionCall
241+
242+
;;!! foo()
243+
;;! ^^^^^
244+
(call
245+
function: (_) @functionCallee
246+
) @_.domain
247+
248+
;;!! lambda _: pass
249+
;;! ^^^^^^^^^^^^^^
250+
(lambda) @anonymousFunction
251+
252+
;;!! match value:
253+
;;! ^^^^^
254+
(match_statement
255+
subject: (_) @private.switchStatementSubject
256+
) @_.domain
257+
258+
;;!! { "value": 0 }
259+
;;! ^^^^^^^
260+
;;! xxxxxxxxx
261+
(pair
262+
key: (_) @collectionKey @collectionKey.trailing.start.endOf
263+
value: (_) @collectionKey.trailing.end.startOf
264+
) @_.domain
265+
266+
;;!! if True:
267+
;;! ^^^^
268+
;;!! elif True:
269+
;;! ^^^^
270+
;;!! while True:
271+
;;! ^^^^
272+
(_
273+
condition: (_) @condition
274+
) @_.domain
275+
276+
;;!! match value:
277+
;;! ^^^^^
278+
(case_clause
279+
pattern: (_) @condition.start
280+
guard: (_)? @condition.end
281+
) @_.domain
282+
283+
;;!! case 0: pass
284+
;;! ^^^^^^^^^^^^
285+
(case_clause) @branch
286+
287+
(match_statement) @branch.iteration @condition.iteration
288+
289+
;;!! 1 if True else 0
290+
;;! ^^^^
291+
;;! ----------------
292+
(
293+
(conditional_expression
294+
"if"
295+
.
296+
(_) @condition
297+
) @_.domain
298+
)
299+
300+
;;!! 1 if True else 0
301+
;;! ^
302+
(
303+
(conditional_expression
304+
(_) @branch
305+
.
306+
"if"
307+
)
308+
)
309+
310+
;;!! 1 if True else 0
311+
;;! ^
312+
(
313+
(conditional_expression
314+
"else"
315+
.
316+
(_) @branch
317+
)
318+
)
319+
320+
(conditional_expression) @branch.iteration
321+
322+
;;!! [aaa for aaa in bbb if ccc]
323+
;;!! (aaa for aaa in bbb if ccc)
324+
;;!! {aaa for aaa in bbb if ccc}
325+
;;! ^^^
326+
;;! xxxxxx
327+
;;! ---------------------------
328+
;;!! {aaa: aaa for aaa in bbb if ccc}
329+
;;! ^^^
330+
;;! xxxxxx
331+
;;! --------------------------------
332+
(_
333+
(if_clause
334+
"if"
335+
(_) @condition
336+
) @_.removal
337+
(#not-parent-type? @_.removal case_clause)
338+
) @_.domain
339+
340+
;;!! for name in value:
341+
;;! ^^^^ ^^^^^
342+
;;! ------------------
343+
(for_statement
344+
left: (_) @name
345+
right: (_) @value
346+
) @_.domain
347+
348+
;;!! if True: pass
349+
;;! ^^^^^^^^^^^^^
350+
(if_statement
351+
"if" @branch.start
352+
consequence: (_) @branch.end
353+
)
354+
355+
;;!! elif True: pass
356+
;;! ^^^^^^^^^^^^^^^
357+
(elif_clause) @branch
358+
359+
;;!! else: pass
360+
;;! ^^^^^^^^^^
361+
(else_clause) @branch
362+
363+
(if_statement) @branch.iteration
364+
365+
;;!! try: pass
366+
;;! ^^^^^^^^^
367+
(try_statement
368+
"try" @branch.start
369+
body: (_) @branch.end
370+
)
371+
372+
;;!! except: pass
373+
;;! ^^^^^^^^^^^^
374+
(except_clause) @branch
375+
376+
;;!! finally: pass
377+
;;! ^^^^^^^^^^^^^
378+
(finally_clause) @branch
379+
380+
(try_statement) @branch.iteration
381+
382+
;;!! while True: pass
383+
;;! ^^^^^^^^^^^^^^^^
384+
(while_statement
385+
"while" @branch.start
386+
body: (_) @branch.end
387+
)
388+
389+
(while_statement) @branch.iteration
390+
391+
;;!! for aaa in bbb: pass
392+
;;! ^^^^^^^^^^^^^^^^^^^^
393+
(for_statement
394+
"for" @branch.start
395+
body: (_) @branch.end
396+
)
397+
398+
(for_statement) @branch.iteration

0 commit comments

Comments
 (0)