Hi,
I read a lot of docs, and a lot of examples, but I didn’t find a way to add multiple decorations with multiple marks for a single View.
Is it possible ? If so, how ?
Hi,
I read a lot of docs, and a lot of examples, but I didn’t find a way to add multiple decorations with multiple marks for a single View.
Is it possible ? If so, how ?
@marijn Is it possible ?
I really read almost all the doc, but didn’t find a way to do it. Even tho the example with underline is interesting, it doesn’t prove that it’s possible with multiple marks. I need your help, please.
I really don’t understand. Of course you can have multiple marks. The examples have multiple marks.
Oh, sorry if it wasnt clear.
Here is an example:
const addUnderline = StateEffect.define<{from: number, to: number}>({
map: ({from, to}, change) => ({from: change.mapPos(from), to: change.mapPos(to)})
})
const generateField = (mark: Decoration) => {
return () => StateField.define<DecorationSet>({
create() {
return Decoration.none
},
update(underlines, tr) {
underlines = underlines.map(tr.changes)
for (let e of tr.effects) if (e.is(addUnderline)) {
underlines = underlines.update({
add: [mark.range(e.value.from, e.value.to)]
})
}
return underlines
},
provide: f => EditorView.decorations.from(f)
})
}
const underlineMarkRed = Decoration.mark({class: "cm-underline-red"})
const underlineMarkGreen = Decoration.mark({class: "cm-underline-green"})
const underlineTheme = EditorView.baseTheme({
".cm-underline-red": { textDecoration: "underline 3px red" },
".cm-underline-green": { textDecoration: "underline 3px green" },
})
export function underlineSelection(view: EditorView, mark: Decoration, from: number, to: number) {
let effects: any[] = [ addUnderline.of({from, to}) ]
effects.push(StateEffect.appendConfig.of([generateField(mark)(),
underlineTheme]))
view.dispatch({effects})
return true
}
function addHighlighting(view: EditorView) {
underlineSelection(view, underlineMarkGreen, 0, 4); // Both highlight in green
underlineSelection(view, underlineMarkRed, 6, 10); // Both highlight in green
}
Here is a minimal example that I tried to recreate.
At the end, from char 0 to 4 and from char 6 to 10, there is a green underline.
None of them are red.
I searched for many different approaches.
From what I understand, it’s that the EditorView.decorations is updated with the wrong Field.
But I don’t really know how it is possible to do things differently.
You A) are using a single effect type for all type of underlines, so they will all pick up your addUnderline
effects (which is probably the reason you’re seeing only green underlines—the green ones cover the red ones), B) are adding a new state field for every underline you add, which doesn’t make any sense and will be hugely inefficient.
Thank you a lot!
You were right for the first point!
Yes, I agree 100% with you that it’s innefficient.
I have an idea to create a field for one color of underline, but I don’t know if there is a way to create a single field for every underline, because I didn’t find a way for the field to access the mark in an effect.
Is it possible ?
Thank you again btw!