Skip to content

Commit 7ab052a

Browse files
committed
first cut of token_at_position api, microsoft#91555
1 parent a267564 commit 7ab052a

7 files changed

Lines changed: 91 additions & 1 deletion

File tree

src/vs/vscode.proposed.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,4 +2203,24 @@ declare module 'vscode' {
22032203

22042204
//#endregion
22052205

2206+
2207+
//#region https://github.com/microsoft/vscode/issues/91555
2208+
2209+
export enum StandardTokenType {
2210+
Other = 0,
2211+
Comment = 1,
2212+
String = 2,
2213+
RegEx = 4
2214+
}
2215+
2216+
export interface TokenInformation {
2217+
type: StandardTokenType;
2218+
range: Range;
2219+
}
2220+
2221+
export namespace languages {
2222+
export function getTokenInformationAtPosition(document: TextDocument, position: Position): Promise<TokenInformation>;
2223+
}
2224+
2225+
//#endregion
22062226
}

src/vs/workbench/api/browser/mainThreadLanguages.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import { IModeService } from 'vs/editor/common/services/modeService';
88
import { IModelService } from 'vs/editor/common/services/modelService';
99
import { MainThreadLanguagesShape, MainContext, IExtHostContext } from '../common/extHost.protocol';
1010
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
11+
import { IPosition } from 'vs/editor/common/core/position';
12+
import { IRange, Range } from 'vs/editor/common/core/range';
13+
import { StandardTokenType } from 'vs/editor/common/modes';
1114

1215
@extHostNamedCustomer(MainContext.MainThreadLanguages)
1316
export class MainThreadLanguages implements MainThreadLanguagesShape {
@@ -40,4 +43,19 @@ export class MainThreadLanguages implements MainThreadLanguagesShape {
4043
this._modelService.setMode(model, this._modeService.create(languageId));
4144
return Promise.resolve(undefined);
4245
}
46+
47+
async $tokensAtPosition(resource: UriComponents, position: IPosition): Promise<undefined | { type: StandardTokenType, range: IRange }> {
48+
const uri = URI.revive(resource);
49+
const model = this._modelService.getModel(uri);
50+
if (!model) {
51+
return undefined;
52+
}
53+
model.tokenizeIfCheap(position.lineNumber);
54+
const tokens = model.getLineTokens(position.lineNumber);
55+
const idx = tokens.findTokenIndexAtOffset(position.column - 1);
56+
return {
57+
type: tokens.getStandardTokenType(idx),
58+
range: new Range(position.lineNumber, 1 + tokens.getStartOffset(idx), position.lineNumber, 1 + tokens.getEndOffset(idx))
59+
};
60+
}
4361
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
431431
},
432432
setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => {
433433
return extHostLanguageFeatures.setLanguageConfiguration(extension, language, configuration);
434+
},
435+
getTokenInformationAtPosition(doc: vscode.TextDocument, pos: vscode.Position) {
436+
checkProposedApiEnabled(extension);
437+
return extHostLanguages.tokenAtPosition(doc, pos);
434438
}
435439
};
436440

@@ -1040,6 +1044,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
10401044
SnippetString: extHostTypes.SnippetString,
10411045
SourceBreakpoint: extHostTypes.SourceBreakpoint,
10421046
SourceControlInputBoxValidationType: extHostTypes.SourceControlInputBoxValidationType,
1047+
StandardTokenType: extHostTypes.StandardTokenType,
10431048
StatusBarAlignment: extHostTypes.StatusBarAlignment,
10441049
SymbolInformation: extHostTypes.SymbolInformation,
10451050
SymbolKind: extHostTypes.SymbolKind,

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
393393
export interface MainThreadLanguagesShape extends IDisposable {
394394
$getLanguages(): Promise<string[]>;
395395
$changeLanguage(resource: UriComponents, languageId: string): Promise<void>;
396+
$tokensAtPosition(resource: UriComponents, position: IPosition): Promise<undefined | { type: modes.StandardTokenType, range: IRange }>;
396397
}
397398

398399
export interface MainThreadMessageOptions {

src/vs/workbench/api/common/extHostLanguages.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import { MainContext, MainThreadLanguagesShape, IMainContext } from './extHost.protocol';
77
import type * as vscode from 'vscode';
88
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
9+
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
10+
import { StandardTokenType, Range, Position } from 'vs/workbench/api/common/extHostTypes';
911

1012
export class ExtHostLanguages {
1113

@@ -32,4 +34,31 @@ export class ExtHostLanguages {
3234
}
3335
return data.document;
3436
}
37+
38+
async tokenAtPosition(document: vscode.TextDocument, position: vscode.Position): Promise<vscode.TokenInformation> {
39+
const versionNow = document.version;
40+
const pos = typeConvert.Position.from(position);
41+
const info = await this._proxy.$tokensAtPosition(document.uri, pos);
42+
const defaultRange = {
43+
type: StandardTokenType.Other,
44+
range: document.getWordRangeAtPosition(position) ?? new Range(position.line, position.character, position.line, position.character)
45+
};
46+
if (!info) {
47+
// no result
48+
return defaultRange;
49+
}
50+
const result = {
51+
range: typeConvert.Range.to(info.range),
52+
type: typeConvert.TokenType.to(info.type)
53+
};
54+
if (!result.range.contains(<Position>position)) {
55+
// bogous result
56+
return defaultRange;
57+
}
58+
if (versionNow !== document.version) {
59+
// concurrent change
60+
return defaultRange;
61+
}
62+
return result;
63+
}
3564
}

src/vs/workbench/api/common/extHostTypeConverters.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,22 @@ export namespace Range {
9595
}
9696
}
9797

98+
export namespace TokenType {
99+
export function to(type: modes.StandardTokenType): types.StandardTokenType {
100+
switch (type) {
101+
case modes.StandardTokenType.Comment: return types.StandardTokenType.Comment;
102+
case modes.StandardTokenType.Other: return types.StandardTokenType.Other;
103+
case modes.StandardTokenType.RegEx: return types.StandardTokenType.RegEx;
104+
case modes.StandardTokenType.String: return types.StandardTokenType.String;
105+
}
106+
}
107+
}
108+
98109
export namespace Position {
99110
export function to(position: IPosition): types.Position {
100111
return new types.Position(position.lineNumber - 1, position.column - 1);
101112
}
102-
export function from(position: types.Position): IPosition {
113+
export function from(position: types.Position | vscode.Position): IPosition {
103114
return { lineNumber: position.line + 1, column: position.character + 1 };
104115
}
105116
}

src/vs/workbench/api/common/extHostTypes.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2774,3 +2774,9 @@ export class AuthenticationSession implements vscode.AuthenticationSession2 {
27742774
}
27752775

27762776
//#endregion Authentication
2777+
export enum StandardTokenType {
2778+
Other = 0,
2779+
Comment = 1,
2780+
String = 2,
2781+
RegEx = 4
2782+
}

0 commit comments

Comments
 (0)