Skip to content

Commit 2390ec4

Browse files
r
1 parent 47334fd commit 2390ec4

File tree

4 files changed

+114
-7
lines changed

4 files changed

+114
-7
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
foo().bar()
2+
---
3+
4+
[#1 Content] =
5+
[#1 Removal] =
6+
[#1 Domain] = 0:0-0:5
7+
>-----<
8+
0| foo().bar()
9+
10+
[#1 Insertion delimiter] = " "
11+
12+
13+
[#2 Content] =
14+
[#2 Removal] =
15+
[#2 Domain] = 0:0-0:11
16+
>-----------<
17+
0| foo().bar()
18+
19+
[#2 Insertion delimiter] = " "
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
foo().bar()
2+
---
3+
4+
[#1 Content] =
5+
[#1 Removal] = 0:0-0:3
6+
>---<
7+
0| foo().bar()
8+
9+
[#1 Domain] = 0:0-0:5
10+
>-----<
11+
0| foo().bar()
12+
13+
[#1 Insertion delimiter] = " "
14+
15+
16+
[#2 Content] =
17+
[#2 Removal] = 0:0-0:9
18+
>---------<
19+
0| foo().bar()
20+
21+
[#2 Domain] = 0:0-0:11
22+
>-----------<
23+
0| foo().bar()
24+
25+
[#2 Insertion delimiter] = " "

packages/cursorless-engine/src/languages/TreeSitterQuery/queryPredicateOperators.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,67 @@ class GrowToNamedSiblings extends QueryPredicateOperator<GrowToNamedSiblings> {
264264
return true;
265265
}
266266
}
267+
/**
268+
* A predicate operator that modifies the range of the match to grow to leading siblings of the same type.
269+
*
270+
* The `leadingSeparator` argument specificies the separator each node except the first sibling will be separated by.
271+
*
272+
* ```
273+
* (#call-chain! @foo ".")
274+
* ```
275+
*/
276+
class CallChain extends QueryPredicateOperator<CallChain> {
277+
name = "call-chain!" as const;
278+
schema = z.union([z.tuple([q.node]), z.tuple([q.node, q.string])]);
279+
280+
run(nodeInfo: MutableQueryCapture, leadingSeparator: string) {
281+
const { node, range, document } = nodeInfo;
282+
283+
if (node.parent == null) {
284+
throw Error("Node has no parent");
285+
}
286+
287+
const { children } = node.parent;
288+
const nodeIndex = children.findIndex((n) => n.id === node.id);
289+
290+
if (nodeIndex === -1) {
291+
throw Error("Node not found in parent");
292+
}
293+
294+
let start = children[nodeIndex];
295+
let end = start;
296+
297+
for (let i = nodeIndex; i > -1; --i) {
298+
const child = children[i];
299+
300+
if (child.type !== node.type) {
301+
break;
302+
}
303+
304+
start = child;
305+
306+
const childRange = makeRangeFromPositions(
307+
child.startPosition,
308+
child.endPosition,
309+
);
310+
311+
const childText = document.getText(childRange);
312+
313+
if (!childText.startsWith(leadingSeparator)) {
314+
break;
315+
}
316+
}
317+
318+
if (start.id !== end.id) {
319+
nodeInfo.range = makeRangeFromPositions(
320+
start.startPosition,
321+
end.endPosition,
322+
);
323+
}
324+
325+
return true;
326+
}
327+
}
267328

268329
/**
269330
* A predicate operator that modifies the range of the match by trimming trailing whitespace,
@@ -442,6 +503,7 @@ export const queryPredicateOperators = [
442503
new CharacterRange(),
443504
new ShrinkToMatch(),
444505
new GrowToNamedSiblings(),
506+
new CallChain(),
445507
new AllowMultiple(),
446508
new InsertionDelimiter(),
447509
new SingleOrMultilineDelimiter(),

queries/r.scm

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,16 @@
134134
;; Function calls
135135
;;!! foo()
136136
;;! ^^^^^
137-
;;! -----
138-
(call) @functionCall @argumentOrParameter.iteration.domain
139-
140-
;;!! foo()
141137
;;! ^^^
142138
;;! -----
143-
(call
144-
(identifier) @functionCallee
145-
) @_.domain
139+
(
140+
(call
141+
(identifier) @functionCallee.end
142+
) @functionCall @functionCallee.start.startOf @functionCallee.domain
143+
(#call-chain! @functionCall ".")
144+
(#call-chain! @functionCallee.start.startOf ".")
145+
(#call-chain! @functionCallee.domain ".")
146+
)
146147

147148
;; Technically lists and arrays are just calls to the function `list` or `c`
148149
;;!! list(1, 2, 3)

0 commit comments

Comments
 (0)