EditorView.darkTheme is not true when the theme is dark

when a dark theme is active .theme-dark is added to the dom/body, but EditorView.darkTheme isn’t true when it should be.

means a bit of extra (unnecessary) work have to be done when using third party codemirror themes. Where &dark and &light have to replace with .theme-dark & and .theme-light &.

Confirmed on 1.13.7: with a dark theme active, view.state.facet(EditorView.darkTheme) returns false. Obsidian only toggles .theme-dark on body and never sets the facet.

You can set it yourself from a plugin. workspace.updateOptions() with a mutable extension array (the pattern the docs describe for changing editor extensions at runtime) keeps it in sync:

import { Extension } from "@codemirror/state";
import { EditorView } from "@codemirror/view";

// in onload():
const isDark = () => activeDocument.body.hasClass("theme-dark");
const themeExt: Extension[] = [EditorView.darkTheme.of(isDark())];
this.registerEditorExtension(themeExt);

this.registerEvent(
  this.app.workspace.on("css-change", () => {
    themeExt.length = 0;
    themeExt.push(EditorView.darkTheme.of(isDark()));
    this.app.workspace.updateOptions();
  })
);

I checked it in a scratch vault: the facet follows light → dark → light on the open editor, and a note opened after the switch gets the right value too. css-change fires on every theme switch. With this in place, the &dark / &light selectors in third-party CM themes work unchanged.

It would still be nice if core set the facet itself.