I am trying to add sublime-like search options to codemirror including an ‘in-selection’ option.
When in-selection is chosen I need the highlight overlay to highlight only matches inside the current selection.
Is this possible in CM ? the problem seems to be that the search overlay does not know the editor location of the stream it is looking at.
Any help on implementing this ?
Thx!
marijn
2
Overlays apply to the whole document, so in this case you’ll need to program your own markText
-based highlighting.
I came up with a better solution than markText.
first I make sure selected text have the class ‘selectedText’:
// set cm-selectedText class on selected text
let selectionChangedTimeout, prevRanges=[];
cm.on('beforeSelectionChange', (cm ,obj) => {
clearTimeout(selectionChangedTimeout);
let ranges=obj.ranges;
if (prevRanges.length>0 || ranges.length>0) selectionChangedTimeout=setTimeout(() => {
prevRanges.forEach(range => {
cm.findMarks(range.anchor, range.head).forEach(mark => {
if (mark.className==='cm-selectedText') mark.clear();
});
});
ranges.forEach(range => {
cm.markText(range.anchor, range.head, { className: 'cm-selectedText' });
});
prevRanges=ranges;
}, 100);
});
Then in the search overlay I do:
return state.search.inSelection ? 'selectionSearching' : 'searching';
And then I set the CSS rules as follows:
.cm-searching {
background-color: rgba(255, 255, 0, .4);
}
.cm-selectionSearching.cm-selectedText {
background-color: rgba(255, 255, 0, .4);
}
voila
marijn
4
That’s clever. You can use this addon to get a more efficient approach to keeping the selection marked with a class.