Skip to content

Commit

Permalink
add Go branch scope support (#1854)
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
3 people authored Nov 30, 2023
1 parent e5d1dfc commit 6660914
Show file tree
Hide file tree
Showing 29 changed files with 935 additions and 2 deletions.
57 changes: 57 additions & 0 deletions data/playground/go/branch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package p

func switches(x any) {
switch x {
case 1:
// bar
case 2:
x = nil
case "s":
case 4, "t":
x = 7
// qux
case 5:
// foo
fallthrough
default:
panic("x")
}
switch x := x.(type) {
case int:
x++
case string, struct{}:
println(x)
default:
panic(x)
}
switch {
case x == 1:
panic("one")
case false:
// unreachable
}
}

func ifElseChains(x int) {
if y := 0; x == 1 {
// foo
} else if z:=0; x == 2 {
x--
x--
x--
} else if z:=0; x == 2 {
x--
x--
x--
} else if x == 3 {
x++
} else if x == 3 {
x++
} else {
x *= 2
}

if x == 4{
x++
}
}
18 changes: 17 additions & 1 deletion packages/common/src/types/Position.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Range } from "..";
import { Range, TextDocument } from "..";

export class Position {
/**
Expand Down Expand Up @@ -151,3 +151,19 @@ export class Position {
return this.concise();
}
}

/**
* adjustPosition returns a new position that is offset by the given amount.
* It corrects line and character positions to remain valid in doc.
* @param doc The document
* @param pos The position to adjust
* @param by The amount to adjust by
* @returns The adjusted position
*/
export function adjustPosition(
doc: TextDocument,
pos: Position,
by: number,
): Position {
return doc.positionAt(doc.offsetAt(pos) + by);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Range } from "@cursorless/common";
import { Range, adjustPosition } from "@cursorless/common";
import { z } from "zod";
import { makeRangeFromPositions } from "../../util/nodeSelectors";
import { MutableQueryCapture } from "./QueryCapture";
Expand Down Expand Up @@ -139,6 +139,26 @@ class ShrinkToMatch extends QueryPredicateOperator<ShrinkToMatch> {
}
}

/**
* A predicate operator that modifies the range of the match by trimming trailing whitespace,
* similar to the javascript trimEnd function.
*/
class TrimEnd extends QueryPredicateOperator<TrimEnd> {
name = "trim-end!" as const;
schema = z.tuple([q.node]);

run(nodeInfo: MutableQueryCapture) {
const { document, range } = nodeInfo;
const text = document.getText(range);
const whitespaceLength = text.length - text.trimEnd().length;
nodeInfo.range = new Range(
range.start,
adjustPosition(document, range.end, -whitespaceLength),
);
return true;
}
}

/**
* Indicates that it is ok for multiple captures to have the same domain but
* different targets. For example, if we have the query `(#allow-multiple!
Expand Down Expand Up @@ -197,6 +217,7 @@ class InsertionDelimiter extends QueryPredicateOperator<InsertionDelimiter> {
export const queryPredicateOperators = [
new Log(),
new NotType(),
new TrimEnd(),
new NotParentType(),
new IsNthChild(),
new ChildRange(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 6
spokenForm: change branch
action:
name: clearAndSetSelection
target:
type: primitive
modifiers:
- type: containingScope
scopeType: {type: branch}
usePrePhraseSnapshot: true
initialState:
documentContents: "if x {\n\tx++\n} else {\n\tx--\n}"
selections:
- anchor: {line: 4, character: 1}
active: {line: 4, character: 1}
marks: {}
finalState:
documentContents: "if x {\n\tx++\n} "
selections:
- anchor: {line: 2, character: 2}
active: {line: 2, character: 2}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 6
spokenForm: change branch
action:
name: clearAndSetSelection
target:
type: primitive
modifiers:
- type: containingScope
scopeType: {type: branch}
usePrePhraseSnapshot: true
initialState:
documentContents: "if x {\n\tx++\n} else {\n\tx--\n}"
selections:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
marks: {}
finalState:
documentContents: " else {\n\tx--\n}"
selections:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 6
spokenForm: change branch
action:
name: clearAndSetSelection
target:
type: primitive
modifiers:
- type: containingScope
scopeType: {type: branch}
usePrePhraseSnapshot: true
initialState:
documentContents: "if x {\n\tx++\n} else if y {\n\ty++\n} else {\n\tx--\n}"
selections:
- anchor: {line: 2, character: 7}
active: {line: 2, character: 7}
marks: {}
finalState:
documentContents: "if x {\n\tx++\n} else {\n\tx--\n}"
selections:
- anchor: {line: 2, character: 2}
active: {line: 2, character: 2}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
languageId: go
command:
version: 6
spokenForm: change branch air
action:
name: clearAndSetSelection
target:
type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: a}
modifiers:
- type: containingScope
scopeType: {type: branch}
usePrePhraseSnapshot: true
initialState:
documentContents: |-
switch x {
case 1:
case 2:
panic(x)
}
selections:
- anchor: {line: 4, character: 1}
active: {line: 4, character: 1}
marks:
default.a:
start: {line: 2, character: 0}
end: {line: 2, character: 4}
finalState:
documentContents: |-
switch x {
case 1:
}
selections:
- anchor: {line: 2, character: 0}
active: {line: 2, character: 0}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
languageId: go
command:
version: 6
spokenForm: change branch cap
action:
name: clearAndSetSelection
target:
type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: c}
modifiers:
- type: containingScope
scopeType: {type: branch}
usePrePhraseSnapshot: true
initialState:
documentContents: |-
switch x {
case 1:
case 2:
}
selections:
- anchor: {line: 2, character: 7}
active: {line: 2, character: 7}
marks:
default.c:
start: {line: 1, character: 0}
end: {line: 1, character: 4}
finalState:
documentContents: |-
switch x {
case 2:
}
selections:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 0}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
languageId: go
command:
version: 6
spokenForm: change branch cap
action:
name: clearAndSetSelection
target:
type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: c}
modifiers:
- type: containingScope
scopeType: {type: branch}
usePrePhraseSnapshot: true
initialState:
documentContents: |-
switch x := x.(type) {
case int:
default:
panic(x)
}
selections:
- anchor: {line: 2, character: 8}
active: {line: 2, character: 8}
marks:
default.c:
start: {line: 1, character: 0}
end: {line: 1, character: 4}
finalState:
documentContents: |-
switch x := x.(type) {
default:
panic(x)
}
selections:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 0}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
languageId: go
command:
version: 6
spokenForm: change branch drum
action:
name: clearAndSetSelection
target:
type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: d}
modifiers:
- type: containingScope
scopeType: {type: branch}
usePrePhraseSnapshot: true
initialState:
documentContents: |-
switch x := x.(type) {
case int:
default:
panic(x)
}
selections:
- anchor: {line: 2, character: 8}
active: {line: 2, character: 8}
marks:
default.d:
start: {line: 2, character: 0}
end: {line: 2, character: 7}
finalState:
documentContents: |-
switch x := x.(type) {
case int:
}
selections:
- anchor: {line: 2, character: 0}
active: {line: 2, character: 0}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
languageId: go
command:
version: 6
spokenForm: change every branch
action:
name: clearAndSetSelection
target:
type: primitive
modifiers:
- type: everyScope
scopeType: {type: branch}
usePrePhraseSnapshot: true
initialState:
documentContents: "if x {\n\tx++\n} else if y {\n\ty++\n} else {\n\tx--\n}"
selections:
- anchor: {line: 0, character: 1}
active: {line: 0, character: 1}
marks: {}
finalState:
documentContents: " "
selections:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
- anchor: {line: 0, character: 1}
active: {line: 0, character: 1}
- anchor: {line: 0, character: 2}
active: {line: 0, character: 2}
Loading

0 comments on commit 6660914

Please sign in to comment.