lishid
February 25, 2022, 7:39pm
1
I’m dealing with a case where triple clicking a line will select everything on the line + the newline character at the very end.
It seems that this deviation from standard text selection behavior is generally intended for code editors because it helps with workflows involving copy-pasting blocks of code.
Would it make sense to allow this behavior to be customized? If not, I can just put the custom behavior in a fork instead.
}
function rangeForClick(view: EditorView, pos: number, bias: -1 | 1, type: number): SelectionRange {
if (type == 1) { // Single click
return EditorSelection.cursor(pos, bias)
} else if (type == 2) { // Double click
return groupAt(view.state, pos, bias)
} else { // Triple click
let visual = LineView.find(view.docView, pos), line = view.state.doc.lineAt(visual ? visual.posAtEnd : pos)
let from = visual ? visual.posAtStart : line.from, to = visual ? visual.posAtEnd : line.to
if (to < view.state.doc.length && to == line.to) to++
return EditorSelection.range(from, to)
}
}
let insideY = (y: number, rect: Rect) => y >= rect.top && y <= rect.bottom
let inside = (x: number, y: number, rect: Rect) => insideY(y, rect) && x >= rect.left && x <= rect.right
// Try to determine, for the given coordinates, associated with the
// given position, whether they are related to the element before or
// the element after the position.
marijn
February 28, 2022, 10:14am
2
An extension like this implements triple-click behavior without adding the line break after:
EditorView.mouseSelectionStyle.of((view, event) => {
if (event.detail != 3 || event.button != 0) return null
let start = view.posAtCoords(event)
if (start == null) return null
let startSel = view.state.selection
return {
get(curEvent, extend, multiple) {
let head = view.posAtCoords(curEvent)
if (head == null) return startSel
let anchor = extend ? startSel.main.anchor : start!
let anchorLine = view.state.doc.lineAt(anchor), headLine = view.state.doc.lineAt(head)
let range = head >= anchor ? EditorSelection.range(anchorLine.from, headLine.to)
: EditorSelection.range(anchorLine.to, headLine.from)
return multiple ? startSel.addRange(range) : EditorSelection.create([range])
},
update(update) {
start = update.changes.mapPos(start!)
startSel = startSel.map(update.changes)
}
}
})
2 Likes
lishid
February 28, 2022, 4:39pm
3
Thanks, that works perfectly! I totally forgot we can override with that API.