Skip to content

Commit a855424

Browse files
Added full line scope (#3095)
Line scope that includes leading and trailing whitespace `"change full line"`
1 parent c5c8a5a commit a855424

File tree

15 files changed

+179
-39
lines changed

15 files changed

+179
-39
lines changed

cursorless-talon/src/spoken_forms.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@
174174
"token": "token",
175175
"identifier": "identifier",
176176
"line": "line",
177+
"full line": "fullLine",
177178
"sentence": "sentence",
178179
"block": "paragraph",
179180
"file": "document",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Hello world
2+
---
3+
4+
[Content] =
5+
[Removal] =
6+
[Domain] = 0:0-0:17
7+
>-----------------<
8+
0| Hello world
9+
10+
[Insertion delimiter] = "\n"
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
2+
Hello
3+
world
4+
5+
---
6+
7+
[#1 Content] =
8+
[#1 Domain] = 0:0-0:0
9+
><
10+
0|
11+
12+
[#1 Removal] = 0:0-1:0
13+
>
14+
0|
15+
1| Hello
16+
<
17+
18+
[#1 Trailing delimiter] = 0:0-1:0
19+
>
20+
0|
21+
1| Hello
22+
<
23+
24+
[#1 Insertion delimiter] = "\n"
25+
26+
27+
[#2 Content] =
28+
[#2 Domain] = 1:0-1:5
29+
>-----<
30+
1| Hello
31+
32+
[#2 Removal] = 1:0-2:0
33+
>-----
34+
1| Hello
35+
2| world
36+
<
37+
38+
[#2 Leading delimiter] = 0:0-1:0
39+
>
40+
0|
41+
1| Hello
42+
<
43+
44+
[#2 Trailing delimiter] = 1:5-2:0
45+
>
46+
1| Hello
47+
2| world
48+
<
49+
50+
[#2 Insertion delimiter] = "\n"
51+
52+
53+
[#3 Content] =
54+
[#3 Domain] = 2:0-2:7
55+
>-------<
56+
2| world
57+
58+
[#3 Removal] = 2:0-3:0
59+
>-------
60+
2| world
61+
3|
62+
<
63+
64+
[#3 Leading delimiter] = 1:5-2:0
65+
>
66+
1| Hello
67+
2| world
68+
<
69+
70+
[#3 Trailing delimiter] = 2:7-3:0
71+
>
72+
2| world
73+
3|
74+
<
75+
76+
[#3 Insertion delimiter] = "\n"
77+
78+
79+
[#4 Content] =
80+
[#4 Domain] = 3:0-3:2
81+
>--<
82+
3|
83+
84+
[#4 Removal] = 2:7-3:2
85+
>
86+
2| world
87+
3|
88+
--<
89+
90+
[#4 Leading delimiter] = 2:7-3:0
91+
>
92+
2| world
93+
3|
94+
<
95+
96+
[#4 Insertion delimiter] = "\n"

data/scopeSupportFacetInfos.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@
141141

142142
- `fieldAccess` A field access
143143

144+
### fullLine
145+
146+
- `fullLine` A single full line in the document. Includes leading and trailing whitespace.
147+
144148
### functionCall
145149

146150
- `functionCall` A function call
@@ -196,7 +200,7 @@
196200

197201
### line
198202

199-
- `line` A single line in the document
203+
- `line` A single line in the document. Excludes leading and trailing whitespace.
200204

201205
### list
202206

packages/common/src/scopeSupportFacets/PlaintextScopeSupportFacetInfos.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,15 @@ export const plaintextScopeSupportFacetInfos: Record<
2424
scopeType: "identifier",
2525
},
2626
line: {
27-
description: "A single line in the document",
27+
description:
28+
"A single line in the document. Excludes leading and trailing whitespace.",
2829
scopeType: "line",
2930
},
31+
fullLine: {
32+
description:
33+
"A single full line in the document. Includes leading and trailing whitespace.",
34+
scopeType: "fullLine",
35+
},
3036
sentence: {
3137
description: "A single sentence in the document",
3238
scopeType: "sentence",

packages/common/src/scopeSupportFacets/scopeSupportFacets.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ export type PlaintextScopeSupportFacet =
303303
| "token"
304304
| "identifier"
305305
| "line"
306+
| "fullLine"
306307
| "sentence"
307308
| "paragraph"
308309
| "boundedParagraph"

packages/common/src/types/command/PartialTargetDescriptor.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ export const simpleScopeTypeTypes = [
193193
"token",
194194
"identifier",
195195
"line",
196+
"fullLine",
196197
"sentence",
197198
"paragraph",
198199
"boundedParagraph",

packages/cursorless-engine/src/processTargets/marks/LineNumberStage.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import type {
55
} from "@cursorless/common";
66
import { ide } from "../../singletons/ide.singleton";
77
import type { MarkStage } from "../PipelineStages.types";
8-
import { createLineTarget } from "../modifiers/scopeHandlers";
98
import type { LineTarget } from "../targets";
9+
import { createLineTarget } from "../targets";
1010

1111
export class LineNumberStage implements MarkStage {
1212
constructor(private mark: LineNumberMark) {}
@@ -21,8 +21,8 @@ export class LineNumberStage implements MarkStage {
2121
this.mark.lineNumberType,
2222
this.mark.lineNumber,
2323
);
24-
const contentRange = editor.document.lineAt(lineNumber).range;
25-
return [createLineTarget(editor, false, contentRange)];
24+
const line = editor.document.lineAt(lineNumber);
25+
return [createLineTarget(editor, false, line)];
2626
}
2727
}
2828

packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/LineScopeHandler.ts

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,25 @@ import type {
44
ScopeType,
55
TextEditor,
66
} from "@cursorless/common";
7-
import { Range } from "@cursorless/common";
8-
import { LineTarget } from "../../targets";
7+
import { createLineTarget } from "../../targets";
98
import { BaseScopeHandler } from "./BaseScopeHandler";
109
import type { TargetScope } from "./scope.types";
1110

11+
interface LineScopeType {
12+
type: "line" | "fullLine";
13+
}
14+
1215
export class LineScopeHandler extends BaseScopeHandler {
13-
public readonly scopeType = { type: "line" } as const;
1416
public readonly iterationScopeType: ScopeType = {
1517
type: "paragraph",
1618
} as const;
1719
protected readonly isHierarchical = false;
1820
public readonly includeAdjacentInEvery = true;
1921

20-
constructor(_scopeType: ScopeType, _languageId: string) {
22+
constructor(
23+
public readonly scopeType: LineScopeType,
24+
_languageId: string,
25+
) {
2126
super();
2227
}
2328

@@ -26,48 +31,32 @@ export class LineScopeHandler extends BaseScopeHandler {
2631
position: Position,
2732
direction: Direction,
2833
): Iterable<TargetScope> {
34+
const useFullLine = this.scopeType.type === "fullLine";
35+
2936
if (direction === "forward") {
3037
for (let i = position.line; i < editor.document.lineCount; i++) {
31-
yield lineNumberToScope(editor, i);
38+
yield lineNumberToScope(editor, useFullLine, i);
3239
}
3340
} else {
3441
for (let i = position.line; i >= 0; i--) {
35-
yield lineNumberToScope(editor, i);
42+
yield lineNumberToScope(editor, useFullLine, i);
3643
}
3744
}
3845
}
3946
}
4047

4148
function lineNumberToScope(
4249
editor: TextEditor,
50+
useFullLine: boolean,
4351
lineNumber: number,
4452
): TargetScope {
45-
const { range } = editor.document.lineAt(lineNumber);
53+
const line = editor.document.lineAt(lineNumber);
4654

4755
return {
4856
editor,
49-
domain: range,
50-
getTargets: (isReversed) => [createLineTarget(editor, isReversed, range)],
57+
domain: line.range,
58+
getTargets: (isReversed) => [
59+
createLineTarget(editor, isReversed, line, useFullLine),
60+
],
5161
};
5262
}
53-
54-
export function createLineTarget(
55-
editor: TextEditor,
56-
isReversed: boolean,
57-
range: Range,
58-
) {
59-
return new LineTarget({
60-
editor,
61-
isReversed,
62-
contentRange: fitRangeToLineContent(editor, range),
63-
});
64-
}
65-
66-
export function fitRangeToLineContent(editor: TextEditor, range: Range) {
67-
const startLine = editor.document.lineAt(range.start);
68-
const endLine = editor.document.lineAt(range.end);
69-
return new Range(
70-
startLine.rangeTrimmed?.start ?? startLine.range.start,
71-
endLine.rangeTrimmed?.end ?? endLine.range.end,
72-
);
73-
}

packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/ParagraphScopeHandler.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import type {
22
Direction,
33
Position,
4-
Range,
54
ScopeType,
65
TextDocument,
76
TextEditor,
87
TextLine,
98
} from "@cursorless/common";
9+
import { Range } from "@cursorless/common";
1010
import { ParagraphTarget } from "../../targets";
1111
import { BaseScopeHandler } from "./BaseScopeHandler";
12-
import { fitRangeToLineContent } from "./LineScopeHandler";
1312
import type { TargetScope } from "./scope.types";
1413

1514
export class ParagraphScopeHandler extends BaseScopeHandler {
@@ -95,3 +94,12 @@ function createScope(editor: TextEditor, domain: Range): TargetScope {
9594
],
9695
};
9796
}
97+
98+
function fitRangeToLineContent(editor: TextEditor, range: Range) {
99+
const startLine = editor.document.lineAt(range.start);
100+
const endLine = editor.document.lineAt(range.end);
101+
return new Range(
102+
startLine.rangeTrimmed?.start ?? startLine.range.start,
103+
endLine.rangeTrimmed?.end ?? endLine.range.end,
104+
);
105+
}

0 commit comments

Comments
 (0)