clarification on mark decoration

Hello,

i’ve never used older version of codemirror, starting straight with v6, and i’d like to clarify a few concepts/keywords for my use-case…

I have a simple editor with plaintex (custom DSL with no currently existing CM6 language extension). I’d like to add a simple higlighting to a single range of a text in editor’s content.

Type of highlight i expect is similar to “selection” or a gray-ish background highlight for pre-formatted text here on discourse for anything between backticks `like this`

This is not to be done on keypress in editor (thus my assumption i dont need to define the Command/binding/keymaps that’s in the latter part of the examples) but driven by external HTML event/other component…

E.g. i have text in editor:

container outer {
  leaf hello;
  leaf there;
}

and want to define JS/TS function to trigger/set custom mark decoration for all the text in range of “from” → “to”. e.g. range of 20 -> 31 would “decorate” the text leaf hello;.

Looking into decoration examples on CM page, my current understanding is, i need to use view and run a transaction that will add/remove/overwrite my decoration…

// reference to my existing editor/view
const view = ...; 

// i have no textual "changes" to be done,
// so i guess i need to apply some "effect" here?
const transaction = view.state.update({
  effects: {...} 
});

view.dispatch(transaction);

At this point however, i am completely lost as for actual transaction payload…

What concepts/object types have to be included in the transaction itself that would lead to a specific text range highlight? Please note that following is not a criticism, but my observations that may not be complete/correct, and i’d like a pointers/push to right directions… :slight_smile:

  • There’s a mention of RangeSet but example page then does not instantiate any explicitly with this type defintion/import.

  • do i need code similar to this, when i dont want to edit/update any editor’s text in the transaction doing the highlight?

    const addUnderline = StateEffect.define<{from: number, to: number}>({
    map: ({from, to}, change) => ({from: change.mapPos(from), to: change.mapPos(to)})
    })
    
  • What’s the use-case of a StateField object, reps. what does it represent? (from architectural point of view)

  • The const underlineField = StateField.define<DecorationSet>({ part if confusing for me → do i need to define create/update/provide callbacks? Reps. when do i do, and when not? It’s a bit confusing to me what are the actual underlines in the update callback.

thanks for all/any feedback, and apologies for the wall of text! :slight_smile:

j.

You will have to write an extension that stores the range(s) that is currently highlighted, and registers decorations that show the highlight. The state field in this specific example might provide a good template. It uses an effect to signal added decorations, maintains a range set containing the current decorations, and registers this set with the EditorView.decorations facet. I’m not sure what you mean by “does not instantiate any explicitly”—Decoration.none creates a set, and you can grow and update that by calling methods on it.

thanks for pointers! how does one invoke CM’s extension manually/explicitly via code though?

In the examples it is bound to keymaps, but i’d like to trigger (not)higlighting of a variable range in my reactive framework’s code /methods… (VueJS) therefore my original question whether calling view.state.update is the way to do it.

(by explicit instantiating, i meant that example did not use literal mention of RangeSet type declaration in the code excerpts)

it seems i have reached my goal with almost 100% matching use-case as in

:slight_smile:

compliments to the powerfull library and your effort/energy invested!