Decoration.mark() has lower precedense over styleTags()?

I use markdown in code mirror. I try to achieve a goal, so that all elements in the editor are monospace, and only paragraphs and links are regular-size font.

I need lists, list marks and all whitespace in lists to appear monospace, and the content of the list to be regular font size. I know that for a one-line list that can be easily achieved by styleTags() and for example BulletList/Paragraph. But for list that spans multiple lines, that won’t work because the Paragraph also includes the whitespace

I’ve written this code:

import {HighlightStyle, Language, syntaxHighlighting} from "@codemirror/language";
import {EditorState, Facet, Range} from "@codemirror/state";
import {Decoration, DecorationSet, EditorView, ViewPlugin} from "@codemirror/view";
import {styleTags, Tag} from "@lezer/highlight";
import {MarkdownParser, parser} from "@lezer/markdown";

export function attachedEditorView(parent: HTMLElement): EditorView {
  return new EditorView({
    parent,
    state: EditorState.create({
      doc: '- list item one\n' +
        '  list item two\n' +
        '- second item one\n' +
        '  second item two ',
      extensions
    })
  });
}

const list = Tag.define();

const taggedNodes = styleTags({'BulletList/...': list});

const markdown: MarkdownParser = parser.configure([{props: [taggedNodes]}]);

const highlight = HighlightStyle.define([
  {tag: list, fontFamily: 'monospace'},
]);

const regularFont = Decoration.mark({class: 'cm-regularFont'});

const decorations: Range<Decoration>[] = [
  regularFont.range(2, 15), // "list item one"
  regularFont.range(18, 31), // "list item two"
  regularFont.range(34, 49), // "second item one"
  regularFont.range(52, 67), // "second item two"
];

function decorationPlugin(decorations: DecorationSet): ViewPlugin<object> {
  return ViewPlugin.define(() => ({decorations}),
    {decorations: v => v.decorations});
}

const extensions = [
  new Language(Facet.define(), markdown),
  syntaxHighlighting(highlight),
  decorationPlugin(Decoration.set(decorations)),
  EditorView.baseTheme({
    '.cm-regularFont': {
      'font-family': 'Arial',
      'color': 'red'
    },
  }),
];

And I can see that it works, because the paragraphs have {color:red} like I wanted, but the font-family doesn’t get applied. Somehow fontFamily:monospace from styleTag() takes precedence over it?

How can I achieve this?

Wrapping your decoration extension in Prec.highest should probably fix this.

1 Like

Yes!

It worked, thank you!