diff --git a/packages/cursorless-engine/src/languages/typescript.ts b/packages/cursorless-engine/src/languages/typescript.ts index 04d8bca7da4..1a3b0263ca0 100644 --- a/packages/cursorless-engine/src/languages/typescript.ts +++ b/packages/cursorless-engine/src/languages/typescript.ts @@ -175,7 +175,6 @@ const nodeMatchers: Partial< patternMatcher("yield_expression.~yield!"), ), ifStatement: "if_statement", - anonymousFunction: ["arrow_function", "function"], comment: "comment", regularExpression: "regex", className: ["class_declaration[name]", "class[name]"], @@ -226,59 +225,6 @@ const nodeMatchers: Partial< "export_statement?.abstract_class_declaration", // export abstract class | abstract class "export_statement.class", // export default class ], - functionName: [ - // function - "function_declaration[name]", - // generator function - "generator_function_declaration[name]", - // export default function - "function[name]", - // class method - "method_definition[name]", - // abstract class method - "abstract_method_signature[name]", - // class arrow method - "public_field_definition[name].arrow_function", - // const foo = function() { } - "variable_declarator[name].function", - // const foo = () => { } - "variable_declarator[name].arrow_function", - // foo = function() { } - "assignment_expression[left].function", - // foo = () => { } - "assignment_expression[left].arrow_function", - ], - namedFunction: cascadingMatcher( - patternMatcher( - // [export] function - "export_statement?.function_declaration", - // export default function - // NB: We require export statement because otherwise it is an anonymous - // function - "export_statement.function", - // export default arrow - "export_statement.arrow_function", - // class method - "method_definition", - // class arrow method - "public_field_definition.arrow_function", - // [export] const foo = function() { } - "export_statement?.lexical_declaration.variable_declarator.function", - // [export] const foo = () => { } - "export_statement?.lexical_declaration.variable_declarator.arrow_function", - // foo = function() { } - "assignment_expression.function", - // foo = () => { } - "assignment_expression.arrow_function", - // foo = function*() { } - "generator_function_declaration", - ), - // abstract class method - matcher( - patternFinder("abstract_method_signature"), - extendForwardPastOptional(";"), - ), - ), type: cascadingMatcher( // Typed parameters, properties, and functions typeMatcher(), diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearFunk.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearFunk.yml new file mode 100644 index 00000000000..ec98fcc2248 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearFunk.yml @@ -0,0 +1,28 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: |- + class Aaa { + bbb = () => {}; + } + selections: + - anchor: {line: 1, character: 19} + active: {line: 1, character: 19} + marks: {} +finalState: + documentContents: |- + class Aaa { + + } + selections: + - anchor: {line: 1, character: 4} + active: {line: 1, character: 4} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName.yml new file mode 100644 index 00000000000..d6e7361f1aa --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName.yml @@ -0,0 +1,22 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: name} + usePrePhraseSnapshot: true +initialState: + documentContents: const aaa = "bbb"; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: const = "bbb"; + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName2.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName2.yml new file mode 100644 index 00000000000..56bb2f0bb78 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName2.yml @@ -0,0 +1,22 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: name} + usePrePhraseSnapshot: true +initialState: + documentContents: export const aaa = "bbb"; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: export const = "bbb"; + selections: + - anchor: {line: 0, character: 13} + active: {line: 0, character: 13} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName3.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName3.yml new file mode 100644 index 00000000000..5e9b83a0c00 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName3.yml @@ -0,0 +1,22 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: name} + usePrePhraseSnapshot: true +initialState: + documentContents: var aaa = "bbb"; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: var = "bbb"; + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName4.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName4.yml new file mode 100644 index 00000000000..e15266c766c --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName4.yml @@ -0,0 +1,22 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: name} + usePrePhraseSnapshot: true +initialState: + documentContents: export var aaa = "bbb"; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: export var = "bbb"; + selections: + - anchor: {line: 0, character: 11} + active: {line: 0, character: 11} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName5.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName5.yml new file mode 100644 index 00000000000..a6d64a39b7a --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName5.yml @@ -0,0 +1,24 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: name} + usePrePhraseSnapshot: true +initialState: + documentContents: const aaa = "bbb", ccc = "ddd"; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: const = "bbb", = "ddd"; + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + - anchor: {line: 0, character: 16} + active: {line: 0, character: 16} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName6.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName6.yml new file mode 100644 index 00000000000..28c02aff5df --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName6.yml @@ -0,0 +1,24 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: name} + usePrePhraseSnapshot: true +initialState: + documentContents: export const aaa = "bbb", ccc = "ddd"; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: export const = "bbb", = "ddd"; + selections: + - anchor: {line: 0, character: 13} + active: {line: 0, character: 13} + - anchor: {line: 0, character: 23} + active: {line: 0, character: 23} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName7.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName7.yml new file mode 100644 index 00000000000..2bf478c2f70 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName7.yml @@ -0,0 +1,28 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: name} + usePrePhraseSnapshot: true +initialState: + documentContents: |- + class Aaa { + bbb = "ccc"; + } + selections: + - anchor: {line: 1, character: 16} + active: {line: 1, character: 16} + marks: {} +finalState: + documentContents: |- + class Aaa { + = "ccc"; + } + selections: + - anchor: {line: 1, character: 4} + active: {line: 1, character: 4} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName8.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName8.yml new file mode 100644 index 00000000000..84e62126506 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/javascript/clearName8.yml @@ -0,0 +1,28 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: name} + usePrePhraseSnapshot: true +initialState: + documentContents: |- + class Aaa { + bbb = "ccc" + } + selections: + - anchor: {line: 1, character: 15} + active: {line: 1, character: 15} + marks: {} +finalState: + documentContents: |- + class Aaa { + = "ccc" + } + selections: + - anchor: {line: 1, character: 4} + active: {line: 1, character: 4} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk10.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk10.yml new file mode 100644 index 00000000000..71f628f8e02 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk10.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: const foo = function *bar() {} + selections: + - anchor: {line: 0, character: 12} + active: {line: 0, character: 12} + marks: {} +finalState: + documentContents: "const foo = " + selections: + - anchor: {line: 0, character: 12} + active: {line: 0, character: 12} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk11.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk11.yml new file mode 100644 index 00000000000..7feeafdd19c --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk11.yml @@ -0,0 +1,18 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: const foo = function *bar() {} + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +thrownError: {name: NoContainingScopeError} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk12.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk12.yml new file mode 100644 index 00000000000..c0d95bbe84b --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk12.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: export default function *() {} + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: "" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk13.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk13.yml new file mode 100644 index 00000000000..2a05bf5c741 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk13.yml @@ -0,0 +1,22 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: var foo = () => {}; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: "" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk14.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk14.yml new file mode 100644 index 00000000000..2dc55c04857 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk14.yml @@ -0,0 +1,22 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: export var foo = () => {}; + selections: + - anchor: {line: 0, character: 8} + active: {line: 0, character: 8} + marks: {} +finalState: + documentContents: "" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk15.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk15.yml new file mode 100644 index 00000000000..4231240e28c --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk15.yml @@ -0,0 +1,22 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: const foo = () => {}; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: "" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk16.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk16.yml new file mode 100644 index 00000000000..3594f0e5fbb --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk16.yml @@ -0,0 +1,22 @@ +languageId: javascript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: let foo = () => {}; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: "" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk17.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk17.yml new file mode 100644 index 00000000000..b09b577db4d --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk17.yml @@ -0,0 +1,28 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: |- + interface Aaa { + bbb(): void; + } + selections: + - anchor: {line: 1, character: 16} + active: {line: 1, character: 16} + marks: {} +finalState: + documentContents: |- + interface Aaa { + + } + selections: + - anchor: {line: 1, character: 4} + active: {line: 1, character: 4} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk18.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk18.yml new file mode 100644 index 00000000000..b42129c7ff2 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk18.yml @@ -0,0 +1,42 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: |- + class MyClass { + constructor(value: string); + constructor(value: number); + + constructor(value: string | number) {} + } + selections: + - anchor: {line: 1, character: 31} + active: {line: 1, character: 31} + - anchor: {line: 2, character: 31} + active: {line: 2, character: 31} + - anchor: {line: 4, character: 42} + active: {line: 4, character: 42} + marks: {} +finalState: + documentContents: |- + class MyClass { + + + + + } + selections: + - anchor: {line: 1, character: 4} + active: {line: 1, character: 4} + - anchor: {line: 2, character: 4} + active: {line: 2, character: 4} + - anchor: {line: 4, character: 4} + active: {line: 4, character: 4} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk4.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk4.yml new file mode 100644 index 00000000000..97c7460f743 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk4.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: export function *aaa() {} + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: "" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk5.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk5.yml new file mode 100644 index 00000000000..fdc0063dfc1 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk5.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: (function foo() {}) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +finalState: + documentContents: () + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk6.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk6.yml new file mode 100644 index 00000000000..03f64276c14 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk6.yml @@ -0,0 +1,18 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: (function () {}) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +thrownError: {name: NoContainingScopeError} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk7.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk7.yml new file mode 100644 index 00000000000..e495cbfe548 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk7.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: export const myFunk = () => {}; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: "" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk8.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk8.yml new file mode 100644 index 00000000000..08f782e335e --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk8.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: const foo = function bar() {} + selections: + - anchor: {line: 0, character: 12} + active: {line: 0, character: 12} + marks: {} +finalState: + documentContents: "const foo = " + selections: + - anchor: {line: 0, character: 12} + active: {line: 0, character: 12} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk9.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk9.yml new file mode 100644 index 00000000000..8d2963bf705 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunk9.yml @@ -0,0 +1,18 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: const foo = function bar() {} + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +thrownError: {name: NoContainingScopeError} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName2.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName2.yml new file mode 100644 index 00000000000..7926381d370 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName2.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: functionName} + usePrePhraseSnapshot: true +initialState: + documentContents: export function *aaa() {} + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: export function *() {} + selections: + - anchor: {line: 0, character: 17} + active: {line: 0, character: 17} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName3.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName3.yml new file mode 100644 index 00000000000..56823dad79f --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName3.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: functionName} + usePrePhraseSnapshot: true +initialState: + documentContents: (function foo() {}) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +finalState: + documentContents: (function () {}) + selections: + - anchor: {line: 0, character: 10} + active: {line: 0, character: 10} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName4.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName4.yml new file mode 100644 index 00000000000..054fcd26b5f --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName4.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: functionName} + usePrePhraseSnapshot: true +initialState: + documentContents: export const myFunk = () => {}; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: export const = () => {}; + selections: + - anchor: {line: 0, character: 13} + active: {line: 0, character: 13} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName5.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName5.yml new file mode 100644 index 00000000000..0da9351070d --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName5.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: functionName} + usePrePhraseSnapshot: true +initialState: + documentContents: const foo = function bar() {} + selections: + - anchor: {line: 0, character: 12} + active: {line: 0, character: 12} + marks: {} +finalState: + documentContents: const foo = function () {} + selections: + - anchor: {line: 0, character: 21} + active: {line: 0, character: 21} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName6.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName6.yml new file mode 100644 index 00000000000..fda10309b58 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName6.yml @@ -0,0 +1,18 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: functionName} + usePrePhraseSnapshot: true +initialState: + documentContents: const foo = function bar() {} + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +thrownError: {name: NoContainingScopeError} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName7.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName7.yml new file mode 100644 index 00000000000..45fc50e47ca --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearFunkName7.yml @@ -0,0 +1,28 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear funk name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: functionName} + usePrePhraseSnapshot: true +initialState: + documentContents: |- + interface Aaa { + bbb(): void; + } + selections: + - anchor: {line: 1, character: 16} + active: {line: 1, character: 16} + marks: {} +finalState: + documentContents: |- + interface Aaa { + (): void; + } + selections: + - anchor: {line: 1, character: 4} + active: {line: 1, character: 4} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearLambda5.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearLambda5.yml new file mode 100644 index 00000000000..fcec61dc966 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearLambda5.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear lambda + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: anonymousFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: (function () {}) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +finalState: + documentContents: () + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearLambda6.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearLambda6.yml new file mode 100644 index 00000000000..0b2641cc14d --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearLambda6.yml @@ -0,0 +1,18 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear lambda + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: anonymousFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: (function bar() {}) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +thrownError: {name: NoContainingScopeError} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearLambda7.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearLambda7.yml new file mode 100644 index 00000000000..2f6b3d76754 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearLambda7.yml @@ -0,0 +1,18 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear lambda + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: anonymousFunction} + usePrePhraseSnapshot: true +initialState: + documentContents: (function *bar() {}) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +thrownError: {name: NoContainingScopeError} diff --git a/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearName2.yml b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearName2.yml new file mode 100644 index 00000000000..0e0940792c3 --- /dev/null +++ b/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/typescript/clearName2.yml @@ -0,0 +1,28 @@ +languageId: typescript +command: + version: 5 + spokenForm: clear name + action: {name: clearAndSetSelection} + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: name} + usePrePhraseSnapshot: true +initialState: + documentContents: |- + class Aaa { + public bbb = "ccc"; + } + selections: + - anchor: {line: 1, character: 23} + active: {line: 1, character: 23} + marks: {} +finalState: + documentContents: |- + class Aaa { + public = "ccc"; + } + selections: + - anchor: {line: 1, character: 11} + active: {line: 1, character: 11} diff --git a/queries/javascript.core.scm b/queries/javascript.core.scm index 93ec9109aac..864fd57af93 100644 --- a/queries/javascript.core.scm +++ b/queries/javascript.core.scm @@ -1,7 +1,56 @@ -(_ - name: (_) @name +;; import javascript.function.scm + +( + (_ + name: (_) @name + ) @_.domain + (#not-parent-type? @_.domain export_statement) + (#not-type? + @_.domain + variable_declarator + method_signature + abstract_method_signature + public_field_definition + field_definition + ) +) +(export_statement + (_ + name: (_) @name + ) @dummy + (#not-type? @dummy variable_declarator) ) @_.domain +( + [ + (lexical_declaration + (variable_declarator + name: (_) @name + ) + ) + ;; Note that we can't merge this with the variable declaration above because + ;; of https://github.com/tree-sitter/tree-sitter/issues/1442#issuecomment-1584628651 + (variable_declaration + (variable_declarator + name: (_) @name + ) + ) + ] @_.domain + (#not-parent-type? @_.domain export_statement) + (#allow-multiple! @name) +) + +( + (export_statement + (_ + (variable_declarator + name: (_) @name + ) + ) + ) @_.domain + (#allow-multiple! @name) +) + (augmented_assignment_expression left: (_) @name ) @_.domain diff --git a/queries/javascript.function.scm b/queries/javascript.function.scm new file mode 100644 index 00000000000..13f996af645 --- /dev/null +++ b/queries/javascript.function.scm @@ -0,0 +1,159 @@ +;; Anonymous functions +[ + ;; function() {} + (function + !name + ) + + ;; function *() {} + (generator_function + !name + ) + + ;; () => {} + (arrow_function) +] @anonymousFunction + +;; If we export an anonymous function as default, it semantically feels like a +;; named function. +(export_statement + [ + ;; export default function() {} + (function + !name + ) + + ;; export default function *() {} + (generator_function + !name + ) + + ;; export default () => {} + (arrow_function) + ] +) @namedFunction + +;; Named functions without export +( + [ + ;; function foo() {} + (function_declaration + name: (_) @functionName + ) + + ;; function *foo() {} + (generator_function_declaration + name: (_) @functionName + ) + + ;; (let | const) foo = () => {} + ;; (let | const) foo = function() {} + ;; (let | const) foo = function *() {} + (lexical_declaration + (variable_declarator + name: (_) @functionName + [ + (function + !name + ) + (generator_function + !name + ) + (arrow_function) + ] + ) + ) + + ;; var foo = () => {} + ;; var foo = function() {} + ;; var foo = function *() {} + ;; Note that we can't merge this with the variable declaration above because + ;; of https://github.com/tree-sitter/tree-sitter/issues/1442#issuecomment-1584628651 + (variable_declaration + (variable_declarator + name: (_) @functionName + [ + (function + !name + ) + (generator_function + !name + ) + (arrow_function) + ] + ) + ) + ] @namedFunction @functionName.domain + (#not-parent-type? @namedFunction export_statement) +) + +;; Exported named functions +(export_statement + [ + ;; export [default] function foo() {} + (function_declaration + name: (_) @functionName + ) + + ;; export [default] function *foo() {} + (generator_function_declaration + name: (_) @functionName + ) + + ;; export [default] (let | const | var) foo = () => {} + ;; export [default] (let | const | var) foo = function() {} + ;; export [default] (let | const | var) foo = function *() {} + (_ + (variable_declarator + name: (_) @functionName + [ + (function + !name + ) + (generator_function + !name + ) + (arrow_function) + ] + ) + ) + ] +) @namedFunction @functionName.domain + +;; Note that there are a few Typescript-specific function declarations that we +;; don't handle here; see typescript.scm. +;; We also don't handle function declarations that only exist in Javascript; +;; see javascript.scm. +[ + ;; (function foo() {}) + (function + name: (_) @functionName + ) + + ;; (function *foo() {}) + (generator_function + name: (_) @functionName + ) + + ;; foo() {} + ;; (in class bodies) + (method_definition + name: (_) @functionName + ) + + ;; foo = () => {}; + ;; foo = function() {}; + ;; foo = function *() {}; + (assignment_expression + left: (_) @functionName + right: [ + (function + !name + ) + (generator_function + !name + ) + (arrow_function) + ] + ) +] @namedFunction @functionName.domain diff --git a/queries/javascript.scm b/queries/javascript.scm index 1c1e8ff4a21..381e7b1ff05 100644 --- a/queries/javascript.scm +++ b/queries/javascript.scm @@ -3,3 +3,35 @@ ;; import javascript.jsx.scm ;; import javascript.core.scm + +;; Define this here because the `field_definition` node type doesn't exist +;; in typescript. +( + ;; foo = () => {}; + ;; foo = function() {}; + ;; foo = function *() {}; + ;; (inside class bodies) + (field_definition + property: (_) @functionName + value: [ + (function + !name + ) + (generator_function + !name + ) + (arrow_function) + ] + ) @namedFunction.start @functionName.domain.start + . + ";"? @namedFunction.end @functionName.domain.end +) + +( + ;; foo = ...; + (field_definition + property: (_) @name + ) @name.domain.start + . + ";"? @name.domain.end +) diff --git a/queries/typescript.scm b/queries/typescript.scm index df1cd0f4565..6be6ee6dab2 100644 --- a/queries/typescript.scm +++ b/queries/typescript.scm @@ -11,3 +11,48 @@ (required_parameter (identifier) @name ) @_.domain + +;; Define these here because these node types don't exist in javascript. +( + [ + ;; foo(): void; + ;; (in interface) + ;; foo() {} + ;; (in class) + (method_signature + name: (_) @functionName @name + ) + + ;; abstract foo(): void; + (abstract_method_signature + name: (_) @functionName @name + ) + + ;; [public | private | protected] foo = () => {}; + ;; [public | private | protected] foo = function() {}; + ;; [public | private | protected] foo = function *() {}; + (public_field_definition + name: (_) @functionName + value: [ + (function + !name + ) + (generator_function + !name + ) + (arrow_function) + ] + ) + ] @namedFunction.start @functionName.domain.start @name.domain.start + . + ";"? @namedFunction.end @functionName.domain.end @name.domain.end +) + +( + ;; [public | private | protected] foo = ...; + (public_field_definition + name: (_) @name + ) @name.domain.start + . + ";"? @name.domain.end +) diff --git a/queries/typescriptreact.scm b/queries/typescriptreact.scm index 792c4b5133a..934357070cd 100644 --- a/queries/typescriptreact.scm +++ b/queries/typescriptreact.scm @@ -1,2 +1,2 @@ -;; import javascriptreact.scm +;; import javascript.jsx.scm ;; import typescript.scm