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?

1 Like

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.

2 Likes

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

Yeah, the problem I had was, that I don’t have an editor instance. I am just using the highlightTree from @codemirror/highlight standalone to highlight some code and want to apply a style which is conditional on some media query. I currently still don’t see any other way than either manually removing the old style or using css variables.

1 Like

Right. This’ll improve as soon as the highlighting-style-adding-static-classes is done.

1 Like

Release 0.18.0 should address some of these issue (especially wrt highlighting).

1 Like

@marijn if we have unit tests that relied on the class cm-keyword to check for highlighting syntax, is there another way to check whether or not syntax highlighting is working or not? thanks!

classHighlighter might be what you want.

thanks! hmm :thinking: so i was expecting to see classes with tok-* but interestingly… i’m not… (unless i misunderstood the docs)

image

i am loading themes from https://github.com/uiwjs/react-codemirror/tree/master/theme though. Could this be the issue?

That DOM doesn’t look like it has classHighlighter active. Compare with this.

1 Like

ohh thank you so much!