mirror of
https://github.com/cursorless-dev/cursorless.git
synced 2024-10-05 05:17:38 +03:00
Add suffixedMatcher; use for keys (#260)
* Add suffixedMatcher; use for keys * Fix whitespace * Fix tests
This commit is contained in:
parent
4a5b5501bf
commit
8488e917d0
@ -1,7 +1,7 @@
|
||||
import {
|
||||
createPatternMatchers,
|
||||
argumentMatcher,
|
||||
valueMatcher,
|
||||
prefixedMatcher,
|
||||
} from "../util/nodeMatchers";
|
||||
import { NodeMatcherAlternative, ScopeType } from "../typings/Types";
|
||||
|
||||
@ -95,7 +95,7 @@ const nodeMatchers: Partial<Record<ScopeType, NodeMatcherAlternative>> = {
|
||||
"function_definition[declarator][declarator]", // void funcName() {}
|
||||
"declaration.function_declarator![declarator]", // void funcName();
|
||||
],
|
||||
value: valueMatcher(
|
||||
value: prefixedMatcher(
|
||||
"*[declarator][value]",
|
||||
"*[value]",
|
||||
"assignment_expression[right]",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {
|
||||
createPatternMatchers,
|
||||
argumentMatcher,
|
||||
valueMatcher,
|
||||
prefixedMatcher,
|
||||
} from "../util/nodeMatchers";
|
||||
import { NodeMatcherAlternative, ScopeType } from "../typings/Types";
|
||||
|
||||
@ -62,7 +62,7 @@ const nodeMatchers: Partial<Record<ScopeType, NodeMatcherAlternative>> = {
|
||||
"method_declaration.identifier!",
|
||||
"constructor_declaration.identifier!",
|
||||
],
|
||||
value: valueMatcher("*[declarator][value]", "*[value]"),
|
||||
value: prefixedMatcher("*[declarator][value]", "*[value]"),
|
||||
collectionItem: argumentMatcher("array_initializer"),
|
||||
argumentOrParameter: argumentMatcher("formal_parameters", "argument_list"),
|
||||
};
|
||||
|
@ -1,7 +1,8 @@
|
||||
import {
|
||||
createPatternMatchers,
|
||||
argumentMatcher,
|
||||
valueMatcher,
|
||||
prefixedMatcher,
|
||||
suffixedMatcher,
|
||||
} from "../util/nodeMatchers";
|
||||
import { ScopeType, NodeMatcherAlternative } from "../typings/Types";
|
||||
|
||||
@ -10,8 +11,8 @@ const nodeMatchers: Partial<Record<ScopeType, NodeMatcherAlternative>> = {
|
||||
list: "array",
|
||||
string: "string",
|
||||
comment: "comment",
|
||||
collectionKey: "pair[key]",
|
||||
value: valueMatcher("*[value]"),
|
||||
collectionKey: suffixedMatcher("pair[key]"),
|
||||
value: prefixedMatcher("*[value]"),
|
||||
collectionItem: argumentMatcher("object", "array"),
|
||||
};
|
||||
|
||||
|
@ -2,7 +2,8 @@ import { SyntaxNode } from "web-tree-sitter";
|
||||
import {
|
||||
createPatternMatchers,
|
||||
argumentMatcher,
|
||||
valueMatcher,
|
||||
prefixedMatcher,
|
||||
suffixedMatcher,
|
||||
} from "../util/nodeMatchers";
|
||||
import { NodeMatcherAlternative, ScopeType } from "../typings/Types";
|
||||
|
||||
@ -46,7 +47,7 @@ const nodeMatchers: Partial<Record<ScopeType, NodeMatcherAlternative>> = {
|
||||
list: listTypes,
|
||||
statement: STATEMENT_TYPES,
|
||||
string: "string",
|
||||
collectionKey: "pair[key]",
|
||||
collectionKey: suffixedMatcher("pair[key]"),
|
||||
ifStatement: "if_statement",
|
||||
anonymousFunction: "lambda",
|
||||
functionCall: "call",
|
||||
@ -55,7 +56,7 @@ const nodeMatchers: Partial<Record<ScopeType, NodeMatcherAlternative>> = {
|
||||
className: "class_definition[name]",
|
||||
namedFunction: "decorated_definition?.function_definition",
|
||||
functionName: "function_definition[name]",
|
||||
type: valueMatcher("function_definition[return_type]", "*[type]"),
|
||||
type: prefixedMatcher("function_definition[return_type]", "*[type]"),
|
||||
name: [
|
||||
"assignment[left]",
|
||||
"typed_parameter.identifier!",
|
||||
@ -63,7 +64,7 @@ const nodeMatchers: Partial<Record<ScopeType, NodeMatcherAlternative>> = {
|
||||
"*[name]",
|
||||
],
|
||||
collectionItem: argumentMatcher(...dictionaryTypes, ...listTypes),
|
||||
value: valueMatcher("assignment[right]", "~subscript[value]"),
|
||||
value: prefixedMatcher("assignment[right]", "~subscript[value]"),
|
||||
argumentOrParameter: argumentMatcher("parameters", "argument_list"),
|
||||
};
|
||||
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
patternMatcher,
|
||||
createPatternMatchers,
|
||||
argumentMatcher,
|
||||
suffixedMatcher,
|
||||
} from "../util/nodeMatchers";
|
||||
import {
|
||||
NodeMatcherAlternative,
|
||||
@ -86,7 +87,10 @@ const nodeMatchers: Partial<Record<ScopeType, NodeMatcherAlternative>> = {
|
||||
map: mapTypes,
|
||||
list: listTypes,
|
||||
string: ["string", "template_string"],
|
||||
collectionKey: ["pair[key]", "jsx_attribute.property_identifier!"],
|
||||
collectionKey: suffixedMatcher(
|
||||
"pair[key]",
|
||||
"jsx_attribute.property_identifier!"
|
||||
),
|
||||
collectionItem: argumentMatcher(...mapTypes, ...listTypes),
|
||||
value: valueMatcher(),
|
||||
ifStatement: "if_statement",
|
||||
|
@ -0,0 +1,31 @@
|
||||
spokenForm: chuck key
|
||||
languageId: python
|
||||
command:
|
||||
actionName: remove
|
||||
partialTargets:
|
||||
- type: primitive
|
||||
modifier: {type: containingScope, scopeType: collectionKey, includeSiblings: false}
|
||||
extraArgs: []
|
||||
marks: {}
|
||||
initialState:
|
||||
documentContents: |-
|
||||
{
|
||||
"foo": "bar",
|
||||
"baz": "bongo",
|
||||
}
|
||||
selections:
|
||||
- anchor: {line: 1, character: 5}
|
||||
active: {line: 1, character: 5}
|
||||
finalState:
|
||||
documentContents: |-
|
||||
{
|
||||
"bar",
|
||||
"baz": "bongo",
|
||||
}
|
||||
selections:
|
||||
- anchor: {line: 1, character: 4}
|
||||
active: {line: 1, character: 4}
|
||||
thatMark:
|
||||
- anchor: {line: 1, character: 4}
|
||||
active: {line: 1, character: 4}
|
||||
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: outside, modifier: {type: containingScope, scopeType: collectionKey, includeSiblings: false}}]
|
@ -0,0 +1,31 @@
|
||||
spokenForm: chuck key
|
||||
languageId: python
|
||||
command:
|
||||
actionName: remove
|
||||
partialTargets:
|
||||
- type: primitive
|
||||
modifier: {type: containingScope, scopeType: collectionKey, includeSiblings: false}
|
||||
extraArgs: []
|
||||
marks: {}
|
||||
initialState:
|
||||
documentContents: |-
|
||||
{
|
||||
"foo": "bar",
|
||||
"baz": "bongo",
|
||||
}
|
||||
selections:
|
||||
- anchor: {line: 1, character: 12}
|
||||
active: {line: 1, character: 12}
|
||||
finalState:
|
||||
documentContents: |-
|
||||
{
|
||||
"bar",
|
||||
"baz": "bongo",
|
||||
}
|
||||
selections:
|
||||
- anchor: {line: 1, character: 5}
|
||||
active: {line: 1, character: 5}
|
||||
thatMark:
|
||||
- anchor: {line: 1, character: 4}
|
||||
active: {line: 1, character: 4}
|
||||
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: outside, modifier: {type: containingScope, scopeType: collectionKey, includeSiblings: false}}]
|
@ -13,11 +13,11 @@ initialState:
|
||||
- anchor: {line: 0, character: 2}
|
||||
active: {line: 0, character: 2}
|
||||
finalState:
|
||||
documentContents: "foo: str "
|
||||
documentContents: "foo: str"
|
||||
selections:
|
||||
- anchor: {line: 0, character: 2}
|
||||
active: {line: 0, character: 2}
|
||||
thatMark:
|
||||
- anchor: {line: 0, character: 9}
|
||||
active: {line: 0, character: 9}
|
||||
- anchor: {line: 0, character: 8}
|
||||
active: {line: 0, character: 8}
|
||||
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: outside, modifier: {type: containingScope, scopeType: value, includeSiblings: false}}]
|
||||
|
@ -0,0 +1,29 @@
|
||||
spokenForm: chuck key
|
||||
languageId: typescript
|
||||
command:
|
||||
actionName: remove
|
||||
partialTargets:
|
||||
- type: primitive
|
||||
modifier: {type: containingScope, scopeType: collectionKey, includeSiblings: false}
|
||||
extraArgs: []
|
||||
marks: {}
|
||||
initialState:
|
||||
documentContents: |-
|
||||
{
|
||||
foo: "bar"
|
||||
}
|
||||
selections:
|
||||
- anchor: {line: 1, character: 5}
|
||||
active: {line: 1, character: 5}
|
||||
finalState:
|
||||
documentContents: |-
|
||||
{
|
||||
"bar"
|
||||
}
|
||||
selections:
|
||||
- anchor: {line: 1, character: 4}
|
||||
active: {line: 1, character: 4}
|
||||
thatMark:
|
||||
- anchor: {line: 1, character: 4}
|
||||
active: {line: 1, character: 4}
|
||||
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: outside, modifier: {type: containingScope, scopeType: collectionKey, includeSiblings: false}}]
|
@ -0,0 +1,29 @@
|
||||
spokenForm: clear key
|
||||
languageId: typescript
|
||||
command:
|
||||
actionName: clearAndSetSelection
|
||||
partialTargets:
|
||||
- type: primitive
|
||||
modifier: {type: containingScope, scopeType: collectionKey, includeSiblings: false}
|
||||
extraArgs: []
|
||||
marks: {}
|
||||
initialState:
|
||||
documentContents: |-
|
||||
{
|
||||
foo: "bar"
|
||||
}
|
||||
selections:
|
||||
- anchor: {line: 1, character: 10}
|
||||
active: {line: 1, character: 10}
|
||||
finalState:
|
||||
documentContents: |-
|
||||
{
|
||||
: "bar"
|
||||
}
|
||||
selections:
|
||||
- anchor: {line: 1, character: 4}
|
||||
active: {line: 1, character: 4}
|
||||
thatMark:
|
||||
- anchor: {line: 1, character: 4}
|
||||
active: {line: 1, character: 4}
|
||||
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: collectionKey, includeSiblings: false}}]
|
@ -11,6 +11,7 @@ import {
|
||||
simpleSelectionExtractor,
|
||||
argumentSelectionExtractor,
|
||||
selectWithLeadingDelimiter,
|
||||
selectWithTrailingDelimiter,
|
||||
} from "./nodeSelectors";
|
||||
import {
|
||||
typedNodeFinder,
|
||||
@ -72,10 +73,26 @@ export function argumentMatcher(...parentTypes: string[]): NodeMatcher {
|
||||
);
|
||||
}
|
||||
|
||||
export function valueMatcher(...patterns: string[]): NodeMatcher {
|
||||
/**
|
||||
* Given `patterns`, creates a node matcher that will add leading delimiter to
|
||||
* removal range.
|
||||
* @param patterns Patterns for pattern finder
|
||||
* @returns A node matcher
|
||||
*/
|
||||
export function prefixedMatcher(...patterns: string[]): NodeMatcher {
|
||||
return matcher(patternFinder(...patterns), selectWithLeadingDelimiter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given `patterns`, creates a node matcher that will add trailing delimiter to
|
||||
* removal range.
|
||||
* @param patterns Patterns for pattern finder
|
||||
* @returns A node matcher
|
||||
*/
|
||||
export function suffixedMatcher(...patterns: string[]): NodeMatcher {
|
||||
return matcher(patternFinder(...patterns), selectWithTrailingDelimiter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new matcher that will try the given matchers in sequence until one
|
||||
* returns non-null
|
||||
|
@ -40,11 +40,11 @@ export function selectWithLeadingDelimiter(
|
||||
editor: TextEditor,
|
||||
node: SyntaxNode
|
||||
): SelectionWithContext {
|
||||
const leadingDelimiterToken = node.previousSibling;
|
||||
const leadingNonDelimiterToken = node.previousSibling?.previousSibling;
|
||||
|
||||
const leadingDelimiterRange =
|
||||
leadingDelimiterToken != null
|
||||
? makeRange(leadingDelimiterToken.startPosition, node.startPosition)
|
||||
leadingNonDelimiterToken != null
|
||||
? makeRange(leadingNonDelimiterToken.endPosition, node.startPosition)
|
||||
: null;
|
||||
|
||||
return {
|
||||
@ -55,6 +55,25 @@ export function selectWithLeadingDelimiter(
|
||||
};
|
||||
}
|
||||
|
||||
export function selectWithTrailingDelimiter(
|
||||
editor: TextEditor,
|
||||
node: SyntaxNode
|
||||
): SelectionWithContext {
|
||||
const trailingNonDelimiterToken = node.nextSibling?.nextSibling;
|
||||
|
||||
const trailingDelimiterRange =
|
||||
trailingNonDelimiterToken != null
|
||||
? makeRange(node.endPosition, trailingNonDelimiterToken.startPosition)
|
||||
: null;
|
||||
|
||||
return {
|
||||
...simpleSelectionExtractor(editor, node),
|
||||
context: {
|
||||
trailingDelimiterRange,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function getNextNonDelimiterNode(
|
||||
startNode: SyntaxNode,
|
||||
isDelimiterNode: (node: SyntaxNode) => boolean
|
||||
|
Loading…
Reference in New Issue
Block a user