make multi-section search instantaneous

This commit is contained in:
tophf 2017-12-14 10:35:59 +03:00
parent 49a995afae
commit cc5a254e01

View File

@ -307,7 +307,8 @@ onDOMscriptReady('/codemirror.js').then(() => {
function updateState(cm, newState) { function updateState(cm, newState) {
if (!newState) { if (!newState) {
if (cm.state.search) { const query = (cm.state.search || {}).query;
if (query !== null && query !== undefined) {
return cm.state.search; return cm.state.search;
} }
if (!searchState) { if (!searchState) {
@ -343,23 +344,26 @@ onDOMscriptReady('/codemirror.js').then(() => {
return cm; return cm;
} }
function propagateSearchState(cm) {
if ((cm.state.search || {}).clearSearch) {
cm.execCommand('clearSearch');
}
updateState(cm);
}
function find(activeCM) { function find(activeCM) {
activeCM = focusClosestCM(activeCM); activeCM = focusClosestCM(activeCM);
customizeOpenDialog(activeCM, template.find, function (query) { customizeOpenDialog(activeCM, template.find, function (query) {
this(query); this(query);
searchState = activeCM.state.search; searchState = activeCM.state.search;
const searchOthers = editors.length > 1 && searchState.query; if (!searchState.query ||
editors.forEach(cm => { editors.length === 1 ||
if (cm !== activeCM) { CodeMirror.cmpPos(searchState.posFrom, searchState.posTo)) {
cm.execCommand('clearSearch'); return;
if (searchOthers) {
updateState(cm, searchState);
} }
} editors.forEach(cm => ((cm.state.search || {}).clearSearch = cm !== activeCM));
}); editors.forEach((cm, i) => setTimeout(propagateSearchState, i + 100, cm));
if (searchOthers && CodeMirror.cmpPos(searchState.posFrom, searchState.posTo) === 0) {
findNext(activeCM); findNext(activeCM);
}
}); });
ORIGINAL_COMMAND.find(activeCM); ORIGINAL_COMMAND.find(activeCM);
} }
@ -372,47 +376,54 @@ onDOMscriptReady('/codemirror.js').then(() => {
} }
let pos = activeCM.getCursor(reverse ? 'from' : 'to'); let pos = activeCM.getCursor(reverse ? 'from' : 'to');
// clear the selection, don't move the cursor // clear the selection, don't move the cursor
if (activeCM.somethingSelected()) {
activeCM.setSelection(activeCM.getCursor()); activeCM.setSelection(activeCM.getCursor());
}
const rxQuery = typeof state.query === 'object' const icase = shouldIgnoreCase(state.query);
? state.query : stringAsRegExp(state.query, shouldIgnoreCase(state.query) ? 'i' : ''); const query = searchState.query;
const rxQuery = typeof query === 'object'
? query : stringAsRegExp(query, icase ? 'i' : '');
if ( const total = editors.length;
document.activeElement && if ((!reverse || total === 1 ||
document.activeElement.name === 'applies-value' && (document.activeElement || {}).name === 'applies-value') &&
searchAppliesTo(activeCM) findAppliesTo(activeCM, reverse, rxQuery)) {
) {
return; return;
} }
let cm = activeCM; let cm = activeCM;
for (let i = 0; i < editors.length; i++) { const startIndex = editors.indexOf(cm);
state = updateState(cm); for (let i = 1; i < total; i++) {
if (!cm.hasFocus()) { cm = editors[(startIndex + i * (reverse ? -1 : 1) + total) % total];
pos = reverse ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(0, 0); pos = reverse ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(0, 0);
} const searchCursor = cm.getSearchCursor(query, pos, icase);
const searchCursor = cm.getSearchCursor(state.query, pos, shouldIgnoreCase(state.query));
if (searchCursor.find(reverse)) { if (searchCursor.find(reverse)) {
if (editors.length > 1) { if (total > 1) {
makeSectionVisible(cm); makeSectionVisible(cm);
cm.focus(); cm.focus();
} }
if ((cm.state.search || {}).clearSearch) {
cm.execCommand('clearSearch');
}
state = updateState(cm);
// speedup the original findNext // speedup the original findNext
state.posFrom = reverse ? searchCursor.to() : searchCursor.from(); state.posFrom = reverse ? searchCursor.to() : searchCursor.from();
state.posTo = CodeMirror.Pos(state.posFrom.line, state.posFrom.ch); state.posTo = Object.assign({}, state.posFrom);
ORIGINAL_COMMAND[reverse ? 'findPrev' : 'findNext'](cm); setTimeout(ORIGINAL_COMMAND[reverse ? 'findPrev' : 'findNext'], 0, cm);
return; return;
} else if (!reverse && searchAppliesTo(cm)) { } else if (!reverse && findAppliesTo(cm, reverse, rxQuery)) {
return; return;
} }
cm = editors[(editors.indexOf(cm) + (reverse ? -1 + editors.length : 1)) % editors.length]; cm = editors[(startIndex + (i + 1) * (reverse ? -1 : 1) + total) % total];
if (reverse && searchAppliesTo(cm)) { if (reverse && findAppliesTo(cm, reverse, rxQuery)) {
return; return;
} }
} }
// nothing found so far, so call the original search with wrap-around // nothing found so far, so call the original search with wrap-around
ORIGINAL_COMMAND[reverse ? 'findPrev' : 'findNext'](activeCM); ORIGINAL_COMMAND[reverse ? 'findPrev' : 'findNext'](activeCM);
}
function searchAppliesTo(cm) { function findAppliesTo(cm, reverse, rxQuery) {
let inputs = $$('.applies-value', cm.getSection()); let inputs = $$('.applies-value', cm.getSection());
if (reverse) { if (reverse) {
inputs = inputs.reverse(); inputs = inputs.reverse();
@ -433,7 +444,6 @@ onDOMscriptReady('/codemirror.js').then(() => {
} }
}); });
} }
}
function findPrev(cm) { function findPrev(cm) {
findNext(cm, true); findNext(cm, true);