Zeile 18 | Zeile 18 |
---|
mod(CodeMirror); })(function(CodeMirror) { "use strict";
|
mod(CodeMirror); })(function(CodeMirror) { "use strict";
|
|
|
function searchOverlay(query, caseInsensitive) { if (typeof query == "string") query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
| function searchOverlay(query, caseInsensitive) { if (typeof query == "string") query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
|
Zeile 28 | Zeile 29 |
---|
query.lastIndex = stream.pos; var match = query.exec(stream.string); if (match && match.index == stream.pos) {
|
query.lastIndex = stream.pos; var match = query.exec(stream.string); if (match && match.index == stream.pos) {
|
stream.pos += match[0].length;
| stream.pos += match[0].length || 1;
|
return "searching"; } else if (match) { stream.pos = match.index;
| return "searching"; } else if (match) { stream.pos = match.index;
|
Zeile 39 | Zeile 40 |
---|
}
function SearchState() {
|
}
function SearchState() {
|
this.posFrom = this.posTo = this.query = null;
| this.posFrom = this.posTo = this.lastQuery = this.query = null;
|
this.overlay = null; }
|
this.overlay = null; }
|
|
|
function getSearchState(cm) { return cm.state.search || (cm.state.search = new SearchState());
|
function getSearchState(cm) { return cm.state.search || (cm.state.search = new SearchState());
|
}
| }
|
function queryCaseInsensitive(query) { return typeof query == "string" && query == query.toLowerCase(); }
|
function queryCaseInsensitive(query) { return typeof query == "string" && query == query.toLowerCase(); }
|
|
|
function getSearchCursor(cm, query, pos) { // Heuristic: if the query string is all lowercase, do a case insensitive search.
|
function getSearchCursor(cm, query, pos) { // Heuristic: if the query string is all lowercase, do a case insensitive search.
|
return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
| return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true});
|
}
|
}
|
| function persistentDialog(cm, text, deflt, onEnter, onKeyDown) { cm.openDialog(text, onEnter, { value: deflt, selectValueOnOpen: true, closeOnEnter: false, onClose: function() { clearSearch(cm); }, onKeyDown: onKeyDown }); }
|
function dialog(cm, text, shortText, deflt, f) {
|
function dialog(cm, text, shortText, deflt, f) {
|
if (cm.openDialog) cm.openDialog(text, f, {value: deflt});
| if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
|
else f(prompt(shortText, deflt));
|
else f(prompt(shortText, deflt));
|
}
| }
|
function confirmDialog(cm, text, shortText, fs) { if (cm.openConfirm) cm.openConfirm(text, fs); else if (confirm(shortText)) fs[0](); }
|
function confirmDialog(cm, text, shortText, fs) { if (cm.openConfirm) cm.openConfirm(text, fs); else if (confirm(shortText)) fs[0](); }
|
| function parseString(string) { return string.replace(/\\(.)/g, function(_, ch) { if (ch == "n") return "\n" if (ch == "r") return "\r" return ch }) }
|
function parseQuery(query) { var isRE = query.match(/^\/(.*)\/([a-z]*)$/); if (isRE) { try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); } catch(e) {} // Not a regular expression after all, do a string search
|
function parseQuery(query) { var isRE = query.match(/^\/(.*)\/([a-z]*)$/); if (isRE) { try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); } catch(e) {} // Not a regular expression after all, do a string search
|
| } else { query = parseString(query)
|
} if (typeof query == "string" ? query == "" : query.test("")) query = /x^/; return query; }
|
} if (typeof query == "string" ? query == "" : query.test("")) query = /x^/; return query; }
|
|
|
var queryDialog =
|
var queryDialog =
|
'Search: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>'; function doSearch(cm, rev) { var state = getSearchState(cm);
| '<span class="CodeMirror-search-label">Search:</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
function startSearch(cm, state, query) { state.queryText = query; state.query = parseQuery(query); cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query)); state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query)); cm.addOverlay(state.overlay); if (cm.showMatchesOnScrollbar) { if (state.annotate) { state.annotate.clear(); state.annotate = null; } state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query)); } }
function doSearch(cm, rev, persistent, immediate) { var state = getSearchState(cm);
|
if (state.query) return findNext(cm, rev);
|
if (state.query) return findNext(cm, rev);
|
dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) { cm.operation(function() { if (!query || state.query) return; state.query = parseQuery(query); cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query)); state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query)); cm.addOverlay(state.overlay); if (cm.showMatchesOnScrollbar) { if (state.annotate) { state.annotate.clear(); state.annotate = null; } state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
| var q = cm.getSelection() || state.lastQuery; if (q instanceof RegExp && q.source == "x^") q = null if (persistent && cm.openDialog) { var hiding = null var searchNext = function(query, event) { CodeMirror.e_stop(event); if (!query) return; if (query != state.queryText) { startSearch(cm, state, query); state.posFrom = state.posTo = cm.getCursor();
|
}
|
}
|
state.posFrom = state.posTo = cm.getCursor();
| if (hiding) hiding.style.opacity = 1 findNext(cm, event.shiftKey, function(_, to) { var dialog if (to.line < 3 && document.querySelector && (dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) && dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top) (hiding = dialog).style.opacity = .4 }) }; persistentDialog(cm, queryDialog, q, searchNext, function(event, query) { var keyName = CodeMirror.keyName(event) var extra = cm.getOption('extraKeys'), cmd = (extra && extra[keyName]) || CodeMirror.keyMap[cm.getOption("keyMap")][keyName] if (cmd == "findNext" || cmd == "findPrev" || cmd == "findPersistentNext" || cmd == "findPersistentPrev") { CodeMirror.e_stop(event); startSearch(cm, getSearchState(cm), query); cm.execCommand(cmd); } else if (cmd == "find" || cmd == "findPersistent") { CodeMirror.e_stop(event); searchNext(query, event); } }); if (immediate && q) { startSearch(cm, state, q);
|
findNext(cm, rev);
|
findNext(cm, rev);
|
| } } else { dialog(cm, queryDialog, "Search for:", q, function(query) { if (query && !state.query) cm.operation(function() { startSearch(cm, state, query); state.posFrom = state.posTo = cm.getCursor(); findNext(cm, rev); });
|
});
|
});
|
});
| }
|
}
|
}
|
function findNext(cm, rev) {cm.operation(function() {
| function findNext(cm, rev, callback) {cm.operation(function() {
|
var state = getSearchState(cm); var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); if (!cursor.find(rev)) {
| var state = getSearchState(cm); var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); if (!cursor.find(rev)) {
|
Zeile 99 | Zeile 172 |
---|
if (!cursor.find(rev)) return; } cm.setSelection(cursor.from(), cursor.to());
|
if (!cursor.find(rev)) return; } cm.setSelection(cursor.from(), cursor.to());
|
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
| cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
|
state.posFrom = cursor.from(); state.posTo = cursor.to();
|
state.posFrom = cursor.from(); state.posTo = cursor.to();
|
| if (callback) callback(cursor.from(), cursor.to())
|
});}
|
});}
|
|
|
function clearSearch(cm) {cm.operation(function() { var state = getSearchState(cm);
|
function clearSearch(cm) {cm.operation(function() { var state = getSearchState(cm);
|
| state.lastQuery = state.query;
|
if (!state.query) return;
|
if (!state.query) return;
|
state.query = null;
| state.query = state.queryText = null;
|
cm.removeOverlay(state.overlay); if (state.annotate) { state.annotate.clear(); state.annotate = null; } });}
var replaceQueryDialog =
|
cm.removeOverlay(state.overlay); if (state.annotate) { state.annotate.clear(); state.annotate = null; } });}
var replaceQueryDialog =
|
'Replace: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>'; var replacementQueryDialog = 'With: <input type="text" style="width: 10em" class="CodeMirror-search-field"/>'; var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
| ' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>'; var replacementQueryDialog = '<span class="CodeMirror-search-label">With:</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/>'; var doReplaceConfirm = '<span class="CodeMirror-search-label">Replace?</span> <button>Yes</button> <button>No</button> <button>All</button> <button>Stop</button>';
function replaceAll(cm, query, text) { cm.operation(function() { for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { if (typeof query != "string") { var match = cm.getRange(cursor.from(), cursor.to()).match(query); cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];})); } else cursor.replace(text); } }); }
|
function replace(cm, all) { if (cm.getOption("readOnly")) return;
|
function replace(cm, all) { if (cm.getOption("readOnly")) return;
|
dialog(cm, replaceQueryDialog, "Replace:", cm.getSelection(), function(query) {
| var query = cm.getSelection() || getSearchState(cm).lastQuery; var dialogText = '<span class="CodeMirror-search-label">' + (all ? 'Replace all:' : 'Replace:') + '</span>'; dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) {
|
if (!query) return; query = parseQuery(query); dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
|
if (!query) return; query = parseQuery(query); dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
|
| text = parseString(text)
|
if (all) {
|
if (all) {
|
cm.operation(function() { for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { if (typeof query != "string") { var match = cm.getRange(cursor.from(), cursor.to()).match(query); cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];})); } else cursor.replace(text); } });
| replaceAll(cm, query, text)
|
} else { clearSearch(cm);
|
} else { clearSearch(cm);
|
var cursor = getSearchCursor(cm, query, cm.getCursor());
| var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
|
var advance = function() { var start = cursor.from(), match; if (!(match = cursor.findNext())) {
| var advance = function() { var start = cursor.from(), match; if (!(match = cursor.findNext())) {
|
Zeile 142 | Zeile 226 |
---|
cm.setSelection(cursor.from(), cursor.to()); cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); confirmDialog(cm, doReplaceConfirm, "Replace?",
|
cm.setSelection(cursor.from(), cursor.to()); cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); confirmDialog(cm, doReplaceConfirm, "Replace?",
|
[function() {doReplace(match);}, advance]);
| [function() {doReplace(match);}, advance, function() {replaceAll(cm, query, text)}]);
|
}; var doReplace = function(match) { cursor.replace(typeof query == "string" ? text :
| }; var doReplace = function(match) { cursor.replace(typeof query == "string" ? text :
|
Zeile 156 | Zeile 241 |
---|
}
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
|
}
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
|
| CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);}; CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);}; CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);};
|
CodeMirror.commands.findNext = doSearch; CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; CodeMirror.commands.clearSearch = clearSearch;
| CodeMirror.commands.findNext = doSearch; CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; CodeMirror.commands.clearSearch = clearSearch;
|