fix(markdown): highlight YAML frontmatter in the source editor

The markdown grammar's frontMatter rule embeds source.yaml at the start
of the document, but Orca loaded YAML only when a ```yaml fence label
was seen, so frontmatter stayed plain text. Load the YAML grammar
together with markdown.

Fixes #41658

Co-authored-by: Garrett Peppers <garrett@pepperstech.net>
This commit is contained in:
Jinjing
2026-11-13 14:50:41 -08:00
co-authored by Garrett Peppers
parent 01cddfb50f
commit ae522dfee4
2 changed files with 33 additions and 2 deletions
@@ -0,0 +1,28 @@
import { describe, expect, it, vi } from 'vitest'
import { loadNodeOniguruma } from '../syntax-highlighting/oniguruma-test-harness'
import { createMarkdownTokensProvider } from './markdown-textmate-tokens'
vi.mock('../syntax-highlighting/oniguruma', () => ({ loadOniguruma: loadNodeOniguruma }))
describe('markdown tokenization', () => {
it('colors frontmatter as YAML on first paint, then returns to markdown', async () => {
const provider = await createMarkdownTokensProvider({
editor: { defineTheme: vi.fn() },
languages: { setTokensProvider: vi.fn() }
})
let state = provider.getInitialState()
const tokens = ['---', 'name: "Orca"', 'enabled: true # flag', '---', '# Heading'].map(
(line) => {
const result = provider.tokenize(line, state)
state = result.endState
return result.tokens
}
)
expect(tokens[1]).toContainEqual({ startIndex: 0, scopes: 'md.entity.name.tag.yaml' })
expect(tokens[1]).toContainEqual({ startIndex: 6, scopes: 'md.string.quoted.double.yaml' })
expect(tokens[2]).toContainEqual({ startIndex: 9, scopes: 'md.constant.language.boolean.yaml' })
expect(tokens[2]).toContainEqual({ startIndex: 14, scopes: 'md.comment.line.number-sign.yaml' })
expect(tokens[4]).toContainEqual({ startIndex: 2, scopes: 'md.entity.name.section.markdown' })
})
})
@@ -49,24 +49,27 @@ function fenceLanguagesByLabel(
return byLabel
}
/** VS Code's markdown grammar with Dark+/Light+ colors; fence grammars load on first sight. */
/** VS Code's markdown grammar with Dark+/Light+ colors; YAML loads up front for frontmatter, fence grammars on first sight. */
export async function createMarkdownTokensProvider(
monaco: MonacoModule
): Promise<Monaco.languages.TokensProvider> {
const [
editorCore,
{ default: markdownGrammars },
{ default: yamlGrammars },
{ bundledLanguagesInfo },
{ rules: darkRules },
{ rules: lightRules }
] = await Promise.all([
loadEditorCore(),
import('shiki/langs/markdown.mjs'),
import('shiki/langs/yaml.mjs'),
import('shiki/langs'),
loadBuiltInMarkdownRules('dark'),
loadBuiltInMarkdownRules('light')
])
await editorCore.core.loadLanguage(...markdownGrammars)
// Why: frontmatter embeds YAML at the document start, with no fence label to trigger a lazy load.
await editorCore.core.loadLanguage(...markdownGrammars, ...yamlGrammars)
// Why: Orca's editors all use the built-in theme names; redefining them keeps every setTheme caller unchanged.
monaco.editor.defineTheme('vs-dark', {