Lingering mark on scrollbar

I’m using a custom search replace interface and I’m having a problem with the marks on scrollbar feature. If I replace matches manually the marks on the scrollbar disappear as I go along but if I use my replace all feature with a while loop the last mark is not cleared unless I clear the matches array in cm.showMatchesOnScrollbar() right after the loop

	ToolBars.prototype.replaceAll = function(e) {
		var cm =;
		var tools = this;
		cm.operation(function() {
			var elt =;
			tools.cursor = cm.getSearchCursor(tools.query, {line:0, ch:0}, tools.caseFold);
			var replaceText = tools.elt.replaceText.value;
			var found, from, to, textFound, newText			
			while (found = tools.cursor.findNext()) {
				textFound = cm.getRange(tools.cursor.from(),;	
				newText = typeof tools.query == "string" ? replaceText : textFound.replace(tools.query, replaceText) ;
				tools.cursor.replace(""); // clear old mark
				tools.markRP.push(cm.markText(tools.cursor.from(),, {className: "CodeMirror-markReplaced"}));			
			tools.markScroll.matches = [];
			tools.searchControls1.forEach(function(button) {
				button.disabled = true;
			tools.allReplace = true;
			tools.cursor = null;

tools.markScroll is the object returned by showMatchesOnScrollbar(). Clearing the matches array gets the job done ordinarily, but if I undo then redo I get the lingering match left behind.

Is there a way to get the last mark cleared without clearing the matches array after the loop?

The loop is synchronous—how are you even observing what the scrollbar marks are doing while it runs?

But yeah, the annotatescrollbar addon uses a debounce in order to avoid updating too often during quick changes.

Well, I’m not observing anything while it runs. If I don’t clear the matches array, I just see the last mark there after it’s done. Maybe I wasn’t clear: If I replace one at a time the marks clear as I go along , it’s only when I use replaceAll() that the last one lingers.

I’ve been comparing my code with yours in the search addon and I don’t see anything pertaining to matches on scrollbar. in your replace all function. What are you doing differently to handle this?

Ah, I see. That means something is indeed going wrong. You could try adding some console.log's to the annotatescrollbar code to see when it is refreshing and if it is a timing issue or a bug in the way the annotations are generated.

I tried putting

at the bottom of the while loop and it returns the same number every iteration.