Skip to content

Commit 514ec62

Browse files
committed
add SelectionRange and SelectionRangeKind, microsoft#63935
1 parent f5f4ad9 commit 514ec62

17 files changed

Lines changed: 146 additions & 54 deletions

src/vs/editor/common/modes.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,11 +1025,16 @@ export interface DocumentColorProvider {
10251025
provideColorPresentations(model: model.ITextModel, colorInfo: IColorInformation, token: CancellationToken): ProviderResult<IColorPresentation[]>;
10261026
}
10271027

1028+
export interface SelectionRange {
1029+
kind: string;
1030+
range: IRange;
1031+
}
1032+
10281033
export interface SelectionRangeProvider {
10291034
/**
10301035
* Provide ranges that should be selected from the given position.
10311036
*/
1032-
provideSelectionRanges(model: model.ITextModel, position: Position, token: CancellationToken): ProviderResult<IRange[]>;
1037+
provideSelectionRanges(model: model.ITextModel, position: Position, token: CancellationToken): ProviderResult<SelectionRange[]>;
10331038
}
10341039

10351040
export interface FoldingContext {

src/vs/editor/contrib/smartSelect/bracketSelections.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { SelectionRangeProvider } from 'vs/editor/common/modes';
6+
import { SelectionRangeProvider, SelectionRange } from 'vs/editor/common/modes';
77
import { ITextModel } from 'vs/editor/common/model';
88
import { Position } from 'vs/editor/common/core/position';
99
import { Range } from 'vs/editor/common/core/range';
1010
import { LinkedList } from 'vs/base/common/linkedList';
1111

1212
export class BracketSelectionRangeProvider implements SelectionRangeProvider {
1313

14-
provideSelectionRanges(model: ITextModel, position: Position): Promise<Range[]> {
15-
const bucket: Range[] = [];
14+
provideSelectionRanges(model: ITextModel, position: Position): Promise<SelectionRange[]> {
15+
const bucket: SelectionRange[] = [];
1616
const ranges = new Map<string, LinkedList<Range>>();
1717
return new Promise(resolve => BracketSelectionRangeProvider._bracketsRightYield(resolve, 0, model, position, ranges))
1818
.then(() => new Promise(resolve => BracketSelectionRangeProvider._bracketsLeftYield(resolve, 0, model, position, ranges, bucket)))
@@ -67,7 +67,7 @@ export class BracketSelectionRangeProvider implements SelectionRangeProvider {
6767
}
6868
}
6969

70-
private static _bracketsLeftYield(resolve: () => void, round: number, model: ITextModel, pos: Position, ranges: Map<string, LinkedList<Range>>, bucket: Range[]): void {
70+
private static _bracketsLeftYield(resolve: () => void, round: number, model: ITextModel, pos: Position, ranges: Map<string, LinkedList<Range>>, bucket: SelectionRange[]): void {
7171
const counts = new Map<string, number>();
7272
const t1 = Date.now();
7373
while (true) {
@@ -108,8 +108,8 @@ export class BracketSelectionRangeProvider implements SelectionRangeProvider {
108108
}
109109
const innerBracket = Range.fromPositions(bracket.range.getEndPosition(), closing!.getStartPosition());
110110
const outerBracket = Range.fromPositions(bracket.range.getStartPosition(), closing!.getEndPosition());
111-
bucket.push(innerBracket);
112-
bucket.push(outerBracket);
111+
bucket.push({ range: innerBracket, kind: 'block.bracket' });
112+
bucket.push({ range: outerBracket, kind: 'block.bracket' });
113113
BracketSelectionRangeProvider._addBracketLeading(model, outerBracket, bucket);
114114
}
115115
}
@@ -118,7 +118,7 @@ export class BracketSelectionRangeProvider implements SelectionRangeProvider {
118118
}
119119
}
120120

121-
private static _addBracketLeading(model: ITextModel, bracket: Range, bucket: Range[]): void {
121+
private static _addBracketLeading(model: ITextModel, bracket: Range, bucket: SelectionRange[]): void {
122122
if (bracket.startLineNumber === bracket.endLineNumber) {
123123
return;
124124
}
@@ -128,8 +128,8 @@ export class BracketSelectionRangeProvider implements SelectionRangeProvider {
128128
const startLine = bracket.startLineNumber;
129129
const column = model.getLineFirstNonWhitespaceColumn(startLine);
130130
if (column !== 0 && column !== bracket.startColumn) {
131-
bucket.push(Range.fromPositions(new Position(startLine, column), bracket.getEndPosition()));
132-
bucket.push(Range.fromPositions(new Position(startLine, 1), bracket.getEndPosition()));
131+
bucket.push({ range: Range.fromPositions(new Position(startLine, column), bracket.getEndPosition()), kind: 'block.bracket.leading' });
132+
bucket.push({ range: Range.fromPositions(new Position(startLine, 1), bracket.getEndPosition()), kind: 'block.bracket.leading' });
133133
}
134134

135135
// xxxxxxxx
@@ -140,8 +140,8 @@ export class BracketSelectionRangeProvider implements SelectionRangeProvider {
140140
if (aboveLine > 0) {
141141
const column = model.getLineFirstNonWhitespaceColumn(aboveLine);
142142
if (column === bracket.startColumn && column !== model.getLineLastNonWhitespaceColumn(aboveLine)) {
143-
bucket.push(Range.fromPositions(new Position(aboveLine, column), bracket.getEndPosition()));
144-
bucket.push(Range.fromPositions(new Position(aboveLine, 1), bracket.getEndPosition()));
143+
bucket.push({ range: Range.fromPositions(new Position(aboveLine, column), bracket.getEndPosition()), kind: 'block.bracket.leading' });
144+
bucket.push({ range: Range.fromPositions(new Position(aboveLine, 1), bracket.getEndPosition()), kind: 'block.bracket.leading' });
145145
}
146146
}
147147
}

src/vs/editor/contrib/smartSelect/smartSelect.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,11 @@ export function provideSelectionRanges(model: ITextModel, position: Position, to
221221
for (const group of provider) {
222222
rank += 1;
223223
for (const prov of group) {
224-
work.push(Promise.resolve(prov.provideSelectionRanges(model, position, token)).then(res => {
225-
if (arrays.isNonEmptyArray(res)) {
226-
for (const range of res) {
227-
if (Range.isIRange(range) && Range.containsPosition(range, position)) {
228-
ranges.push({ range: Range.lift(range), rank });
224+
work.push(Promise.resolve(prov.provideSelectionRanges(model, position, token)).then(selectionRanges => {
225+
if (arrays.isNonEmptyArray(selectionRanges)) {
226+
for (const sel of selectionRanges) {
227+
if (Range.isIRange(sel.range) && Range.containsPosition(sel.range, position)) {
228+
ranges.push({ range: Range.lift(sel.range), rank });
229229
}
230230
}
231231
}

src/vs/editor/contrib/smartSelect/test/tokenSelectionSupport.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ suite('SmartSelect', () => {
8181
let actual = new TokenTreeSelectionRangeProvider().provideSelectionRanges(model, new Position(lineNumber, column));
8282

8383

84-
let actualStr = actual.map(r => new Range(r.startLineNumber, r.startColumn, r.endLineNumber, r.endColumn).toString());
84+
let actualStr = actual.map(r => new Range(r.range.startLineNumber, r.range.startColumn, r.range.endLineNumber, r.range.endColumn).toString());
8585
let desiredStr = ranges.reverse().map(r => String(r));
8686

8787
assert.deepEqual(actualStr, desiredStr);
@@ -199,7 +199,7 @@ suite('SmartSelect', () => {
199199
assert.equal(expected.length, ranges.length);
200200
for (const range of ranges) {
201201
let exp = expected.shift() || null;
202-
assert.ok(Range.equalsRange(range, exp), `A=${range} <> E=${exp}`);
202+
assert.ok(Range.equalsRange(range.range, exp), `A=${range} <> E=${exp}`);
203203
}
204204
}
205205

src/vs/editor/contrib/smartSelect/tokenTree.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ import { LineTokens } from 'vs/editor/common/core/lineTokens';
1010
import { ignoreBracketsInToken } from 'vs/editor/common/modes/supports';
1111
import { BracketsUtils, RichEditBrackets } from 'vs/editor/common/modes/supports/richEditBrackets';
1212
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
13-
import { LanguageId, StandardTokenType, SelectionRangeProvider } from 'vs/editor/common/modes';
13+
import { LanguageId, StandardTokenType, SelectionRangeProvider, SelectionRange } from 'vs/editor/common/modes';
1414

1515
export class TokenTreeSelectionRangeProvider implements SelectionRangeProvider {
1616

17-
provideSelectionRanges(model: ITextModel, position: Position): Range[] {
17+
provideSelectionRanges(model: ITextModel, position: Position): SelectionRange[] {
1818
let tree = new TokenTreeBuilder(model).build();
1919
let node = find(tree, position);
2020
let ranges: Range[] = [];
@@ -26,7 +26,7 @@ export class TokenTreeSelectionRangeProvider implements SelectionRangeProvider {
2626
lastRange = node.range;
2727
node = node.parent;
2828
}
29-
return ranges;
29+
return ranges.map(range => ({ range, kind: '' }));
3030
}
3131
}
3232

src/vs/editor/contrib/smartSelect/wordSelections.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,29 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { SelectionRangeProvider, StandardTokenType } from 'vs/editor/common/modes';
6+
import { SelectionRangeProvider, StandardTokenType, SelectionRange } from 'vs/editor/common/modes';
77
import { ITextModel } from 'vs/editor/common/model';
88
import { Position } from 'vs/editor/common/core/position';
99
import { Range } from 'vs/editor/common/core/range';
1010

1111
export class WordSelectionRangeProvider implements SelectionRangeProvider {
1212

13-
provideSelectionRanges(model: ITextModel, position: Position): Range[] {
14-
let result: Range[] = [];
13+
provideSelectionRanges(model: ITextModel, position: Position): SelectionRange[] {
14+
let result: SelectionRange[] = [];
1515
this._addWordRanges(result, model, position);
1616
this._addTokenRange(result, model, position);
1717
this._addLineRanges(result, model, position);
1818
return result;
1919
}
2020

21-
private _addWordRanges(bucket: Range[], model: ITextModel, pos: Position): void {
21+
private _addWordRanges(bucket: SelectionRange[], model: ITextModel, pos: Position): void {
2222
const word = model.getWordAtPosition(pos);
2323
if (word) {
24-
bucket.push(new Range(pos.lineNumber, word.startColumn, pos.lineNumber, word.endColumn));
24+
bucket.push({ range: new Range(pos.lineNumber, word.startColumn, pos.lineNumber, word.endColumn), kind: 'simple.word' });
2525
}
2626
}
2727

28-
private _addTokenRange(bucket: Range[], model: ITextModel, pos: Position): void {
28+
private _addTokenRange(bucket: SelectionRange[], model: ITextModel, pos: Position): void {
2929
const tokens = model.getLineTokens(pos.lineNumber);
3030
const index = tokens.findTokenIndexAtOffset(pos.column - 1);
3131
const type = tokens.getStandardTokenType(index);
@@ -98,15 +98,15 @@ export class WordSelectionRangeProvider implements SelectionRangeProvider {
9898

9999
if (type === StandardTokenType.String) {
100100
// just assume that quotation marks are length=1
101-
bucket.push(Range.fromPositions(left.delta(0, 1), right.delta(0, -1)));
102-
bucket.push(Range.fromPositions(left, right));
101+
bucket.push({ range: Range.fromPositions(left.delta(0, 1), right.delta(0, -1)), kind: 'simple.string' });
102+
bucket.push({ range: Range.fromPositions(left, right), kind: 'simple.string' });
103103
} else {
104-
bucket.push(Range.fromPositions(left, right));
104+
bucket.push({ range: Range.fromPositions(left, right), kind: 'simple.comment' });
105105
}
106106
}
107107

108-
private _addLineRanges(bucket: Range[], model: ITextModel, pos: Position): void {
109-
bucket.push(new Range(pos.lineNumber, model.getLineFirstNonWhitespaceColumn(pos.lineNumber), pos.lineNumber, model.getLineLastNonWhitespaceColumn(pos.lineNumber)));
110-
bucket.push(new Range(pos.lineNumber, model.getLineMinColumn(pos.lineNumber), pos.lineNumber, model.getLineMaxColumn(pos.lineNumber)));
108+
private _addLineRanges(bucket: SelectionRange[], model: ITextModel, pos: Position): void {
109+
bucket.push({ range: new Range(pos.lineNumber, model.getLineFirstNonWhitespaceColumn(pos.lineNumber), pos.lineNumber, model.getLineLastNonWhitespaceColumn(pos.lineNumber)), kind: 'simple.line' });
110+
bucket.push({ range: new Range(pos.lineNumber, model.getLineMinColumn(pos.lineNumber), pos.lineNumber, model.getLineMaxColumn(pos.lineNumber)), kind: 'simple.line' });
111111
}
112112
}

src/vs/editor/contrib/suggest/wordDistance.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export abstract class WordDistance {
3838
if (!ranges || ranges.length === 0) {
3939
return WordDistance.None;
4040
}
41-
return service.computeWordRanges(model.uri, ranges[0]).then(wordRanges => {
41+
return service.computeWordRanges(model.uri, ranges[0].range).then(wordRanges => {
4242
return new class extends WordDistance {
4343
distance(anchor: IPosition, suggestion: CompletionItem) {
4444
if (!wordRanges || !position.equals(editor.getPosition())) {
@@ -56,7 +56,7 @@ export abstract class WordDistance {
5656
let bestWordRange = idx >= 0 ? wordLines[idx] : wordLines[Math.max(0, ~idx - 1)];
5757
let blockDistance = ranges.length;
5858
for (const range of ranges) {
59-
if (!Range.containsRange(range, bestWordRange)) {
59+
if (!Range.containsRange(range.range, bestWordRange)) {
6060
break;
6161
}
6262
blockDistance -= 1;

src/vs/monaco.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5277,11 +5277,16 @@ declare namespace monaco.languages {
52775277
provideColorPresentations(model: editor.ITextModel, colorInfo: IColorInformation, token: CancellationToken): ProviderResult<IColorPresentation[]>;
52785278
}
52795279

5280+
export interface SelectionRange {
5281+
kind: string;
5282+
range: IRange;
5283+
}
5284+
52805285
export interface SelectionRangeProvider {
52815286
/**
52825287
* Provide ranges that should be selected from the given position.
52835288
*/
5284-
provideSelectionRanges(model: editor.ITextModel, position: Position, token: CancellationToken): ProviderResult<IRange[]>;
5289+
provideSelectionRanges(model: editor.ITextModel, position: Position, token: CancellationToken): ProviderResult<SelectionRange[]>;
52855290
}
52865291

52875292
export interface FoldingContext {

src/vs/vscode.proposed.d.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,26 @@ declare module 'vscode' {
1818

1919
//#region Joh - selection range provider
2020

21+
export class SelectionRangeKind {
22+
23+
static readonly Empty: SelectionRangeKind;
24+
static readonly Statement: SelectionRangeKind;
25+
static readonly Expression: SelectionRangeKind;
26+
static readonly Block: SelectionRangeKind;
27+
28+
readonly value: string;
29+
30+
private constructor(value: string);
31+
32+
append(value: string): SelectionRangeKind;
33+
}
34+
35+
export class SelectionRange {
36+
kind: SelectionRangeKind;
37+
range: Range;
38+
constructor(kind: SelectionRangeKind, range: Range);
39+
}
40+
2141
export interface SelectionRangeProvider {
2242
/**
2343
* Provide selection ranges starting at a given position. The first range must [contain](#Range.contains)
@@ -26,7 +46,7 @@ declare module 'vscode' {
2646
* @param position
2747
* @param token
2848
*/
29-
provideSelectionRanges(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Range[]>;
49+
provideSelectionRanges(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<SelectionRange[]>;
3050
}
3151

3252
export namespace languages {

src/vs/workbench/api/node/extHost.api.impl.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,8 @@ export function createApiFactory(
784784
Range: extHostTypes.Range,
785785
RelativePattern: extHostTypes.RelativePattern,
786786
Selection: extHostTypes.Selection,
787+
SelectionRange: extHostTypes.SelectionRange,
788+
SelectionRangeKind: extHostTypes.SelectionRangeKind,
787789
ShellExecution: extHostTypes.ShellExecution,
788790
ShellQuoting: extHostTypes.ShellQuoting,
789791
SignatureHelpTriggerKind: extHostTypes.SignatureHelpTriggerKind,

0 commit comments

Comments
 (0)