Add CircuitPython module highlighting overlay#481
Merged
makermelissa merged 7 commits intocircuitpython:betafrom Apr 29, 2026
Merged
Conversation
CodeMirror 6 dropped the simple extra_keywords mechanism that CM5 had, so instead of forking @codemirror/lang-python we layer a small ViewPlugin on top of the existing Python syntax tree. It walks the visible tree, finds VariableName nodes whose text matches a known CircuitPython core module or common Adafruit library, and tags them with a tok-cp-module class so the theme can color them distinctly. This avoids: - Forking lang-python and tracking upstream changes - Re-tokenizing strings/comments (we only mark identifier nodes) - Adding any per-keystroke parsing cost (decoration set is rebuilt only on doc/viewport/tree changes) Adds a magenta accent (#FF79C6) for .tok-cp-module in the editor theme so CircuitPython modules pop out from regular Python identifiers. Closes circuitpython#363
Drops the hand-curated list of adafruit_* community libraries in favour
of a startsWith("adafruit_") check. New Adafruit CircuitPython libraries
will be highlighted automatically as they ship, with no maintenance
needed in this file. The core CircuitPython module set still uses an
explicit allowlist because those names don't share a distinguishing
prefix.
The CircuitPython Community Bundle ships ~10 libraries with a `circuitpython_` prefix (circuitpython_csv, circuitpython_schedule, circuitpython_functools, etc.). Same prefix-match approach as adafruit_*: new community libraries are highlighted automatically.
Refreshed CIRCUITPYTHON_CORE_MODULES against the current contents of adafruit/circuitpython:shared-bindings/. Added 15 modules that have landed since the initial list was written: audiodelays, audiofilters, audiofreeverb, audiospeed, aurora_epaper, camera, fourwire, gnss, i2cioexpander, lvfontio, mcp4822, mipidsi, ps2io, qspibus, rclcpy. Removed the deprecated paralleldisplay alias (paralleldisplaybus is the modern name and is already listed) and the stray lsm6ds entry, which isn't a shared binding and isn't in the community bundle either. Standard-Python modules that CircuitPython also exposes (math, os, time, random, struct, hashlib, ipaddress, locale, __future__) are intentionally left out so we don't recolour those names in plain Python code. Underscore-prefixed internal bindings (_bleio etc.) are also omitted; users reach for the adafruit_ wrappers, which the prefix wildcard already matches.
These are early Adafruit-maintained libraries that predate the adafruit_ naming convention, not community-bundle modules.
When an identifier matches both classHighlighter's VariableName tag and our CircuitPython overlay, CodeMirror renders nested mark spans. The inner span (closer to the text) is what the browser uses for `color`, and it's chosen by decoration precedence \u2014 so without an explicit precedence wrapper, the syntax highlighter's blue stayed on top and `neopixel` rendered the same color as any other variable. Wrapping the ViewPlugin with Prec.highest puts the tok-cp-module span inside the tok-variableName span, letting the pink override the blue without touching the CSS or using !important.
makermelissa
approved these changes
Apr 29, 2026
Collaborator
makermelissa
left a comment
There was a problem hiding this comment.
Tested and working
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related to #363 (held open until beta features merge to main).
Targets the
betabranch.Approach
CodeMirror 6 dropped the simple
extra_keywordsmechanism that CM5 had, so instead of forking@codemirror/lang-python(and tracking it forever) this layers a smallViewPluginon top of the existing Python syntax tree.The plugin walks the visible
syntaxTree, findsVariableNamenodes whose text matches a known CircuitPython core module or common Adafruit library, and tags them with classtok-cp-moduleso the theme can color them distinctly.Files
js/common/circuitpython_highlight.js— the overlay extension.js/script.js— addscircuitpythonHighlighttoeditorExtensions.sass/layout/_themes.scss— adds.tok-cp-modulerule with a magenta accent (#FF79C6).Module list
~125 names: all CircuitPython core modules (
board,digitalio,displayio,busio,wifi,synthio,keypad,pulseio,pwmio,usb_cdc,usb_hid,usb_midi, etc.) plus the most commonadafruit_*libraries plusneopixelandsimpleio. The list lives in oneSetat the top of the new file — easy to extend or trim.Why this approach
@codemirror/lang-python.VariableName), so strings and comments are never miscolored.@codemirror/viewand@codemirror/languagealready in the tree.Trade-offs / future work
board.D13) we'd extend the same overlay toPropertyNamenodes — easy follow-up.Test
npm run buildis clean.tok-cp-moduleships indist/assets/index.css.