Skip to content

Commit 2af63fd

Browse files
AndreasArvidssonpre-commit-ci-lite[bot]pokey
authored
Migrate typescript scopes (#2040)
Fixes #1892 ## Checklist - [x] 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 --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Pokey Rule <[email protected]>
1 parent 0e266f0 commit 2af63fd

File tree

12 files changed

+415
-222
lines changed

12 files changed

+415
-222
lines changed

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

-17
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { getNodeMatcher } from "./getNodeMatcher";
88
import { stringTextFragmentExtractor as htmlStringTextFragmentExtractor } from "./html";
99
import { stringTextFragmentExtractor as rubyStringTextFragmentExtractor } from "./ruby";
1010
import { stringTextFragmentExtractor as scssStringTextFragmentExtractor } from "./scss";
11-
import { stringTextFragmentExtractor as typescriptStringTextFragmentExtractor } from "./typescript";
1211

1312
export type TextFragmentExtractor = (
1413
node: SyntaxNode,
@@ -131,14 +130,6 @@ const textFragmentExtractors: Record<
131130
"html",
132131
htmlStringTextFragmentExtractor,
133132
),
134-
javascript: constructDefaultTextFragmentExtractor(
135-
"javascript",
136-
typescriptStringTextFragmentExtractor,
137-
),
138-
javascriptreact: constructDefaultTextFragmentExtractor(
139-
"javascriptreact",
140-
typescriptStringTextFragmentExtractor,
141-
),
142133
latex: fullDocumentTextFragmentExtractor,
143134
markdown: fullDocumentTextFragmentExtractor,
144135
ruby: constructDefaultTextFragmentExtractor(
@@ -154,14 +145,6 @@ const textFragmentExtractors: Record<
154145
scssStringTextFragmentExtractor,
155146
),
156147
rust: constructDefaultTextFragmentExtractor("rust"),
157-
typescript: constructDefaultTextFragmentExtractor(
158-
"typescript",
159-
typescriptStringTextFragmentExtractor,
160-
),
161-
typescriptreact: constructDefaultTextFragmentExtractor(
162-
"typescriptreact",
163-
typescriptStringTextFragmentExtractor,
164-
),
165148
xml: constructDefaultTextFragmentExtractor(
166149
"xml",
167150
htmlStringTextFragmentExtractor,
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,12 @@
11
import { SimpleScopeTypeType } from "@cursorless/common";
2-
import type { SyntaxNode } from "web-tree-sitter";
3-
import { NodeMatcherAlternative, SelectionWithEditor } from "../typings/Types";
4-
import { patternFinder } from "../util/nodeFinders";
5-
import {
6-
argumentMatcher,
7-
cascadingMatcher,
8-
conditionMatcher,
9-
createPatternMatchers,
10-
matcher,
11-
patternMatcher,
12-
trailingMatcher,
13-
} from "../util/nodeMatchers";
14-
import {
15-
childRangeSelector,
16-
extendForwardPastOptional,
17-
getNodeInternalRange,
18-
getNodeRange,
19-
unwrapSelectionExtractor,
20-
} from "../util/nodeSelectors";
21-
import { branchMatcher } from "./branchMatcher";
22-
import { elseExtractor, elseIfExtractor } from "./elseIfExtractor";
23-
import { ternaryBranchMatcher } from "./ternaryBranchMatcher";
24-
25-
// Generated by the following command:
26-
// > curl https://raw.githubusercontent.com/tree-sitter/tree-sitter-typescript/4c20b54771e4b390ee058af2930feb2cd55f2bf8/typescript/src/node-types.json \
27-
// | jq '[.[] | select(.type == "statement" or .type == "declaration") | .subtypes[].type]'
28-
const STATEMENT_TYPES = [
29-
"abstract_class_declaration",
30-
"ambient_declaration",
31-
"break_statement",
32-
"class_declaration",
33-
"continue_statement",
34-
"debugger_statement",
35-
"declaration",
36-
"do_statement",
37-
"empty_statement",
38-
"enum_declaration",
39-
"export_statement",
40-
"expression_statement",
41-
"for_in_statement",
42-
"for_statement",
43-
"function_declaration",
44-
"function_signature",
45-
"generator_function_declaration",
46-
"if_statement",
47-
"import_alias",
48-
"import_statement",
49-
"interface_declaration",
50-
"internal_module",
51-
"labeled_statement",
52-
"lexical_declaration",
53-
"module",
54-
"return_statement",
55-
// "statement_block", This is disabled since we want the whole statement and not just the block
56-
"switch_statement",
57-
"throw_statement",
58-
"try_statement",
59-
"type_alias_declaration",
60-
"variable_declaration",
61-
"while_statement",
62-
"with_statement",
63-
];
64-
65-
const mapTypes = ["object", "object_pattern"];
66-
const listTypes = ["array", "array_pattern"];
2+
import { NodeMatcherAlternative } from "../typings/Types";
3+
import { argumentMatcher, createPatternMatchers } from "../util/nodeMatchers";
674

685
const nodeMatchers: Partial<
696
Record<SimpleScopeTypeType, NodeMatcherAlternative>
707
> = {
71-
map: mapTypes,
72-
list: listTypes,
73-
string: ["string", "template_string"],
748
collectionItem: "jsx_attribute",
75-
collectionKey: trailingMatcher(
76-
[
77-
"pair[key]",
78-
"jsx_attribute.property_identifier!",
79-
"object_type.property_signature[name]!",
80-
"shorthand_property_identifier",
81-
],
82-
[":"],
83-
),
84-
ifStatement: "if_statement",
85-
comment: "comment",
86-
regularExpression: "regex",
87-
className: ["class_declaration[name]", "class[name]"],
88-
functionCall: ["call_expression", "new_expression"],
89-
functionCallee: cascadingMatcher(
90-
patternMatcher("call_expression[function]"),
91-
matcher(
92-
patternFinder("new_expression"),
93-
childRangeSelector(["arguments"], []),
94-
),
95-
),
96-
statement: cascadingMatcher(
97-
matcher(
98-
patternFinder(
99-
"property_signature",
100-
"public_field_definition",
101-
"abstract_method_signature",
102-
),
103-
extendForwardPastOptional(";"),
104-
),
105-
patternMatcher(
106-
...STATEMENT_TYPES.map((type) => `export_statement?.${type}`),
107-
"method_definition",
108-
),
109-
),
110-
condition: cascadingMatcher(
111-
patternMatcher("ternary_expression[condition]"),
112-
conditionMatcher(
113-
"if_statement[condition]",
114-
"for_statement[condition]",
115-
"while_statement[condition]",
116-
"do_statement[condition]",
117-
),
118-
),
119-
["private.switchStatementSubject"]: matcher(
120-
patternFinder("switch_statement[value]"),
121-
unwrapSelectionExtractor,
122-
),
123-
branch: cascadingMatcher(
124-
patternMatcher("switch_case"),
125-
matcher(patternFinder("else_clause"), elseExtractor("if_statement")),
126-
matcher(patternFinder("if_statement"), elseIfExtractor()),
127-
branchMatcher("try_statement", ["catch_clause", "finally_clause"]),
128-
ternaryBranchMatcher("ternary_expression", [1, 2]),
129-
),
130-
class: [
131-
"export_statement?.class_declaration", // export class | class
132-
"export_statement?.abstract_class_declaration", // export abstract class | abstract class
133-
"export_statement.class", // export default class
134-
],
1359
argumentOrParameter: argumentMatcher("formal_parameters", "arguments"),
136-
// XML, JSX
137-
attribute: ["jsx_attribute"],
13810
};
13911

14012
export const patternMatchers = createPatternMatchers(nodeMatchers);
141-
142-
export function stringTextFragmentExtractor(
143-
node: SyntaxNode,
144-
_selection: SelectionWithEditor,
145-
) {
146-
if (
147-
node.type === "string_fragment" ||
148-
node.type === "regex_pattern" ||
149-
node.type === "jsx_text"
150-
) {
151-
return getNodeRange(node);
152-
}
153-
154-
if (node.type === "template_string") {
155-
// Exclude starting and ending quotation marks
156-
return getNodeInternalRange(node);
157-
}
158-
159-
return null;
160-
}

packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/changeCallee5.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ initialState:
1313
active: {line: 0, character: 24}
1414
marks: {}
1515
finalState:
16-
documentContents: let test = new ()
16+
documentContents: let test = ()
1717
selections:
18-
- anchor: {line: 0, character: 15}
19-
active: {line: 0, character: 15}
18+
- anchor: {line: 0, character: 11}
19+
active: {line: 0, character: 11}

packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/changeCallee6.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ initialState:
1313
active: {line: 0, character: 28}
1414
marks: {}
1515
finalState:
16-
documentContents: let test = new ()
16+
documentContents: let test = ()
1717
selections:
18-
- anchor: {line: 0, character: 15}
19-
active: {line: 0, character: 15}
18+
- anchor: {line: 0, character: 11}
19+
active: {line: 0, character: 11}

packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/changeCallee7.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ initialState:
1313
active: {line: 0, character: 24}
1414
marks: {}
1515
finalState:
16-
documentContents: let test = new ()
16+
documentContents: let test = ()
1717
selections:
18-
- anchor: {line: 0, character: 15}
19-
active: {line: 0, character: 15}
18+
- anchor: {line: 0, character: 11}
19+
active: {line: 0, character: 11}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
languageId: typescript
2+
command:
3+
version: 6
4+
spokenForm: chuck type
5+
action:
6+
name: remove
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: type}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: <Type>foo
15+
selections:
16+
- anchor: {line: 0, character: 1}
17+
active: {line: 0, character: 1}
18+
marks: {}
19+
finalState:
20+
documentContents: foo
21+
selections:
22+
- anchor: {line: 0, character: 0}
23+
active: {line: 0, character: 0}

packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/takeEveryKey.yml renamed to packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearEveryKey.yml

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
languageId: typescript
22
command:
33
version: 1
4-
spokenForm: take every key
5-
action: setSelection
4+
spokenForm: change every key
5+
action: clearAndSetSelection
66
targets:
77
- type: primitive
88
modifier: {type: containingScope, scopeType: collectionKey, includeSiblings: true}
@@ -19,11 +19,11 @@ initialState:
1919
finalState:
2020
documentContents: |-
2121
const value = {
22-
key1: "hello",
23-
key2: "there",
22+
: "hello",
23+
: "there",
2424
};
2525
selections:
2626
- anchor: {line: 1, character: 4}
27-
active: {line: 1, character: 8}
27+
active: {line: 1, character: 4}
2828
- anchor: {line: 2, character: 4}
29-
active: {line: 2, character: 8}
29+
active: {line: 2, character: 4}

packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/takeEveryKey2.yml renamed to packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearEveryKey2.yml

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
languageId: typescript
22
command:
33
version: 1
4-
spokenForm: take every key
5-
action: setSelection
4+
spokenForm: change every key
5+
action: clearAndSetSelection
66
targets:
77
- type: primitive
88
modifier: {type: containingScope, scopeType: collectionKey, includeSiblings: true}
@@ -19,11 +19,11 @@ initialState:
1919
finalState:
2020
documentContents: |-
2121
{
22-
foo: "hello",
23-
bar,
22+
: "hello",
23+
,
2424
}
2525
selections:
2626
- anchor: {line: 1, character: 4}
27-
active: {line: 1, character: 7}
27+
active: {line: 1, character: 4}
2828
- anchor: {line: 2, character: 4}
29-
active: {line: 2, character: 7}
29+
active: {line: 2, character: 4}

0 commit comments

Comments
 (0)