Skip to content

refactor(code-editor): update to Codemirror 6#421

Merged
e111077 merged 3 commits intogoogle:mainfrom
e111077:codemirror-6
Sep 22, 2025
Merged

refactor(code-editor): update to Codemirror 6#421
e111077 merged 3 commits intogoogle:mainfrom
e111077:codemirror-6

Conversation

@e111077
Copy link
Collaborator

@e111077 e111077 commented Mar 18, 2025

Upgrade to codemirror 6

per-file summary

src/playground-code-editor.ts Major rewrite to adapt to CodeMirror 6:
  • Replaced CodeMirror 5 imports and types with CodeMirror 6 equivalents (EditorState, EditorView, Extension, Compartment, etc.).
  • Removed the old playgroundStyles import and added the new styles import from playground-styles.ts.
  • Applied the .tok-* classes with syntaxHighlighting(classHighlighter, {fallback: true})
  • Changed internal state management from CM5's Editor instance to CM6's EditorView and EditorState.
  • Updated property getters (cursorPosition, cursorIndex, tokenUnderCursor) to use the CM6 API.
  • Rewrote the update method to use CM6 Compartments and StateEffects for dynamic configuration changes for the following features:
    • line numbers
    • wrapping
    • language
    • read-only
    • completions
  • Replaced the CM5 view creation logic with CM6 EditorView instantiation and state creation (_createEditorState).
  • Implemented language switching using _getLanguageExtension and the _languageCompartment.
  • Autocomplete
    • Rewrote completion logic using CM6's autocompletion extension
    • Removed CM5 hint-related code.
    • Adapted _showDiagnostics to use CM6 Decorations and StateField.
  • Reimplemented hide/fold pragma logic
    • using CM6 Decorations, WidgetType, and Annotations.
  • Removed CM5-specific methods and event listeners (e.g., _onRenderLine).
  • Added createRenderRoot to handle shadow root adoption for the EditorView
    • This was done to shore up some issues with the shadow root not being available in certain instances at connectedCallback()
playground-styles.css

Deleted this file entirely. Instead manually wrote the .css.ts file's style overrides.

src/playground-styles.ts
  • Defines the editor's base styles and syntax highlighting theme.
  • Styles are adapted from the old playground-styles.css but use CodeMirror 6 class names
  • unlike before, it's not the styles + overrides, but rather JUST the overrides + css custom props
package.json
  • Removed CodeMirror 5 related packages (@types/codemirror, codemirror-grammar-mode, google_modes).
  • Added numerous CodeMirror 6 packages (@codemirror/*, @lezer/*).
  • Updated the main codemirror dependency to ^6.0.1.
  • Added codemirror-5 as a git dependency, for theme generation compatibility.
  • Updated versions and integrity hash
  • Removed build scripts related to CM5 (build:styles-module, build:codemirror).
  • Updated wireit configurations to remove dependencies on the deleted build scripts.
rollup.config.codemirror.js Deleted this file. It was responsible for bundling CodeMirror 5 and its addons.
rollup.config.styles.js

Deleted this file. It was used to process playground-styles.css into a TypeScript module.

scripts/theme-generator.js

Updated the script to read theme files from the codemirror-5/theme directory instead of codemirror/theme, reflecting the aliased package name for the old version.

src/_codemirror

Deleted this directory. This was the entry point for the custom CodeMirror 5 ESM-ified bundle.

src/cm-lang-lit.ts
  • Defines custom CodeMirror 6 language support for Lit templates
    • html, css, svg, mathml within JavaScript and TypeScript
  • exports language definitions:
    • litLanguage
    • litJsxLanguage
    • A main lit() language support function.
src/configurator/highlight-tokens.ts
  • Updated the cmClass property for each token definition to match the new token class names generated by CodeMirror 6's classHighlighter
    • e.g., cm-keyword changed to tok-keyword
  • Added a new synBool token.
src/configurator/playground-theme-detector.ts
  • Removed logic specific to CodeMirror 5's rendering (viewportMargin).
  • Added a mapping (tokenToCssProperty) to translate CM6 token names back to the existing CSS custom property names for compatibility.
  • Updated the logic for extracting token classes to handle both cm- and tok- prefixes.
  • Adjusted the text processing logic to better match how CM6 structures its highlighted output (e.g., handling #id in CSS).
src/internal/codemirror.ts

Deleted this file. It previously exported the CodeMirror 5 global object.

Parent Children
(main) e111077#1

@e111077 e111077 force-pushed the codemirror-6 branch 4 times, most recently from b19a47f to 7c0472e Compare April 3, 2025 06:41
@e111077 e111077 marked this pull request as ready for review April 3, 2025 06:43
@e111077 e111077 requested a review from justinfagnani April 3, 2025 06:43
@e111077
Copy link
Collaborator Author

e111077 commented Apr 10, 2025

heya @justinfagnani @aomarks, I've added a summary to my description in the order of what files I think are important in this PR

@e111077 e111077 force-pushed the codemirror-6 branch 5 times, most recently from f20aba8 to c1c8a98 Compare May 15, 2025 22:05
Copy link
Member

@aomarks aomarks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the very slow review.

Code looks really nice, appreciate all the comments!

Just some small nits.

@e111077
Copy link
Collaborator Author

e111077 commented May 21, 2025

Also re: cache check failure in CI, is that solved with a new version of Wireit or is that a repo setting?

Updated Ci settings for Wireit to use v2 caching

@e111077
Copy link
Collaborator Author

e111077 commented May 22, 2025

thanks for the review @aomarks, addressed comments. The CI seems to be failing because GH actions caching seems to have been deprecated? Fixed, see previous comment.

@e111077 e111077 force-pushed the codemirror-6 branch 7 times, most recently from fff3844 to 8a8358e Compare May 22, 2025 21:30
const parsers: Record<string, LRParser> = {
html: htmlLanguage.parser,
css: cssLanguage.parser,
svg: xmlLanguage.parser,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, I wasn't 100% sure that svg and mathml should use the xml parser, or if the HTML mode handles that, but I think XML is correct since there's no containing <svg> tag to kick the parser into XML mode.

This issues is that I think we may be missing out on code completion in these sections though, since the parser doesn't know that we're specifically in SVG or MathML languages. Maybe there's something we can pull from the HTML language, or maybe there are SVG and MathML languages we can use?

Copy link
Collaborator Author

@e111077 e111077 Jul 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think HTML uses the XML parser – I don't know if we can do any better. When I added the XML package, the tree-shaken / minified bundle didn't change in size

}

// Map from CM6 token names to CSS property base names
// This maintains backward compatibility with the CSS custom property names
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this 👍

but I would discuss whether it's needed, or if consumers can update their custom themes easily enough along with a new major version of playground elements.

I suspect we'll be on CM6 and its class names for a long while after this transition.

Copy link
Collaborator Author

@e111077 e111077 Jul 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can maybe do two major releases. this one (engine breaking) and a proper breaking one? I'm just thinking of our own migration on lit.dev being annoying

const themeFilenames = fs
.readdirSync(
pathlib.resolve(rootDir, 'node_modules', 'codemirror', 'theme')
pathlib.resolve(rootDir, 'node_modules', 'codemirror-5', 'theme')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget the details, but did we talk about using native CM6 themes instead, like https://github.com/fsegurai/codemirror-themes?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a sub-PR that we can merge into this branch or after this one that allows for arbitrarily setting extensions

e111077#1

feat(editor): enable adding codemirror extensions
@e111077 e111077 merged commit bf57bfe into google:main Sep 22, 2025
3 of 4 checks passed
@e111077 e111077 deleted the codemirror-6 branch September 22, 2025 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants