Skip to content

Commit 85058b4

Browse files
authored
Merge pull request #3362 from kammeows/Branch_Kamakshi
fix: reset search match counter when switching files (issue #3361)
2 parents b0ef067 + 602222b commit 85058b4

File tree

1 file changed

+107
-40
lines changed

1 file changed

+107
-40
lines changed

client/utils/codemirror-search.js

+107-40
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ import upArrow from '../images/up-arrow.svg?byContent';
1818
import exitIcon from '../images/exit.svg?byContent';
1919

2020
function searchOverlay(query, caseInsensitive) {
21-
if (typeof query == 'string')
21+
if (typeof query == 'string') {
2222
query = new RegExp(
2323
query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'),
2424
caseInsensitive ? 'gi' : 'g'
2525
);
26-
else if (!query.global)
26+
} else if (!query.global) {
2727
query = new RegExp(query.source, query.ignoreCase ? 'gi' : 'g');
28+
}
2829

2930
return {
3031
token: function (stream) {
@@ -49,6 +50,8 @@ function SearchState() {
4950
this.caseInsensitive = true;
5051
this.wholeWord = false;
5152
this.replaceStarted = false;
53+
this.lastFileName =
54+
document.querySelector('.editor__file-name span')?.innerText || null;
5255
}
5356

5457
function getSearchState(cm) {
@@ -60,6 +63,50 @@ function getSearchCursor(cm, query, pos) {
6063
return cm.getSearchCursor(query, pos, getSearchState(cm).caseInsensitive);
6164
}
6265

66+
function watchFileChanges(cm, searchState, searchField) {
67+
let observer = null;
68+
69+
function setupObserver() {
70+
var fileNameElement = document.querySelector('.editor__file-name span');
71+
72+
if (!fileNameElement) {
73+
setTimeout(setupObserver, 500);
74+
return;
75+
}
76+
77+
if (observer) {
78+
return;
79+
}
80+
81+
observer = new MutationObserver(() => {
82+
if (searchField.value.length > 1) {
83+
startSearch(cm, searchState, searchField.value);
84+
}
85+
});
86+
87+
observer.observe(fileNameElement, { characterData: true, subtree: true });
88+
}
89+
90+
function disconnectObserver() {
91+
if (observer) {
92+
observer.disconnect();
93+
observer = null;
94+
}
95+
}
96+
97+
setupObserver();
98+
99+
setInterval(() => {
100+
var searchDialog = document.querySelector('.CodeMirror-dialog');
101+
if (!searchDialog && observer) {
102+
disconnectObserver();
103+
return;
104+
} else if (searchDialog && !observer) {
105+
setupObserver();
106+
}
107+
}, 500);
108+
}
109+
63110
function isMouseClick(event) {
64111
if (event.detail > 0) return true;
65112
else return false;
@@ -88,10 +135,11 @@ function persistentDialog(cm, text, deflt, onEnter, replaceOpened, onKeyDown) {
88135

89136
var state = getSearchState(cm);
90137

138+
watchFileChanges(cm, getSearchState(cm), searchField);
139+
91140
CodeMirror.on(searchField, 'keyup', function (e) {
92141
state.replaceStarted = false;
93142
if (e.keyCode !== 13 && searchField.value.length > 1) {
94-
// not enter and more than 1 character to search
95143
startSearch(cm, getSearchState(cm), searchField.value);
96144
} else if (searchField.value.length < 1) {
97145
cm.display.wrapper.querySelector(
@@ -101,8 +149,8 @@ function persistentDialog(cm, text, deflt, onEnter, replaceOpened, onKeyDown) {
101149
});
102150

103151
CodeMirror.on(closeButton, 'click', function () {
104-
clearSearch(cm);
105152
dialog.parentNode.removeChild(dialog);
153+
clearSearch(cm);
106154
cm.focus();
107155
});
108156

@@ -323,7 +371,6 @@ function parseString(string) {
323371
function parseQuery(query, state) {
324372
var emptyQuery = 'x^'; // matches nothing
325373
if (query === '') {
326-
// empty string matches nothing
327374
query = emptyQuery;
328375
} else {
329376
if (state.regexp === false) {
@@ -349,44 +396,64 @@ function parseQuery(query, state) {
349396
}
350397

351398
function startSearch(cm, state, query) {
352-
state.queryText = query;
353-
state.lastQuery = query;
354-
state.query = parseQuery(query, state);
355-
cm.removeOverlay(state.overlay, state.caseInsensitive);
356-
state.overlay = searchOverlay(state.query, state.caseInsensitive);
357-
cm.addOverlay(state.overlay);
358-
if (cm.showMatchesOnScrollbar) {
359-
if (state.annotate) {
360-
state.annotate.clear();
361-
state.annotate = null;
399+
var searchDialog = document.querySelector('.CodeMirror-dialog');
400+
if (searchDialog) {
401+
// check if the file has changed
402+
let currentFileName = document.querySelector('.editor__file-name span')
403+
?.innerText;
404+
405+
if (state.lastFileName !== currentFileName) {
406+
state.lastFileName = currentFileName;
407+
state.queryText = null;
408+
state.lastQuery = null;
409+
state.query = null;
410+
cm.removeOverlay(state.overlay);
411+
state.overlay = null;
412+
413+
if (searchDialog) {
414+
cm.display.wrapper.querySelector(
415+
'.CodeMirror-search-results'
416+
).innerText = '0/0';
417+
}
362418
}
363-
state.annotate = cm.showMatchesOnScrollbar(
364-
state.query,
365-
state.caseInsensitive
366-
);
367-
}
368419

369-
//Updating the UI everytime the search input changes
370-
var cursor = getSearchCursor(cm, state.query);
371-
cursor.findNext();
372-
var num_match = cm.state.search.annotate.matches.length;
373-
//no matches found
374-
if (num_match == 0) {
375-
cm.display.wrapper.querySelector(
376-
'.CodeMirror-search-results'
377-
).innerText = i18n.t('CodemirrorFindAndReplace.NoResults');
420+
state.queryText = query;
421+
state.lastQuery = query;
422+
state.query = parseQuery(query, state);
378423
cm.removeOverlay(state.overlay, state.caseInsensitive);
379-
} else {
380-
var next =
381-
cm.state.search.annotate.matches.findIndex((s) => {
382-
return (
383-
s.from.ch === cursor.from().ch && s.from.line === cursor.from().line
384-
);
385-
}) + 1;
386-
var text_match = next + '/' + num_match;
387-
cm.display.wrapper.querySelector(
388-
'.CodeMirror-search-results'
389-
).innerText = text_match;
424+
state.overlay = searchOverlay(state.query, state.caseInsensitive);
425+
cm.addOverlay(state.overlay);
426+
if (cm.showMatchesOnScrollbar) {
427+
if (state.annotate) {
428+
state.annotate.clear();
429+
state.annotate = null;
430+
}
431+
state.annotate = cm.showMatchesOnScrollbar(
432+
state.query,
433+
state.caseInsensitive
434+
);
435+
}
436+
437+
var cursor = getSearchCursor(cm, state.query);
438+
cursor.findNext();
439+
var num_match = cm.state.search.annotate.matches.length;
440+
if (num_match == 0) {
441+
cm.display.wrapper.querySelector(
442+
'.CodeMirror-search-results'
443+
).innerText = i18n.t('CodemirrorFindAndReplace.NoResults');
444+
cm.removeOverlay(state.overlay, state.caseInsensitive);
445+
} else {
446+
var next =
447+
cm.state.search.annotate.matches.findIndex((s) => {
448+
return (
449+
s.from.ch === cursor.from().ch && s.from.line === cursor.from().line
450+
);
451+
}) + 1;
452+
var text_match = next + '/' + num_match;
453+
cm.display.wrapper.querySelector(
454+
'.CodeMirror-search-results'
455+
).innerText = text_match;
456+
}
390457
}
391458
}
392459

0 commit comments

Comments
 (0)