mirror of
https://github.com/cursorless-dev/cursorless.git
synced 2024-10-04 21:07:21 +03:00
Simple node matcher improvements
This commit is contained in:
parent
681435e1cf
commit
2e0afe9af1
@ -50,6 +50,7 @@ export type ScopeType =
|
|||||||
| "class"
|
| "class"
|
||||||
| "arrowFunction"
|
| "arrowFunction"
|
||||||
| "namedFunction"
|
| "namedFunction"
|
||||||
|
| "pair"
|
||||||
| "ifStatement";
|
| "ifStatement";
|
||||||
export type PieceType = "subtoken" | "character";
|
export type PieceType = "subtoken" | "character";
|
||||||
|
|
||||||
|
@ -45,10 +45,10 @@ class Actions {
|
|||||||
}
|
}
|
||||||
const editor = editors[0];
|
const editor = editors[0];
|
||||||
|
|
||||||
editor.selections = targets.map((target) => target.selection.selection);
|
|
||||||
if (editor.viewColumn != null) {
|
if (editor.viewColumn != null) {
|
||||||
await commands.executeCommand(columnFocusCommands[editor.viewColumn]);
|
await commands.executeCommand(columnFocusCommands[editor.viewColumn]);
|
||||||
}
|
}
|
||||||
|
editor.selections = targets.map((target) => target.selection.selection);
|
||||||
editor.revealRange(editor.selections[0]);
|
editor.revealRange(editor.selections[0]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,28 +1,14 @@
|
|||||||
import { SyntaxNode } from "tree-sitter";
|
import { SyntaxNode } from "tree-sitter";
|
||||||
import { Position, Selection } from "vscode";
|
import { Position, Selection } from "vscode";
|
||||||
|
|
||||||
type NodeMatcher = (node: SyntaxNode) => boolean;
|
type NodeMatcher = (node: SyntaxNode, isInside: boolean) => Selection | null;
|
||||||
|
|
||||||
type NodeSelectionExtractor = (
|
|
||||||
node: SyntaxNode,
|
|
||||||
isInside: boolean
|
|
||||||
) => Selection | null;
|
|
||||||
|
|
||||||
interface NodeDescriptor {
|
|
||||||
matcher: NodeMatcher;
|
|
||||||
extractor: NodeSelectionExtractor;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasType(...typeNames: string[]): NodeMatcher {
|
function hasType(...typeNames: string[]): NodeMatcher {
|
||||||
return (node: SyntaxNode) => typeNames.includes(node.type);
|
return (node: SyntaxNode, isInside: boolean) =>
|
||||||
|
typeNames.includes(node.type) ? simpleSelectionExtractor(node) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const makeSimpleNodeDescriptor = (...typeNames: string[]) => ({
|
function simpleSelectionExtractor(node: SyntaxNode) {
|
||||||
matcher: hasType("pair"),
|
|
||||||
extractor: simpleSelectionExtractor,
|
|
||||||
});
|
|
||||||
|
|
||||||
function simpleSelectionExtractor(node: SyntaxNode, isInside: boolean) {
|
|
||||||
return new Selection(
|
return new Selection(
|
||||||
new Position(node.startPosition.row, node.startPosition.column),
|
new Position(node.startPosition.row, node.startPosition.column),
|
||||||
new Position(node.endPosition.row, node.endPosition.column)
|
new Position(node.endPosition.row, node.endPosition.column)
|
||||||
@ -30,25 +16,25 @@ function simpleSelectionExtractor(node: SyntaxNode, isInside: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const nodeMatchers = {
|
const nodeMatchers = {
|
||||||
class: makeSimpleNodeDescriptor("class_declaration"),
|
class: hasType("class_declaration"),
|
||||||
arrowFunction: makeSimpleNodeDescriptor("arrow_function"),
|
arrowFunction: hasType("arrow_function"),
|
||||||
pair: {
|
pair: (node: SyntaxNode, isInside: boolean) => {
|
||||||
matcher: hasType("pair"),
|
if (node.type !== "pair") {
|
||||||
extractor: (node: SyntaxNode, isInside: boolean) => {
|
return null;
|
||||||
return new Selection(
|
}
|
||||||
new Position(node.startPosition.row, node.startPosition.column),
|
return new Selection(
|
||||||
new Position(node.endPosition.row, node.endPosition.column)
|
new Position(node.startPosition.row, node.startPosition.column),
|
||||||
);
|
new Position(node.endPosition.row, node.endPosition.column)
|
||||||
},
|
);
|
||||||
},
|
},
|
||||||
namedFunction(node: SyntaxNode) {
|
namedFunction(node: SyntaxNode, isInside: boolean) {
|
||||||
// Simple case, eg
|
// Simple case, eg
|
||||||
// function foo() {}
|
// function foo() {}
|
||||||
if (
|
if (
|
||||||
node.type === "function_declaration" ||
|
node.type === "function_declaration" ||
|
||||||
node.type === "method_definition"
|
node.type === "method_definition"
|
||||||
) {
|
) {
|
||||||
return true;
|
return simpleSelectionExtractor(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Class property defined as field definition with arrow
|
// Class property defined as field definition with arrow
|
||||||
@ -61,14 +47,14 @@ const nodeMatchers = {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
node.valueNode.type === "arrow_function"
|
node.valueNode.type === "arrow_function"
|
||||||
) {
|
) {
|
||||||
return true;
|
return simpleSelectionExtractor(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// eg:
|
// eg:
|
||||||
// const foo = () => "hello"
|
// const foo = () => "hello"
|
||||||
if (node.type === "lexical_declaration") {
|
if (node.type === "lexical_declaration") {
|
||||||
if (node.namedChildCount !== 1) {
|
if (node.namedChildCount !== 1) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const child = node.firstNamedChild!;
|
const child = node.firstNamedChild!;
|
||||||
@ -78,13 +64,13 @@ const nodeMatchers = {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
child.valueNode.type === "arrow_function"
|
child.valueNode.type === "arrow_function"
|
||||||
) {
|
) {
|
||||||
return true;
|
return simpleSelectionExtractor(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return null;
|
||||||
},
|
},
|
||||||
ifStatement: makeSimpleNodeDescriptor("if_statement"),
|
ifStatement: hasType("if_statement"),
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nodeMatchers;
|
export default nodeMatchers;
|
||||||
|
@ -119,8 +119,12 @@ function getSelectionsFromMark(
|
|||||||
function transformSelection(
|
function transformSelection(
|
||||||
context: ProcessedTargetsContext,
|
context: ProcessedTargetsContext,
|
||||||
transformation: Transformation,
|
transformation: Transformation,
|
||||||
|
position: Position,
|
||||||
selection: SelectionWithEditor
|
selection: SelectionWithEditor
|
||||||
): SelectionWithEditor {
|
): SelectionWithEditor {
|
||||||
|
const isInside =
|
||||||
|
position === "end" || position === "start" || position === "inside";
|
||||||
|
|
||||||
switch (transformation.type) {
|
switch (transformation.type) {
|
||||||
case "identity":
|
case "identity":
|
||||||
return selection;
|
return selection;
|
||||||
@ -132,16 +136,11 @@ function transformSelection(
|
|||||||
const nodeMatcher = nodeMatchers[transformation.scopeType];
|
const nodeMatcher = nodeMatchers[transformation.scopeType];
|
||||||
|
|
||||||
while (node != null) {
|
while (node != null) {
|
||||||
if (nodeMatcher(node)) {
|
const matchedSelection = nodeMatcher(node, isInside);
|
||||||
|
if (matchedSelection != null) {
|
||||||
return {
|
return {
|
||||||
editor: selection.editor,
|
editor: selection.editor,
|
||||||
selection: new Selection(
|
selection: matchedSelection,
|
||||||
new vscode.Position(
|
|
||||||
node.startPosition.row,
|
|
||||||
node.startPosition.column
|
|
||||||
),
|
|
||||||
new vscode.Position(node.endPosition.row, node.endPosition.column)
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
console.log(node.type);
|
console.log(node.type);
|
||||||
|
Loading…
Reference in New Issue
Block a user