@marijn Thanks to you and Nirmal above I have it pretty much working. I’m about to publish an npm module to make this easier.
Only 1 thing I’m a little stuck on (but still have mostly working): CSS rendering.
Here’s what I’m currently doing:
// more code above that uses highlightTree() to generate the proper markup
// FIXME: don't hard-code 'ͼ1 ͼ2 ͼ4'
return `
<div class="cm-editor ͼ1 ͼ2 ͼ4">
<div class="cm-scroller">
<div class="cm-content">${tokenizedStringWithClassNames}</div>
</div>
</div>`;
Which generates this:
<div class="cm-editor ͼ1 ͼ2 ͼ4">
<div class="cm-scroller">
<div class="cm-content">
<div class="cm-line"><span class="ͼb">function</span> <span class="ͼg">add</span>(<span class="ͼg">a</span>,<span class="ͼg">b</span>){</div>
<div class="cm-line"> <span class="ͼb">return</span> a+b;</div>
<div class="cm-line">} </div>
<div class="cm-line"><span class="ͼm">// amazing comment!</span></div>
</div>
</div>
</div>
So far so good.
import {oneDarkHighlightStyle, oneDarkTheme } from '@codemirror/theme-one-dark'
Now I import the theme and pass oneDarkHighlightStyle
to highlightTree()
.
I get most of the CSS rules by calling oneDarkHighlightStyle.module.getRules()
:
.ͼp {color: #c678dd;}
.ͼq {color: #e06c75;}
.ͼr {color: #61afef;}
.ͼs {color: #d19a66;}
.ͼt {color: #abb2bf;}
.ͼu {color: #e5c07b;}
.ͼv {color: #56b6c2;}
.ͼw {color: #7d8799;}
.ͼx {font-weight: bold;}
.ͼy {font-style: italic;}
.ͼz {text-decoration: line-through;}
.ͼ10 {color: #7d8799; text-decoration: underline;}
.ͼ11 {font-weight: bold; color: #e06c75;}
.ͼ12 {color: #d19a66;}
.ͼ13 {color: #98c379;}
.ͼ14 {color: #ffffff;}
I realized I’m missing some styles, like the background-color of the editor etc…
I’m able to extract the missing styles by… :
- extracting
oneDarkTheme[0].value
to get the scope class → ͼo
- extract the rest of the styles with
oneDarkTheme[1].value?.getRules();
→
.ͼo {color: #abb2bf; background-color: #282c34;}
.ͼo .cm-content {caret-color: #528bff;}
.ͼo .cm-cursor, .ͼo .cm-dropCursor {border-left-color: #528bff;}
.ͼo.cm-focused .cm-selectionBackground, .ͼo .cm-selectionBackground, .ͼo .cm-content ::selection {background-color: #3E4451;}
.ͼo .cm-panels {background-color: #21252b; color: #abb2bf;}
.ͼo .cm-panels.cm-panels-top {border-bottom: 2px solid black;}
.ͼo .cm-panels.cm-panels-bottom {border-top: 2px solid black;}
.ͼo .cm-searchMatch {background-color: #72a1ff59; outline: 1px solid #457dff;}
.ͼo .cm-searchMatch.cm-searchMatch-selected {background-color: #6199ff2f;}
.ͼo .cm-activeLine {background-color: #2c313a;}
.ͼo .cm-selectionMatch {background-color: #aafe661a;}
.ͼo.cm-focused .cm-matchingBracket, .ͼo.cm-focused .cm-nonmatchingBracket {background-color: #bad0f847; outline: 1px solid #515a6b;}
.ͼo .cm-gutters {background-color: #282c34; color: #7d8799; border: none;}
.ͼo .cm-activeLineGutter {background-color: #2c313a;}
.ͼo .cm-foldPlaceholder {background-color: transparent; border: none; color: #ddd;}
.ͼo .cm-tooltip {border: none; background-color: #353a42;}
.ͼo .cm-tooltip .cm-tooltip-arrow:before {border-top-color: transparent; border-bottom-color: transparent;}
.ͼo .cm-tooltip .cm-tooltip-arrow:after {border-top-color: #353a42; border-bottom-color: #353a42;}
.ͼo .cm-tooltip-autocomplete > ul > li[aria-selected] {background-color: #2c313a; color: #abb2bf;}
Now I add ͼo
classname to the .cm-editor
element and then this works. But extracting the missing styles this way feels very hacky and brittle to me.
@marijn Any guidance on what I’m doing here? Any APIs I should be calling instead of what I’m doing?
Thank you!