Hello,
I am trying to create an atomic multiline widget but seems I can only do one or the other.
export function chatPrompt(state: EditorState) {
const chatWidgets: Range<Decoration>[] = [];
const doc = state.doc.toString();
// get position of string between "[[" and "]]"
const regex = /\[\[([\s\S]*?)\]\]/g;
let match;
while ((match = regex.exec(doc)) !== null) {
const chat = match[1];
const position = match.index;
const end = match.index + match[0].length;
const deco = Decoration.replace({
widget: new ChatPromptWidget(chat),
});
const range = deco.range(position, end);
chatWidgets.push(range);
}
return Decoration.set(chatWidgets);
}
export class ChatPromptWidget extends WidgetType {
value: string;
constructor(value: string) {
super();
this.value = value;
}
toDOM(): HTMLElement {
const span = document.createElement("span");
span.innerHTML = this.value;
span.className = "cm-prompt";
return span;
}
}
Option 1: using ViewPlugin = but this gives me error -
RangeError: Decorations that replace line breaks may not be specified via plugins
export const chatPromptEffect = StateEffect.define<{
decorations: DecorationSet;
}>({});
export const chatPromptPlugin = ViewPlugin.fromClass(
class {
chats: DecorationSet;
constructor(view: EditorView) {
this.chats = chatPrompt(view.state);
}
update(update: { state: EditorState }) {
this.chats = chatPrompt(update.state);
}
},
{
decorations: (instance) => instance.chats,
provide: (plugin) =>
EditorView.atomicRanges.of((view) => {
return view.state.field(charPromptExtension);
// or return view.plugin(plugin)?.chats || Decoration.none;
}),
},
);
Option 2: using StateField: but there is a type mismatch.
export const charPromptExtension = StateField.define({
create() {
return Decoration.none;
},
update(value, tr) {
for (const effect of tr.effects) {
if (effect.is(chatPromptEffect)) {
value = effect.value?.decorations;
}
}
return value;
},
provide(f) {
return EditorView.atomicRanges.from(f);
/* Error - TS2345: Argument of type StateField<DecorationSet> is not assignable to parameter of type
StateField<(view: EditorView) => RangeSet<any>>
Type DecorationSet is not assignable to type (view: EditorView) => RangeSet<any>
Type RangeSet<Decoration> provides no match for the signature (view: EditorView): RangeSet<any> */
},
});
If this even possible? Any pointers would be very helpful.