##// END OF EJS Templates
avoid jsonlib returning Decimal...
avoid jsonlib returning Decimal The only functional change is that Decimal objects will no longer come out of jsonlib, but the code that handles jsonlib's two minor differences wrt other json libraries is now a bit clearer and better documented. Relevant test is added.

File last commit:

r5970:b6bb1663
r6060:4506273c
Show More
search.js
114 lines | 4.6 KiB | application/javascript | JavascriptLexer
// Define search commands. Depends on dialog.js or another
// implementation of the openDialog method.
// Replace works a little oddly -- it will do the replace on the next
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
// replace by making sure the match is no longer selected when hitting
// Ctrl-G.
(function() {
function SearchState() {
this.posFrom = this.posTo = this.query = null;
this.marked = [];
}
function getSearchState(cm) {
return cm._searchState || (cm._searchState = new SearchState());
}
function dialog(cm, text, shortText, f) {
if (cm.openDialog) cm.openDialog(text, f);
else f(prompt(shortText, ""));
}
function confirmDialog(cm, text, shortText, fs) {
if (cm.openConfirm) cm.openConfirm(text, fs);
else if (confirm(shortText)) fs[0]();
}
function parseQuery(query) {
var isRE = query.match(/^\/(.*)\/$/);
return isRE ? new RegExp(isRE[1]) : query;
}
var queryDialog =
'Search: <input type="text" style="width: 10em"> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
function doSearch(cm, rev) {
var state = getSearchState(cm);
if (state.query) return findNext(cm, rev);
dialog(cm, queryDialog, "Search for:", function(query) {
cm.operation(function() {
if (!query || state.query) return;
state.query = parseQuery(query);
if (cm.lineCount() < 2000) { // This is too expensive on big documents.
for (var cursor = cm.getSearchCursor(query); cursor.findNext();)
state.marked.push(cm.markText(cursor.from(), cursor.to(), "CodeMirror-searching"));
}
state.posFrom = state.posTo = cm.getCursor();
findNext(cm, rev);
});
});
}
function findNext(cm, rev) {cm.operation(function() {
var state = getSearchState(cm);
var cursor = cm.getSearchCursor(state.query, rev ? state.posFrom : state.posTo);
if (!cursor.find(rev)) {
cursor = cm.getSearchCursor(state.query, rev ? {line: cm.lineCount() - 1} : {line: 0, ch: 0});
if (!cursor.find(rev)) return;
}
cm.setSelection(cursor.from(), cursor.to());
state.posFrom = cursor.from(); state.posTo = cursor.to();
})}
function clearSearch(cm) {cm.operation(function() {
var state = getSearchState(cm);
if (!state.query) return;
state.query = null;
for (var i = 0; i < state.marked.length; ++i) state.marked[i].clear();
state.marked.length = 0;
})}
var replaceQueryDialog =
'Replace: <input type="text" style="width: 10em"> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
var replacementQueryDialog = 'With: <input type="text" style="width: 10em">';
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
function replace(cm, all) {
dialog(cm, replaceQueryDialog, "Replace:", function(query) {
if (!query) return;
query = parseQuery(query);
dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
if (all) {
cm.operation(function() {
for (var cursor = cm.getSearchCursor(query); cursor.findNext();) {
if (typeof query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
cursor.replace(text.replace(/\$(\d)/, function(w, i) {return match[i];}));
} else cursor.replace(text);
}
});
} else {
clearSearch(cm);
var cursor = cm.getSearchCursor(query, cm.getCursor());
function advance() {
var start = cursor.from(), match;
if (!(match = cursor.findNext())) {
cursor = cm.getSearchCursor(query);
if (!(match = cursor.findNext()) ||
(cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
}
cm.setSelection(cursor.from(), cursor.to());
confirmDialog(cm, doReplaceConfirm, "Replace?",
[function() {doReplace(match);}, advance]);
}
function doReplace(match) {
cursor.replace(typeof query == "string" ? text :
text.replace(/\$(\d)/, function(w, i) {return match[i];}));
advance();
}
advance();
}
});
});
}
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
CodeMirror.commands.findNext = doSearch;
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
CodeMirror.commands.clearSearch = clearSearch;
CodeMirror.commands.replace = replace;
CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
})();