search overlay in selection

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!

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 :slight_smile:

That’s clever. You can use this addon to get a more efficient approach to keeping the selection marked with a class.