33 *-------------------------------------------------------- */
44import type {
55 CodeToTokensBaseOptions ,
6+ Grammar ,
7+ GrammarState ,
68 ShikiInternal ,
79 ThemedToken ,
810 ThemedTokenScopeExplanation ,
@@ -11,15 +13,15 @@ import type {
1113} from '@shikijs/types'
1214import type {
1315 FontStyle ,
14- IGrammar ,
1516 IRawThemeSetting ,
1617 StateStack ,
1718} from '@shikijs/vscode-textmate'
1819
20+ import type { Root } from 'hast'
1921import { ShikiError } from '@shikijs/types'
20- import { EncodedTokenMetadata , INITIAL } from '@shikijs/vscode-textmate'
2122
22- import { getGrammarStack , GrammarState } from '../textmate/grammar-state'
23+ import { EncodedTokenMetadata , INITIAL } from '@shikijs/vscode-textmate'
24+ import { getGrammarStack , getLastGrammarStateFromMap , GrammarState as GrammarStateImpl , setLastGrammarStateToMap } from '../textmate/grammar-state'
2325import { applyColorReplacements , isNoneTheme , isPlainLang , resolveColorReplacements , splitLines } from '../utils'
2426import { tokenizeAnsiWithTheme } from './code-to-tokens-ansi'
2527
@@ -50,19 +52,29 @@ export function codeToTokensBase(
5052 if ( options . grammarState . lang !== _grammar . name ) {
5153 throw new ShikiError ( `Grammar state language "${ options . grammarState . lang } " does not match highlight language "${ _grammar . name } "` )
5254 }
53- if ( options . grammarState . theme !== themeName ) {
54- throw new ShikiError ( `Grammar state theme "${ options . grammarState . theme } " does not match highlight theme "${ themeName } "` )
55+ if ( ! options . grammarState . themes . includes ( theme . name ) ) {
56+ throw new ShikiError ( `Grammar state themes "${ options . grammarState . themes } " do not contain highlight theme "${ theme . name } "` )
5557 }
5658 }
5759
5860 return tokenizeWithTheme ( code , _grammar , theme , colorMap , options )
5961}
6062
63+ export function getLastGrammarState (
64+ internal : ShikiInternal ,
65+ element : ThemedToken [ ] [ ] | Root
66+ ) : GrammarState | undefined
6167export function getLastGrammarState (
6268 internal : ShikiInternal ,
6369 code : string ,
64- options : CodeToTokensBaseOptions = { } ,
65- ) : GrammarState {
70+ options ?: CodeToTokensBaseOptions
71+ ) : GrammarState
72+ export function getLastGrammarState ( ...args : any [ ] ) : GrammarState | undefined {
73+ if ( args . length === 2 ) {
74+ return getLastGrammarStateFromMap ( args [ 1 ] )
75+ }
76+
77+ const [ internal , code , options = { } ] = args as [ ShikiInternal , string , CodeToTokensBaseOptions ]
6678 const {
6779 lang = 'text' ,
6880 theme : themeName = internal . getLoadedThemes ( ) [ 0 ] ,
@@ -77,7 +89,7 @@ export function getLastGrammarState(
7789
7890 const _grammar = internal . getLanguage ( lang )
7991
80- return new GrammarState (
92+ return new GrammarStateImpl (
8193 _tokenizeWithTheme ( code , _grammar , theme , colorMap , options ) . stateStack ,
8294 _grammar . name ,
8395 theme . name ,
@@ -92,17 +104,27 @@ interface ThemeSettingsSelectors {
92104
93105export function tokenizeWithTheme (
94106 code : string ,
95- grammar : IGrammar ,
107+ grammar : Grammar ,
96108 theme : ThemeRegistrationResolved ,
97109 colorMap : string [ ] ,
98110 options : TokenizeWithThemeOptions ,
99111) : ThemedToken [ ] [ ] {
100- return _tokenizeWithTheme ( code , grammar , theme , colorMap , options ) . tokens
112+ const result = _tokenizeWithTheme ( code , grammar , theme , colorMap , options )
113+
114+ const grammarState = new GrammarStateImpl (
115+ _tokenizeWithTheme ( code , grammar , theme , colorMap , options ) . stateStack ,
116+ grammar . name ,
117+ theme . name ,
118+ )
119+
120+ setLastGrammarStateToMap ( result . tokens , grammarState )
121+
122+ return result . tokens
101123}
102124
103125function _tokenizeWithTheme (
104126 code : string ,
105- grammar : IGrammar ,
127+ grammar : Grammar ,
106128 theme : ThemeRegistrationResolved ,
107129 colorMap : string [ ] ,
108130 options : TokenizeWithThemeOptions ,
@@ -120,7 +142,7 @@ function _tokenizeWithTheme(
120142 const lines = splitLines ( code )
121143
122144 let stateStack = options . grammarState
123- ? getGrammarStack ( options . grammarState )
145+ ? getGrammarStack ( options . grammarState , theme . name ) ?? INITIAL
124146 : options . grammarContextCode != null
125147 ? _tokenizeWithTheme (
126148 options . grammarContextCode ,
0 commit comments