Skip to content

Commit efbb7fb

Browse files
authored
feat(core): lighter token explanation with scopeName (#739)
1 parent 933415c commit efbb7fb

File tree

4 files changed

+698
-28
lines changed

4 files changed

+698
-28
lines changed

packages/core/src/code-to-tokens-base.ts

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -125,28 +125,6 @@ function _tokenizeWithTheme(
125125
let actual: ThemedToken[] = []
126126
const final: ThemedToken[][] = []
127127

128-
const themeSettingsSelectors: ThemeSettingsSelectors[] = []
129-
if (options.includeExplanation) {
130-
for (const setting of theme.settings) {
131-
let selectors: string[]
132-
switch (typeof setting.scope) {
133-
case 'string':
134-
selectors = setting.scope.split(/,/).map(scope => scope.trim())
135-
break
136-
case 'object':
137-
selectors = setting.scope
138-
break
139-
default:
140-
continue
141-
}
142-
143-
themeSettingsSelectors.push({
144-
settings: setting,
145-
selectors: selectors.map(selector => selector.split(/ /)),
146-
})
147-
}
148-
}
149-
150128
for (let i = 0, len = lines.length; i < len; i++) {
151129
const [line, lineOffset] = lines[i]
152130
if (line === '') {
@@ -201,6 +179,29 @@ function _tokenizeWithTheme(
201179
}
202180

203181
if (options.includeExplanation) {
182+
const themeSettingsSelectors: ThemeSettingsSelectors[] = []
183+
184+
if (options.includeExplanation !== 'scopeName') {
185+
for (const setting of theme.settings) {
186+
let selectors: string[]
187+
switch (typeof setting.scope) {
188+
case 'string':
189+
selectors = setting.scope.split(/,/).map(scope => scope.trim())
190+
break
191+
case 'object':
192+
selectors = setting.scope
193+
break
194+
default:
195+
continue
196+
}
197+
198+
themeSettingsSelectors.push({
199+
settings: setting,
200+
selectors: selectors.map(selector => selector.split(/ /)),
201+
})
202+
}
203+
}
204+
204205
token.explanation = []
205206
let offset = 0
206207
while (startIndex + offset < nextStartIndex) {
@@ -213,7 +214,14 @@ function _tokenizeWithTheme(
213214
offset += tokenWithScopesText.length
214215
token.explanation.push({
215216
content: tokenWithScopesText,
216-
scopes: explainThemeScopes(themeSettingsSelectors, tokenWithScopes.scopes),
217+
scopes: options.includeExplanation === 'scopeName'
218+
? explainThemeScopesNameOnly(
219+
tokenWithScopes.scopes,
220+
)
221+
: explainThemeScopesFull(
222+
themeSettingsSelectors,
223+
tokenWithScopes.scopes,
224+
),
217225
})
218226

219227
tokensWithScopesIndex! += 1
@@ -233,17 +241,22 @@ function _tokenizeWithTheme(
233241
}
234242
}
235243

236-
function explainThemeScopes(
244+
function explainThemeScopesNameOnly(
245+
scopes: string[],
246+
): ThemedTokenScopeExplanation[] {
247+
return scopes.map(scope => ({ scopeName: scope }))
248+
}
249+
250+
function explainThemeScopesFull(
237251
themeSelectors: ThemeSettingsSelectors[],
238252
scopes: string[],
239253
): ThemedTokenScopeExplanation[] {
240254
const result: ThemedTokenScopeExplanation[] = []
241255
for (let i = 0, len = scopes.length; i < len; i++) {
242-
const parentScopes = scopes.slice(0, i)
243256
const scope = scopes[i]
244257
result[i] = {
245258
scopeName: scope,
246-
themeMatches: explainThemeScope(themeSelectors, scope, parentScopes),
259+
themeMatches: explainThemeScope(themeSelectors, scope, scopes.slice(0, i)),
247260
}
248261
}
249262
return result

packages/core/src/types/tokens.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { GrammarState } from '../grammar-state'
2+
import type { IRawThemeSetting } from '../textmate'
23
import type { SpecialLanguage } from './langs'
34
import type { SpecialTheme, ThemeRegistrationAny } from './themes'
45
import type { CodeOptionsThemes } from './options'
@@ -36,7 +37,7 @@ export interface CodeToTokensWithThemesOptions<Languages = string, Themes = stri
3637

3738
export interface ThemedTokenScopeExplanation {
3839
scopeName: string
39-
themeMatches: any[]
40+
themeMatches?: IRawThemeSetting[]
4041
}
4142

4243
export interface ThemedTokenExplanation {
@@ -149,9 +150,12 @@ export interface TokenizeWithThemeOptions {
149150
/**
150151
* Include explanation of why a token is given a color.
151152
*
153+
* You can optionally pass `scopeName` to only include explanation for scopes,
154+
* which is more performant than full explanation.
155+
*
152156
* @default false
153157
*/
154-
includeExplanation?: boolean
158+
includeExplanation?: boolean | 'scopeName'
155159

156160
/**
157161
* A map of color names to new color values.

0 commit comments

Comments
 (0)