@@ -26,6 +26,8 @@ import { findMatchingThemeRule } from 'vs/workbench/services/textMate/common/TMH
2626import { ITextMateService , IGrammar , IToken , StackElement } from 'vs/workbench/services/textMate/common/textMateService' ;
2727import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService' ;
2828import { CancellationTokenSource } from 'vs/base/common/cancellation' ;
29+ import { ColorThemeData , TokenStyleDefinitions , TokenStyleDefinition } from 'vs/workbench/services/themes/common/colorThemeData' ;
30+ import { TokenStylingRule } from 'vs/platform/theme/common/tokenClassificationRegistry' ;
2931
3032class InspectEditorTokensController extends Disposable implements IEditorContribution {
3133
@@ -121,7 +123,8 @@ interface ISemanticTokenInfo {
121123 type : string ;
122124 modifiers : string [ ] ;
123125 range : Range ;
124- metadata : IDecodedMetadata
126+ metadata : IDecodedMetadata ,
127+ definitions : TokenStyleDefinitions
125128}
126129
127130interface IDecodedMetadata {
@@ -248,17 +251,21 @@ class InspectEditorTokensWidget extends Disposable implements IContentWidget {
248251 const semanticTokenInfo = semanticTokens && this . _getSemanticTokenAtPosition ( semanticTokens , position ) ;
249252
250253 let tokenText ;
254+
251255 let metadata : IDecodedMetadata | undefined ;
252- let primary : IDecodedMetadata | undefined ;
253- if ( textMateTokenInfo ) {
256+ let tmFallback : IDecodedMetadata | undefined ;
257+
258+ if ( semanticTokenInfo ) {
259+ tokenText = this . _model . getValueInRange ( semanticTokenInfo . range ) ;
260+ metadata = semanticTokenInfo . metadata ;
261+ if ( textMateTokenInfo ) {
262+ tmFallback = textMateTokenInfo . metadata ;
263+ }
264+ } else if ( textMateTokenInfo ) {
254265 let tokenStartIndex = textMateTokenInfo . token . startIndex ;
255266 let tokenEndIndex = textMateTokenInfo . token . endIndex ;
256267 tokenText = this . _model . getLineContent ( position . lineNumber ) . substring ( tokenStartIndex , tokenEndIndex ) ;
257268 metadata = textMateTokenInfo . metadata ;
258- primary = semanticTokenInfo ?. metadata ;
259- } else if ( semanticTokenInfo ) {
260- tokenText = this . _model . getValueInRange ( semanticTokenInfo . range ) ;
261- metadata = semanticTokenInfo . metadata ;
262269 } else {
263270 return 'No grammar or semantic tokens available.' ;
264271 }
@@ -268,28 +275,36 @@ class InspectEditorTokensWidget extends Disposable implements IContentWidget {
268275 result += `<hr class="tiw-metadata-separator" style="clear:both"/>` ;
269276
270277 result += `<table class="tiw-metadata-table"><tbody>` ;
271- result += `<tr><td class="tiw-metadata-key">language</td><td class="tiw-metadata-value">${ escape ( metadata . languageIdentifier . language ) } </td></tr>` ;
272- result += `<tr><td class="tiw-metadata-key">standard token type</td><td class="tiw-metadata-value">${ this . _tokenTypeToString ( metadata . tokenType ) } </td></tr>` ;
273- if ( semanticTokenInfo ) {
274- result += `<tr><td class="tiw-metadata-key">semantic token type</td><td class="tiw-metadata-value">${ semanticTokenInfo . type } </td></tr>` ;
275- const modifiers = semanticTokenInfo . modifiers . join ( ' ' ) || '-' ;
276- result += `<tr><td class="tiw-metadata-key">semantic token modifiers</td><td class="tiw-metadata-value">${ modifiers } </td></tr>` ;
277- }
278+ result += `<tr><td class="tiw-metadata-key">language</td><td class="tiw-metadata-value">${ escape ( textMateTokenInfo ?. metadata . languageIdentifier . language || '' ) } </td></tr>` ;
279+ result += `<tr><td class="tiw-metadata-key">standard token type</td><td class="tiw-metadata-value">${ this . _tokenTypeToString ( textMateTokenInfo ?. metadata . tokenType || StandardTokenType . Other ) } </td></tr>` ;
278280 result += `</tbody></table>` ;
279281
280282 result += `<hr class="tiw-metadata-separator"/>` ;
281283 result += `<table class="tiw-metadata-table"><tbody>` ;
282- result += this . _formatMetadata ( metadata , primary ) ;
284+ result += this . _formatMetadata ( metadata , tmFallback ) ;
283285 result += `</tbody></table>` ;
284286
287+ if ( semanticTokenInfo ) {
288+ result += `<hr class="tiw-metadata-separator"/>` ;
289+ result += `<table class="tiw-metadata-table"><tbody>` ;
290+ result += `<tr><td class="tiw-metadata-key">semantic token type</td><td class="tiw-metadata-value">${ semanticTokenInfo . type } </td></tr>` ;
291+ const modifiers = semanticTokenInfo . modifiers . join ( ' ' ) || '-' ;
292+ result += `<tr><td class="tiw-metadata-key">semantic token modifiers</td><td class="tiw-metadata-value">${ modifiers } </td></tr>` ;
293+ result += `</tbody></table>` ;
294+
295+ result += `<div>${ this . _renderTokenStyleDefinition ( semanticTokenInfo . definitions . foreground ) } </div>` ;
296+ }
297+
285298 if ( textMateTokenInfo ) {
286299 let theme = this . _themeService . getColorTheme ( ) ;
287300 result += `<hr class="tiw-metadata-separator"/>` ;
288- let matchingRule = findMatchingThemeRule ( theme , textMateTokenInfo . token . scopes , false ) ;
289- if ( matchingRule ) {
290- result += `<code class="tiw-theme-selector">${ matchingRule . rawSelector } \n${ JSON . stringify ( matchingRule . settings , null , '\t' ) } </code>` ;
291- } else {
292- result += `<span class="tiw-theme-selector">No theme selector.</span>` ;
301+ if ( ! semanticTokenInfo ) {
302+ let matchingRule = findMatchingThemeRule ( theme , textMateTokenInfo . token . scopes , false ) ;
303+ if ( matchingRule ) {
304+ result += `<code class="tiw-theme-selector">${ matchingRule . rawSelector } \n${ JSON . stringify ( matchingRule . settings , null , '\t' ) } </code>` ;
305+ } else {
306+ result += `<span class="tiw-theme-selector">No theme selector.</span>` ;
307+ }
293308 }
294309
295310 result += `<ul>` ;
@@ -301,15 +316,20 @@ class InspectEditorTokensWidget extends Disposable implements IContentWidget {
301316 return result ;
302317 }
303318
304- private _formatMetadata ( metadata : IDecodedMetadata , master ?: IDecodedMetadata ) {
319+ private _formatMetadata ( metadata ? : IDecodedMetadata , fallback ?: IDecodedMetadata ) {
305320 let result = '' ;
306321
307- const fontStyle = master ? master . fontStyle : metadata . fontStyle ;
308- result += `<tr><td class="tiw-metadata-key">font style</td><td class="tiw-metadata-value">${ fontStyle } </td></tr>` ;
309- const foreground = master && master . foreground || metadata . foreground ;
310- result += `<tr><td class="tiw-metadata-key">foreground</td><td class="tiw-metadata-value">${ foreground } </td></tr>` ;
311- const background = master && master . background || metadata . background ;
312- result += `<tr><td class="tiw-metadata-key">background</td><td class="tiw-metadata-value">${ background } </td></tr>` ;
322+ function render ( label : string , value : string | undefined , property : keyof IDecodedMetadata ) {
323+ const info = metadata ?. [ property ] !== value ? ` (tm)` : '' ;
324+ return `<tr><td class="tiw-metadata-key">${ label } </td><td class="tiw-metadata-value">${ value + info } </td></tr>` ;
325+ }
326+
327+ const fontStyle = metadata ?. fontStyle || fallback ?. fontStyle ;
328+ result += render ( 'font style' , fontStyle , 'fontStyle' ) ;
329+ const foreground = metadata ?. foreground || fallback ?. foreground ;
330+ result += render ( 'foreground' , foreground , 'foreground' ) ;
331+ const background = metadata ?. background || fallback ?. background ;
332+ result += render ( 'background' , background , 'background' ) ;
313333
314334 if ( foreground && background ) {
315335 const backgroundColor = Color . fromHex ( background ) , foregroundColor = Color . fromHex ( foreground ) ;
@@ -436,15 +456,58 @@ class InspectEditorTokensWidget extends Disposable implements IContentWidget {
436456 const type = semanticTokens . legend . tokenTypes [ typeIdx ] ;
437457 const modifiers = semanticTokens . legend . tokenModifiers . filter ( ( _ , k ) => modSet & 1 << k ) ;
438458 const range = new Range ( line + 1 , character + 1 , line + 1 , character + 1 + len ) ;
439- const metadata = this . _decodeMetadata ( this . _themeService . getTheme ( ) . getTokenStyleMetadata ( type , modifiers ) || 0 ) ;
440- return { type, modifiers, range, metadata } ;
459+ const definitions = { } ;
460+ const theme = this . _themeService . getTheme ( ) as ColorThemeData ;
461+ const m = theme . getTokenStyleMetadata ( type , modifiers , true , definitions ) ;
462+ const metadata = this . _decodeMetadata ( m || 0 ) ;
463+ return { type, modifiers, range, metadata, definitions } ;
441464 }
442465 lastLine = line ;
443466 lastCharacter = character ;
444467 }
445468 return null ;
446469 }
447470
471+ private _renderTokenStyleDefinition ( definition : TokenStyleDefinition | undefined ) : string {
472+ if ( definition === undefined ) {
473+ return '' ;
474+ }
475+ const theme = this . _themeService . getTheme ( ) as ColorThemeData ;
476+
477+ const isTokenStylingRule = ( d : any ) : d is TokenStylingRule => ! ! d . value ;
478+ if ( Array . isArray ( definition ) ) {
479+ let result = '' ;
480+ result += `<ul>` ;
481+ for ( const d of definition ) {
482+ result += `<li>${ escape ( d . join ( ' ' ) ) } </li>` ;
483+ }
484+ result += `</ul>` ;
485+
486+ for ( const d of definition ) {
487+ let matchingRule = findMatchingThemeRule ( theme , d , false ) ;
488+ if ( matchingRule ) {
489+ result += `<code class="tiw-theme-selector">${ matchingRule . rawSelector } \n${ JSON . stringify ( matchingRule . settings , null , '\t' ) } </code>` ;
490+ break ;
491+ }
492+ }
493+ return result ;
494+ } else if ( isTokenStylingRule ( definition ) ) {
495+
496+ const scope = theme . getTokenStylingRuleScope ( definition ) ;
497+
498+ if ( scope === 'setting' ) {
499+ return `User settings: ${ definition . selector } ` ;
500+ } else if ( scope === 'theme' ) {
501+ return `Color theme: ${ definition . selector } ` ;
502+ }
503+ return '' ;
504+ } else if ( typeof definition === 'string' ) {
505+ return `Selector: ${ definition } ` ;
506+ } else {
507+ return `Token style: Foreground: ${ definition . foreground } , bold: ${ definition . bold } , italic: ${ definition . italic } , underline: ${ definition . underline } ,` ;
508+ }
509+ }
510+
448511 public getDomNode ( ) : HTMLElement {
449512 return this . _domNode ;
450513 }
0 commit comments