From 99f904adcc37d93c90defcd8ce898598e25be212 Mon Sep 17 00:00:00 2001 From: Hugues Hiegel Date: Wed, 11 Mar 2015 16:55:04 +0100 Subject: Lot of plugins --- .../lib/CodeMirror-2.3/lib/util/search.js | 118 +++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 codemirror_ui/lib/CodeMirror-2.3/lib/util/search.js (limited to 'codemirror_ui/lib/CodeMirror-2.3/lib/util/search.js') diff --git a/codemirror_ui/lib/CodeMirror-2.3/lib/util/search.js b/codemirror_ui/lib/CodeMirror-2.3/lib/util/search.js new file mode 100644 index 0000000..c5a2bcc --- /dev/null +++ b/codemirror_ui/lib/CodeMirror-2.3/lib/util/search.js @@ -0,0 +1,118 @@ +// 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 getSearchCursor(cm, query, pos) { + // Heuristic: if the query string is all lowercase, do a case insensitive search. + return cm.getSearchCursor(query, pos, typeof query == "string" && query == query.toLowerCase()); + } + 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(/^\/(.*)\/([a-z]*)$/); + return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query; + } + var queryDialog = + 'Search: (Use /re/ syntax for regexp search)'; + 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 = getSearchCursor(cm, 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 = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); + if (!cursor.find(rev)) { + cursor = getSearchCursor(cm, 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: (Use /re/ syntax for regexp search)'; + var replacementQueryDialog = 'With: '; + var doReplaceConfirm = "Replace? "; + 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.compoundChange(function() { 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)/, function(w, i) {return match[i];})); + } else cursor.replace(text); + } + })}); + } else { + clearSearch(cm); + var cursor = getSearchCursor(cm, query, cm.getCursor()); + function advance() { + var start = cursor.from(), match; + if (!(match = cursor.findNext())) { + cursor = getSearchCursor(cm, query); + if (!(match = cursor.findNext()) || + (start && 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);}; +})(); -- cgit v1.2.3