I’d appreciate it if you could put this into the codebase since I use the cursorGroupForwardWin and selectGroupForwardWin.
Here’s my implementation that seems to work OK:
/// Delete the selection forward in the default Windows style,
/// where it moves to the start of the next group.
export const deleteGroupForwardWin: StateCommand = target => deleteBy(target, range => {
let pos = range.head, {state} = target, line = state.doc.lineAt(pos)
let categorize = state.charCategorizer(pos)
for (let cat: CharCategory | null = null;;) {
if (pos == line.to) {
if (pos == range.head && line.number != state.doc.lines)
pos += 1
break
}
let next = findClusterBreak(line.text, pos - line.from, true) + line.from
let nextChar = line.text.slice(Math.min(pos, next) - line.from, Math.max(pos, next) - line.from)
let nextCat = categorize(nextChar)
if (cat != null && nextCat != cat && nextCat != CharCategory.Space) break
cat = nextCat
pos = next
}
return pos
})
Where the real difference from deleteByGroup is these lines:
(regular version)
if (cat != null && nextCat != cat) break
if (nextChar != " " ) cat = nextCat
(win version)
if (cat != null && nextCat != cat && nextCat != CharCategory.Space) break
cat = nextCat
The logic just says that any category change wants you to stop, except if you go into the space category. So this will allow whitespace following some non-whitespace group to be eaten upafter.
I’m not sure if there’s a reason to check “ “ instead of CharCategory.Space. I think the latter would also eat up tabs which you want?