The problem I have is removing preexisting decoration in the same range as the text I am parsing … I need the text of the currently changed word (if I get more text as is done above that’s fine), then I need to remove existing word decorations and parse.
DecorationSet.find receives absolute positions, how do I translate the positions used in
let txt = tr.selection.$from.parent.textBetween(0, tr.selection.$from.parent.content.size);
to positions I can feed to deco.remove(deco.find( ????, ???? )); ?
$f.start() and $f.end() will be the same position when the cursor is on a node boundary, or the positions around the text node when it is inside a text node. They won’t help you get the range around inserted text.
Your state lives in a closed-over variable rather than in the actual state field
You’re returning a transaction from apply, which should return an updated state. Similarly, init should return an initial state.
You’re not mapping your decoration set forward in apply (decos = decos.map(tr.mapping, tr.doc)), which is probably the reason you’re seeing strange effects.
thx, I am confused here, what is the right way to get the range here ?
yes, I find that easier, the only shortcoming I can see is that decos will not be available to code outside the plugin … is there any other issue with this ?
In the ref, here, the syntax shows -> T but the text reads producing a new field value so I’m confused which one is correct ?
There’s no easy answer to that. You could inspect the step maps for the steps in the transaction and use forEach to get the ranges they inserted, but that would involve mapping ranges from previous steps forward through subsequent steps. I don’t have time to write the code out for you, though.
Also it completely defeats the purpose of having persistent data structures and will cause all instances of the editor state to share the same plugin state, and thus break whenever you use it in a non-linear way (create two state updates from a single start state).
In the ref, here, the syntax shows → T
T here is the type parameter that stands for the plugin state’s type.
Thing is, I am only interested in the text word around the cursor position. If I get a bit more or not that’s ok, so it seems the implementation above works fine for that. I think $from and $to work ok in this case ?
I tried to adapt the code from the word highlighter gist
so:
function rangeFromTransform(tr) {
let from, to
for (let i = 0; i < tr.steps.length; i++) {
let step = tr.steps[i],
map = step.getMap()
let stepFrom = map.map(step.from || step.pos, -1)
let stepTo = map.map(step.to || step.pos, 1)
from = from ? map.map(from, -1).pos.min(stepFrom) : stepFrom
to = to ? map.map(to, 1).pos.max(stepTo) : stepTo
}
return { from, to }
}
let { from, to } = rangeFromTransform(tr)
if (from && to && tr.docChanged) {
const $t = state.doc.resolve(to)
let txt = $t.parent.textBetween(0, $t.end() - $t.start(), ' ');