Why does CM6 use the "ͼ" character in class names?

I’m working on switching from CodeMirror 5 to 6 and noticed that there are some classes that start with the ͼ character. For example, when using the html highlighter the names of html tags have the ͼf class. The cm-wrap div also has the ͼ1, ͼ2, and ͼ3 classes.

I didn’t see anything about this in the migration guide or the reference manual, is there a reason for this character over something more easily typed on keyboards?

These are generated anonymous classes. You shouldn’t be typing them, because targeting them with CSS rules isn’t going to work—they aren’t stable across page loads.

Is writing css-in-js / style-mod going to be the only way to affect syntax highlighting styles when using codemirror/highlight?

Two things you could’ve done previously with codemirror 5, which provided stable read-able tokens, with css only is that you could have

  1. language specific syntax highlighting (.class .cm-token)

  2. theme specific syntax highlight (.theme .cm-token)

Is the only way to achieve these two right now to create and then mount the javascript-generated stylesheets? What’s the reasoning to let styleMod generate the syntax tokens via its default function

  // :: () → string
  // Generate a new unique CSS class name.
  static newName() {
    let id = top[COUNT] || 1
    top[COUNT] = id + 1
    return C + id.toString(36)
  }

rather than something like the following which allows developers to hardcode the values and then target them with css later on

    for (let style of spec) {
      let cls = style.className || StyleModule.newName() // edited
      modSpec["." + cls] = Object.assign({}, style, {tag: null, className: null}) // edited
      let tags = style.tag
      if (!Array.isArray(tags)) tags = [tags as Tag]
      for (let tag of tags) this.map[tag.id] = cls
    }

Is writing css-in-js / style-mod going to be the only way to affect syntax highlighting styles when using codemirror/highlight?

Yes.

language specific syntax highlighting (.class .cm-token)

I had plans for this but it appears I never finished. Would a way for a highlighting style to scope rules to a specific language work for your use case?

theme specific syntax highlight (.theme .cm-token)

The idea is that each theme will want to provide its own highlighter (see for an example the One Dark theme).

something like the following which allows developers to hardcode the values

The problem with hardcoded values is that they’ll clash. And things like highlight styles don’t assign names to rules at all right now.

Adding my use case to this thread instead of starting a new one. Let me know if it makes more sense to start its own thread.

We make a markdown-based note tool called Obsidian. I’m experimenting with CM6 for our markdown editor (we’re currently using CM5).

Part of the big selling point that our customers love is the fact that they can easily customize any aspect of the app using “Custom CSS” - basically a stylesheet (or multiple) the user can define to re-theme the app.

Many of our users have taken liberty to re-style tokens from our markdown parser (originally based on HyperMD) to their preferences.

Users have also shared many “community themes” under an official repo like this:

I think as long as there’s a way to consistently generate token classes (preferably developer-definable, so we can keep the same class names as we’re currently using), that would be a reasonable solution to the use case.

2 Likes

I had plans for this but it appears I never finished. Would a way for a highlighting style to scope rules to a specific language work for your use case?

Yeah that would work

The idea is that each theme will want to provide its own highlighter

One drawback of this is that if a person wanted to toggle between light and dark modes by adding a class to the root of their app, they would also have to write additional javascript to toggle the theme of codemirror instead of relying on css from the app toggle.

The problem with hardcoded values is that they’ll clash. And things like highlight styles don’t assign names to rules at all right now.

As long as each spec fed into HighlightStyle is given a unique name, there shouldn’t be conflict right? For example,

export const oneDarkHighlightStyle = HighlightStyle.define(
  {tag: t.keyword, 
   name: "cm-keyword",
   color: violet},
  {tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName],
   name: "cm-meta",
   color: coral},
  {tag: t.string,
   name: "cm-string",
   color: sage},
}

Edit: A small, additional reason for having hardcoded / stable class-names is that it would make debugging styles a bit easier: e.g. given ͼ2, it’s hard to know looking at the class only which of the style tags were applied.

1 Like

This way of defining styles seems weird and limited. I want to embed codemirror into prosemirror, and the final developer/user of the editor can modify the highlight style through CSS.

It seems difficult to achieve this behavior.

I am also struggling with this. I am adopting CodeMirror 6 in an App wich applies Dark or Light theme based on a media query. There is window.matchMedia wich gives us a programatic way of dealing with it. But there seems to be no way to “unmount” stylemodules:

    const darkMode = window.matchMedia('(prefers-color-scheme: dark)')
    function updateTheme(darkMode: boolean) {      
      if (darkMode) {                
        StyleModule.mount(document, dark.module);
      } else {
        StyleModule.mount(document, light.module); 
      }
    }
    updateTheme(darkMode.matches);
    darkMode.addEventListener("change", (e) => updateTheme(e.matches))    

The code does not work as expected since the old style module is still around… I cannot use a codemirror extension here since I am also using syntax highlighting standalone (pre rendered on the server) in the same document.

I found a workaround for me: I use css variables like 'color': 'var(--some-color)' instead of concrete color values in the color theme and set them in the outer style sheet. Not optimal but it works well with media queries and everything.

1 Like

You’re not using them in the intended way. I’m not sure what is in light and dark, but you shouldn’t be manually mounting style modules like that unless you want them to apply unconditionally. Create a proper theme or highlight style, and add it to your editor configuration. Only the active themes and highlighter will take effect.

See also the Styling and theming design discussion thread