Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
malwaredllc
GitHub Repository: malwaredllc/byob
Path: blob/master/web-gui/buildyourownbotnet/assets/js/codemirror/addon/search/search.js
1294 views
1
// Define search commands. Depends on dialog.js or another
2
// implementation of the openDialog method.
3
4
// Replace works a little oddly -- it will do the replace on the next
5
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
6
// replace by making sure the match is no longer selected when hitting
7
// Ctrl-G.
8
9
(function() {
10
function searchOverlay(query, caseInsensitive) {
11
var startChar;
12
if (typeof query == "string") {
13
startChar = query.charAt(0);
14
query = new RegExp("^" + query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"),
15
caseInsensitive ? "i" : "");
16
} else {
17
query = new RegExp("^(?:" + query.source + ")", query.ignoreCase ? "i" : "");
18
}
19
if (typeof query == "string") return {token: function(stream) {
20
if (stream.match(query)) return "searching";
21
stream.next();
22
stream.skipTo(query.charAt(0)) || stream.skipToEnd();
23
}};
24
return {token: function(stream) {
25
if (stream.match(query)) return "searching";
26
while (!stream.eol()) {
27
stream.next();
28
if (startChar)
29
stream.skipTo(startChar) || stream.skipToEnd();
30
if (stream.match(query, false)) break;
31
}
32
}};
33
}
34
35
function SearchState() {
36
this.posFrom = this.posTo = this.query = null;
37
this.overlay = null;
38
}
39
function getSearchState(cm) {
40
return cm.state.search || (cm.state.search = new SearchState());
41
}
42
function queryCaseInsensitive(query) {
43
return typeof query == "string" && query == query.toLowerCase();
44
}
45
function getSearchCursor(cm, query, pos) {
46
// Heuristic: if the query string is all lowercase, do a case insensitive search.
47
return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
48
}
49
function dialog(cm, text, shortText, deflt, f) {
50
if (cm.openDialog) cm.openDialog(text, f, {value: deflt});
51
else f(prompt(shortText, deflt));
52
}
53
function confirmDialog(cm, text, shortText, fs) {
54
if (cm.openConfirm) cm.openConfirm(text, fs);
55
else if (confirm(shortText)) fs[0]();
56
}
57
function parseQuery(query) {
58
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
59
return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query;
60
}
61
var queryDialog =
62
'Search: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
63
function doSearch(cm, rev) {
64
var state = getSearchState(cm);
65
if (state.query) return findNext(cm, rev);
66
dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) {
67
cm.operation(function() {
68
if (!query || state.query) return;
69
state.query = parseQuery(query);
70
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
71
state.overlay = searchOverlay(state.query);
72
cm.addOverlay(state.overlay);
73
state.posFrom = state.posTo = cm.getCursor();
74
findNext(cm, rev);
75
});
76
});
77
}
78
function findNext(cm, rev) {cm.operation(function() {
79
var state = getSearchState(cm);
80
var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
81
if (!cursor.find(rev)) {
82
cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
83
if (!cursor.find(rev)) return;
84
}
85
cm.setSelection(cursor.from(), cursor.to());
86
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
87
state.posFrom = cursor.from(); state.posTo = cursor.to();
88
});}
89
function clearSearch(cm) {cm.operation(function() {
90
var state = getSearchState(cm);
91
if (!state.query) return;
92
state.query = null;
93
cm.removeOverlay(state.overlay);
94
});}
95
96
var replaceQueryDialog =
97
'Replace: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
98
var replacementQueryDialog = 'With: <input type="text" style="width: 10em"/>';
99
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
100
function replace(cm, all) {
101
dialog(cm, replaceQueryDialog, "Replace:", cm.getSelection(), function(query) {
102
if (!query) return;
103
query = parseQuery(query);
104
dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
105
if (all) {
106
cm.operation(function() {
107
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
108
if (typeof query != "string") {
109
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
110
cursor.replace(text.replace(/\$(\d)/, function(_, i) {return match[i];}));
111
} else cursor.replace(text);
112
}
113
});
114
} else {
115
clearSearch(cm);
116
var cursor = getSearchCursor(cm, query, cm.getCursor());
117
var advance = function() {
118
var start = cursor.from(), match;
119
if (!(match = cursor.findNext())) {
120
cursor = getSearchCursor(cm, query);
121
if (!(match = cursor.findNext()) ||
122
(start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
123
}
124
cm.setSelection(cursor.from(), cursor.to());
125
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
126
confirmDialog(cm, doReplaceConfirm, "Replace?",
127
[function() {doReplace(match);}, advance]);
128
};
129
var doReplace = function(match) {
130
cursor.replace(typeof query == "string" ? text :
131
text.replace(/\$(\d)/, function(_, i) {return match[i];}));
132
advance();
133
};
134
advance();
135
}
136
});
137
});
138
}
139
140
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
141
CodeMirror.commands.findNext = doSearch;
142
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
143
CodeMirror.commands.clearSearch = clearSearch;
144
CodeMirror.commands.replace = replace;
145
CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
146
})();
147
148