Skip to content

Commit 6660914

Browse files
josharianpre-commit-ci-lite[bot]pokey
authored
add Go branch scope support (#1854)
Not all the behavior is perfect (I'm looking at you, pour and drink), but it's better than not existing. The perfect is the enemy of the good. ## 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 e5d1dfc commit 6660914

29 files changed

+935
-2
lines changed

data/playground/go/branch.go

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package p
2+
3+
func switches(x any) {
4+
switch x {
5+
case 1:
6+
// bar
7+
case 2:
8+
x = nil
9+
case "s":
10+
case 4, "t":
11+
x = 7
12+
// qux
13+
case 5:
14+
// foo
15+
fallthrough
16+
default:
17+
panic("x")
18+
}
19+
switch x := x.(type) {
20+
case int:
21+
x++
22+
case string, struct{}:
23+
println(x)
24+
default:
25+
panic(x)
26+
}
27+
switch {
28+
case x == 1:
29+
panic("one")
30+
case false:
31+
// unreachable
32+
}
33+
}
34+
35+
func ifElseChains(x int) {
36+
if y := 0; x == 1 {
37+
// foo
38+
} else if z:=0; x == 2 {
39+
x--
40+
x--
41+
x--
42+
} else if z:=0; x == 2 {
43+
x--
44+
x--
45+
x--
46+
} else if x == 3 {
47+
x++
48+
} else if x == 3 {
49+
x++
50+
} else {
51+
x *= 2
52+
}
53+
54+
if x == 4{
55+
x++
56+
}
57+
}

packages/common/src/types/Position.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Range } from "..";
1+
import { Range, TextDocument } from "..";
22

33
export class Position {
44
/**
@@ -151,3 +151,19 @@ export class Position {
151151
return this.concise();
152152
}
153153
}
154+
155+
/**
156+
* adjustPosition returns a new position that is offset by the given amount.
157+
* It corrects line and character positions to remain valid in doc.
158+
* @param doc The document
159+
* @param pos The position to adjust
160+
* @param by The amount to adjust by
161+
* @returns The adjusted position
162+
*/
163+
export function adjustPosition(
164+
doc: TextDocument,
165+
pos: Position,
166+
by: number,
167+
): Position {
168+
return doc.positionAt(doc.offsetAt(pos) + by);
169+
}

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

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Range } from "@cursorless/common";
1+
import { Range, adjustPosition } from "@cursorless/common";
22
import { z } from "zod";
33
import { makeRangeFromPositions } from "../../util/nodeSelectors";
44
import { MutableQueryCapture } from "./QueryCapture";
@@ -139,6 +139,26 @@ class ShrinkToMatch extends QueryPredicateOperator<ShrinkToMatch> {
139139
}
140140
}
141141

142+
/**
143+
* A predicate operator that modifies the range of the match by trimming trailing whitespace,
144+
* similar to the javascript trimEnd function.
145+
*/
146+
class TrimEnd extends QueryPredicateOperator<TrimEnd> {
147+
name = "trim-end!" as const;
148+
schema = z.tuple([q.node]);
149+
150+
run(nodeInfo: MutableQueryCapture) {
151+
const { document, range } = nodeInfo;
152+
const text = document.getText(range);
153+
const whitespaceLength = text.length - text.trimEnd().length;
154+
nodeInfo.range = new Range(
155+
range.start,
156+
adjustPosition(document, range.end, -whitespaceLength),
157+
);
158+
return true;
159+
}
160+
}
161+
142162
/**
143163
* Indicates that it is ok for multiple captures to have the same domain but
144164
* different targets. For example, if we have the query `(#allow-multiple!
@@ -197,6 +217,7 @@ class InsertionDelimiter extends QueryPredicateOperator<InsertionDelimiter> {
197217
export const queryPredicateOperators = [
198218
new Log(),
199219
new NotType(),
220+
new TrimEnd(),
200221
new NotParentType(),
201222
new IsNthChild(),
202223
new ChildRange(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
languageId: go
2+
command:
3+
version: 6
4+
spokenForm: change branch
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: branch}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: "if x {\n\tx++\n} else {\n\tx--\n}"
15+
selections:
16+
- anchor: {line: 4, character: 1}
17+
active: {line: 4, character: 1}
18+
marks: {}
19+
finalState:
20+
documentContents: "if x {\n\tx++\n} "
21+
selections:
22+
- anchor: {line: 2, character: 2}
23+
active: {line: 2, character: 2}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
languageId: go
2+
command:
3+
version: 6
4+
spokenForm: change branch
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: branch}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: "if x {\n\tx++\n} else {\n\tx--\n}"
15+
selections:
16+
- anchor: {line: 0, character: 0}
17+
active: {line: 0, character: 0}
18+
marks: {}
19+
finalState:
20+
documentContents: " else {\n\tx--\n}"
21+
selections:
22+
- anchor: {line: 0, character: 0}
23+
active: {line: 0, character: 0}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
languageId: go
2+
command:
3+
version: 6
4+
spokenForm: change branch
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: containingScope
11+
scopeType: {type: branch}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: "if x {\n\tx++\n} else if y {\n\ty++\n} else {\n\tx--\n}"
15+
selections:
16+
- anchor: {line: 2, character: 7}
17+
active: {line: 2, character: 7}
18+
marks: {}
19+
finalState:
20+
documentContents: "if x {\n\tx++\n} else {\n\tx--\n}"
21+
selections:
22+
- anchor: {line: 2, character: 2}
23+
active: {line: 2, character: 2}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
languageId: go
2+
command:
3+
version: 6
4+
spokenForm: change branch air
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
mark: {type: decoratedSymbol, symbolColor: default, character: a}
10+
modifiers:
11+
- type: containingScope
12+
scopeType: {type: branch}
13+
usePrePhraseSnapshot: true
14+
initialState:
15+
documentContents: |-
16+
switch x {
17+
case 1:
18+
case 2:
19+
panic(x)
20+
}
21+
selections:
22+
- anchor: {line: 4, character: 1}
23+
active: {line: 4, character: 1}
24+
marks:
25+
default.a:
26+
start: {line: 2, character: 0}
27+
end: {line: 2, character: 4}
28+
finalState:
29+
documentContents: |-
30+
switch x {
31+
case 1:
32+
33+
}
34+
selections:
35+
- anchor: {line: 2, character: 0}
36+
active: {line: 2, character: 0}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
languageId: go
2+
command:
3+
version: 6
4+
spokenForm: change branch cap
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
mark: {type: decoratedSymbol, symbolColor: default, character: c}
10+
modifiers:
11+
- type: containingScope
12+
scopeType: {type: branch}
13+
usePrePhraseSnapshot: true
14+
initialState:
15+
documentContents: |-
16+
switch x {
17+
case 1:
18+
case 2:
19+
}
20+
selections:
21+
- anchor: {line: 2, character: 7}
22+
active: {line: 2, character: 7}
23+
marks:
24+
default.c:
25+
start: {line: 1, character: 0}
26+
end: {line: 1, character: 4}
27+
finalState:
28+
documentContents: |-
29+
switch x {
30+
31+
case 2:
32+
}
33+
selections:
34+
- anchor: {line: 1, character: 0}
35+
active: {line: 1, character: 0}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
languageId: go
2+
command:
3+
version: 6
4+
spokenForm: change branch cap
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
mark: {type: decoratedSymbol, symbolColor: default, character: c}
10+
modifiers:
11+
- type: containingScope
12+
scopeType: {type: branch}
13+
usePrePhraseSnapshot: true
14+
initialState:
15+
documentContents: |-
16+
switch x := x.(type) {
17+
case int:
18+
default:
19+
panic(x)
20+
}
21+
selections:
22+
- anchor: {line: 2, character: 8}
23+
active: {line: 2, character: 8}
24+
marks:
25+
default.c:
26+
start: {line: 1, character: 0}
27+
end: {line: 1, character: 4}
28+
finalState:
29+
documentContents: |-
30+
switch x := x.(type) {
31+
32+
default:
33+
panic(x)
34+
}
35+
selections:
36+
- anchor: {line: 1, character: 0}
37+
active: {line: 1, character: 0}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
languageId: go
2+
command:
3+
version: 6
4+
spokenForm: change branch drum
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
mark: {type: decoratedSymbol, symbolColor: default, character: d}
10+
modifiers:
11+
- type: containingScope
12+
scopeType: {type: branch}
13+
usePrePhraseSnapshot: true
14+
initialState:
15+
documentContents: |-
16+
switch x := x.(type) {
17+
case int:
18+
default:
19+
panic(x)
20+
}
21+
selections:
22+
- anchor: {line: 2, character: 8}
23+
active: {line: 2, character: 8}
24+
marks:
25+
default.d:
26+
start: {line: 2, character: 0}
27+
end: {line: 2, character: 7}
28+
finalState:
29+
documentContents: |-
30+
switch x := x.(type) {
31+
case int:
32+
33+
}
34+
selections:
35+
- anchor: {line: 2, character: 0}
36+
active: {line: 2, character: 0}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
languageId: go
2+
command:
3+
version: 6
4+
spokenForm: change every branch
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
modifiers:
10+
- type: everyScope
11+
scopeType: {type: branch}
12+
usePrePhraseSnapshot: true
13+
initialState:
14+
documentContents: "if x {\n\tx++\n} else if y {\n\ty++\n} else {\n\tx--\n}"
15+
selections:
16+
- anchor: {line: 0, character: 1}
17+
active: {line: 0, character: 1}
18+
marks: {}
19+
finalState:
20+
documentContents: " "
21+
selections:
22+
- anchor: {line: 0, character: 0}
23+
active: {line: 0, character: 0}
24+
- anchor: {line: 0, character: 1}
25+
active: {line: 0, character: 1}
26+
- anchor: {line: 0, character: 2}
27+
active: {line: 0, character: 2}

0 commit comments

Comments
 (0)