diff --git a/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts b/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts index 8feeb14711d..eb036defdbe 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts @@ -14,6 +14,7 @@ import { escape } from 'vs/base/common/strings'; import { ContentWidgetPositionPreference, IActiveCodeEditor, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser'; import { EditorAction, ServicesAccessor, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { Position } from 'vs/editor/common/core/position'; +import { Range } from 'vs/editor/common/core/range'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { FontStyle, LanguageIdentifier, StandardTokenType, TokenMetadata, DocumentSemanticTokensProviderRegistry, SemanticTokensLegend, SemanticTokens } from 'vs/editor/common/modes'; @@ -111,11 +112,16 @@ class InspectEditorTokens extends EditorAction { } } -interface ICompleteLineTokenization { - startState: StackElement | null; - tokens1: IToken[]; - tokens2: Uint32Array; - endState: StackElement; +interface ITextMateTokenInfo { + token: IToken; + metadata: IDecodedMetadata; +} + +interface ISemanticTokenInfo { + type: string; + modifiers: string[]; + range: Range; + metadata: IDecodedMetadata } interface IDecodedMetadata { @@ -221,10 +227,12 @@ class InspectEditorTokensWidget extends Disposable implements IContentWidget { this._domNode.appendChild(document.createTextNode(nls.localize('inspectTMScopesWidget.loading', "Loading..."))); Promise.all([this._grammar, this._semanticTokens]).then(([grammar, semanticTokens]) => { - if (!grammar) { - throw new Error(`Could not find grammar for language!`); + if (this._isDisposed) { + return; } - this._compute(grammar, semanticTokens, position); + let text = this._compute(grammar, semanticTokens, position); + this._domNode.innerHTML = text; + this._editor.layoutContentWidget(this); }, (err) => { this._notificationService.warn(err); @@ -235,85 +243,62 @@ class InspectEditorTokensWidget extends Disposable implements IContentWidget { } - private _compute(grammar: IGrammar, semanticTokens: SemanticTokensResult | null, position: Position): void { - if (this._isDisposed) { - return; - } - let data = this._getTokensAtLine(grammar, position.lineNumber); + private _compute(grammar: IGrammar | null, semanticTokens: SemanticTokensResult | null, position: Position): string { + const textMateTokenInfo = grammar && this._getTokensAtPosition(grammar, position); + const semanticTokenInfo = semanticTokens && this._getSemanticTokenAtPosition(semanticTokens, position); - let token1Index = 0; - for (let i = data.tokens1.length - 1; i >= 0; i--) { - let t = data.tokens1[i]; - if (position.column - 1 >= t.startIndex) { - token1Index = i; - break; - } + let tokenText; + let metadata: IDecodedMetadata | undefined; + let primary: IDecodedMetadata | undefined; + if (textMateTokenInfo) { + let tokenStartIndex = textMateTokenInfo.token.startIndex; + let tokenEndIndex = textMateTokenInfo.token.endIndex; + tokenText = this._model.getLineContent(position.lineNumber).substring(tokenStartIndex, tokenEndIndex); + metadata = textMateTokenInfo.metadata; + primary = semanticTokenInfo?.metadata; + } else if (semanticTokenInfo) { + tokenText = this._model.getValueInRange(semanticTokenInfo.range); + metadata = semanticTokenInfo.metadata; + } else { + return 'No grammar or semantic tokens available.'; } - let token2Index = 0; - for (let i = (data.tokens2.length >>> 1); i >= 0; i--) { - if (position.column - 1 >= data.tokens2[(i << 1)]) { - token2Index = i; - break; - } - } - - let semanticMetadata: IDecodedMetadata | undefined = undefined; - let semanticClasssification; - if (semanticTokens) { - semanticClasssification = this._getSemanticTokenAtPosition(semanticTokens, position); - if (semanticClasssification) { - const metadata = this._themeService.getTheme().getTokenStyleMetadata(semanticClasssification.type, semanticClasssification.modifiers); - if (metadata) { - semanticMetadata = this._decodeMetadata(metadata); - } - } - } - - let result = ''; - - let tokenStartIndex = data.tokens1[token1Index].startIndex; - let tokenEndIndex = data.tokens1[token1Index].endIndex; - let tokenText = this._model.getLineContent(position.lineNumber).substring(tokenStartIndex, tokenEndIndex); result += `
| language | ${escape(metadata.languageIdentifier.language)} |
| standard token type | ${this._tokenTypeToString(metadata.tokenType)} |
| semantic token type | ${semanticClasssification.type} |
| semantic token type | ${semanticTokenInfo.type} |
| semantic token modifiers | ${modifiers} |
${matchingRule.rawSelector}\n${JSON.stringify(matchingRule.settings, null, '\t')}`;
- } else {
- result += `No theme selector.`;
- }
+ if (textMateTokenInfo) {
+ let theme = this._themeService.getColorTheme();
+ result += `${matchingRule.rawSelector}\n${JSON.stringify(matchingRule.settings, null, '\t')}`;
+ } else {
+ result += `No theme selector.`;
+ }
- result += `