@standardnotes/markdown-minimal 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +3 -0
- package/CHANGELOG.md +63 -0
- package/Gruntfile.js +125 -0
- package/README.md +26 -0
- package/dist/app.css +143 -0
- package/dist/app.css.map +1 -0
- package/dist/app.js +118 -0
- package/dist/app.js.map +1 -0
- package/dist/dist.css +490 -0
- package/dist/dist.js +11214 -0
- package/dist/lib.js +11096 -0
- package/dist/sn-codemirror-search/dialog/dialog.css +46 -0
- package/dist/sn-codemirror-search/dialog/dialog.js +161 -0
- package/dist/sn-codemirror-search/search.js +258 -0
- package/dist/sn-codemirror-search/searchcursor.js +293 -0
- package/ext.json +8 -0
- package/index.html +23 -0
- package/min-markdown.jpg +0 -0
- package/package.json +41 -0
- package/src/main.js +110 -0
- package/src/main.scss +151 -0
- package/vendor/addon/modes/overlay.js +90 -0
- package/vendor/mark-selection.js +119 -0
- package/vendor/modes/gfm/gfm.js +130 -0
- package/vendor/modes/markdown/markdown.js +884 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
.CodeMirror-dialog {
|
|
2
|
+
position: absolute;
|
|
3
|
+
left: 0; right: 0;
|
|
4
|
+
background: var(--sn-stylekit-contrast-background-color);
|
|
5
|
+
z-index: 15;
|
|
6
|
+
padding: .3em .8em;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
color: inherit;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.CodeMirror-dialog-top {
|
|
12
|
+
border-bottom: 1px solid var(--sn-stylekit-border-color);
|
|
13
|
+
top: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.CodeMirror-dialog-bottom {
|
|
17
|
+
border-top: 1px solid var(--sn-stylekit-border-color);
|
|
18
|
+
bottom: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.CodeMirror-search-label {
|
|
22
|
+
font-size: var(--sn-stylekit-base-font-size);
|
|
23
|
+
font-weight: bold;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.CodeMirror-search-hint {
|
|
27
|
+
font-size: var(--sn-stylekit-base-font-size);
|
|
28
|
+
display: none;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.CodeMirror-search-field {
|
|
32
|
+
width: 65% !important;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.CodeMirror-dialog input {
|
|
36
|
+
border: none;
|
|
37
|
+
outline: none;
|
|
38
|
+
background: transparent;
|
|
39
|
+
color: var(--sn-stylekit-contrast-foreground-color);
|
|
40
|
+
font-size: var(--sn-stylekit-base-font-size);
|
|
41
|
+
font-family: monospace;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.CodeMirror-dialog button {
|
|
45
|
+
font-size: 70%;
|
|
46
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
2
|
+
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
3
|
+
|
|
4
|
+
// Open simple dialogs on top of an editor. Relies on dialog.css.
|
|
5
|
+
|
|
6
|
+
(function(mod) {
|
|
7
|
+
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
8
|
+
mod(require("../../lib/codemirror"));
|
|
9
|
+
else if (typeof define == "function" && define.amd) // AMD
|
|
10
|
+
define(["../../lib/codemirror"], mod);
|
|
11
|
+
else // Plain browser env
|
|
12
|
+
mod(CodeMirror);
|
|
13
|
+
})(function(CodeMirror) {
|
|
14
|
+
function dialogDiv(cm, template, bottom) {
|
|
15
|
+
var wrap = cm.getWrapperElement();
|
|
16
|
+
var dialog;
|
|
17
|
+
dialog = wrap.appendChild(document.createElement("div"));
|
|
18
|
+
if (bottom)
|
|
19
|
+
dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
|
|
20
|
+
else
|
|
21
|
+
dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
|
|
22
|
+
|
|
23
|
+
if (typeof template == "string") {
|
|
24
|
+
dialog.innerHTML = template;
|
|
25
|
+
} else { // Assuming it's a detached DOM element.
|
|
26
|
+
dialog.appendChild(template);
|
|
27
|
+
}
|
|
28
|
+
CodeMirror.addClass(wrap, 'dialog-opened');
|
|
29
|
+
return dialog;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function closeNotification(cm, newVal) {
|
|
33
|
+
if (cm.state.currentNotificationClose)
|
|
34
|
+
cm.state.currentNotificationClose();
|
|
35
|
+
cm.state.currentNotificationClose = newVal;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
CodeMirror.defineExtension("openDialog", function(template, callback, options) {
|
|
39
|
+
if (!options) options = {};
|
|
40
|
+
|
|
41
|
+
closeNotification(this, null);
|
|
42
|
+
|
|
43
|
+
var dialog = dialogDiv(this, template, options.bottom);
|
|
44
|
+
var closed = false, me = this;
|
|
45
|
+
function close(newVal) {
|
|
46
|
+
if (typeof newVal == 'string') {
|
|
47
|
+
inp.value = newVal;
|
|
48
|
+
} else {
|
|
49
|
+
if (closed) return;
|
|
50
|
+
closed = true;
|
|
51
|
+
CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
|
|
52
|
+
dialog.parentNode.removeChild(dialog);
|
|
53
|
+
me.focus();
|
|
54
|
+
|
|
55
|
+
if (options.onClose) options.onClose(dialog);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
var inp = dialog.getElementsByTagName("input")[0], button;
|
|
60
|
+
if (inp) {
|
|
61
|
+
inp.focus();
|
|
62
|
+
|
|
63
|
+
if (options.value) {
|
|
64
|
+
inp.value = options.value;
|
|
65
|
+
if (options.selectValueOnOpen !== false) {
|
|
66
|
+
inp.select();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (options.onInput)
|
|
71
|
+
CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
|
|
72
|
+
if (options.onKeyUp)
|
|
73
|
+
CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
|
|
74
|
+
|
|
75
|
+
CodeMirror.on(inp, "keydown", function(e) {
|
|
76
|
+
if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
|
|
77
|
+
if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
|
|
78
|
+
inp.blur();
|
|
79
|
+
CodeMirror.e_stop(e);
|
|
80
|
+
close();
|
|
81
|
+
}
|
|
82
|
+
if (e.keyCode == 13) callback(inp.value, e);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
|
|
86
|
+
} else if (button = dialog.getElementsByTagName("button")[0]) {
|
|
87
|
+
CodeMirror.on(button, "click", function() {
|
|
88
|
+
close();
|
|
89
|
+
me.focus();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
|
|
93
|
+
|
|
94
|
+
button.focus();
|
|
95
|
+
}
|
|
96
|
+
return close;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
|
|
100
|
+
closeNotification(this, null);
|
|
101
|
+
var dialog = dialogDiv(this, template, options && options.bottom);
|
|
102
|
+
var buttons = dialog.getElementsByTagName("button");
|
|
103
|
+
var closed = false, me = this, blurring = 1;
|
|
104
|
+
function close() {
|
|
105
|
+
if (closed) return;
|
|
106
|
+
closed = true;
|
|
107
|
+
CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
|
|
108
|
+
dialog.parentNode.removeChild(dialog);
|
|
109
|
+
me.focus();
|
|
110
|
+
}
|
|
111
|
+
buttons[0].focus();
|
|
112
|
+
for (var i = 0; i < buttons.length; ++i) {
|
|
113
|
+
var b = buttons[i];
|
|
114
|
+
(function(callback) {
|
|
115
|
+
CodeMirror.on(b, "click", function(e) {
|
|
116
|
+
CodeMirror.e_preventDefault(e);
|
|
117
|
+
close();
|
|
118
|
+
if (callback) callback(me);
|
|
119
|
+
});
|
|
120
|
+
})(callbacks[i]);
|
|
121
|
+
CodeMirror.on(b, "blur", function() {
|
|
122
|
+
--blurring;
|
|
123
|
+
setTimeout(function() { if (blurring <= 0) close(); }, 200);
|
|
124
|
+
});
|
|
125
|
+
CodeMirror.on(b, "focus", function() { ++blurring; });
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
/*
|
|
130
|
+
* openNotification
|
|
131
|
+
* Opens a notification, that can be closed with an optional timer
|
|
132
|
+
* (default 5000ms timer) and always closes on click.
|
|
133
|
+
*
|
|
134
|
+
* If a notification is opened while another is opened, it will close the
|
|
135
|
+
* currently opened one and open the new one immediately.
|
|
136
|
+
*/
|
|
137
|
+
CodeMirror.defineExtension("openNotification", function(template, options) {
|
|
138
|
+
closeNotification(this, close);
|
|
139
|
+
var dialog = dialogDiv(this, template, options && options.bottom);
|
|
140
|
+
var closed = false, doneTimer;
|
|
141
|
+
var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
|
|
142
|
+
|
|
143
|
+
function close() {
|
|
144
|
+
if (closed) return;
|
|
145
|
+
closed = true;
|
|
146
|
+
clearTimeout(doneTimer);
|
|
147
|
+
CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
|
|
148
|
+
dialog.parentNode.removeChild(dialog);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
CodeMirror.on(dialog, 'click', function(e) {
|
|
152
|
+
CodeMirror.e_preventDefault(e);
|
|
153
|
+
close();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
if (duration)
|
|
157
|
+
doneTimer = setTimeout(close, duration);
|
|
158
|
+
|
|
159
|
+
return close;
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
2
|
+
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
3
|
+
|
|
4
|
+
// Define search commands. Depends on dialog.js or another
|
|
5
|
+
// implementation of the openDialog method.
|
|
6
|
+
|
|
7
|
+
// Replace works a little oddly -- it will do the replace on the next
|
|
8
|
+
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
|
|
9
|
+
// replace by making sure the match is no longer selected when hitting
|
|
10
|
+
// Ctrl-G.
|
|
11
|
+
|
|
12
|
+
(function(mod) {
|
|
13
|
+
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
14
|
+
mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog"));
|
|
15
|
+
else if (typeof define == "function" && define.amd) // AMD
|
|
16
|
+
define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod);
|
|
17
|
+
else // Plain browser env
|
|
18
|
+
mod(CodeMirror);
|
|
19
|
+
})(function(CodeMirror) {
|
|
20
|
+
"use strict";
|
|
21
|
+
|
|
22
|
+
function searchOverlay(query, caseInsensitive) {
|
|
23
|
+
if (typeof query == "string")
|
|
24
|
+
query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
|
|
25
|
+
else if (!query.global)
|
|
26
|
+
query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");
|
|
27
|
+
|
|
28
|
+
return {token: function(stream) {
|
|
29
|
+
query.lastIndex = stream.pos;
|
|
30
|
+
var match = query.exec(stream.string);
|
|
31
|
+
if (match && match.index == stream.pos) {
|
|
32
|
+
stream.pos += match[0].length || 1;
|
|
33
|
+
return "searching";
|
|
34
|
+
} else if (match) {
|
|
35
|
+
stream.pos = match.index;
|
|
36
|
+
} else {
|
|
37
|
+
stream.skipToEnd();
|
|
38
|
+
}
|
|
39
|
+
}};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function SearchState() {
|
|
43
|
+
this.posFrom = this.posTo = this.lastQuery = this.query = null;
|
|
44
|
+
this.overlay = null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getSearchState(cm) {
|
|
48
|
+
return cm.state.search || (cm.state.search = new SearchState());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function queryCaseInsensitive(query) {
|
|
52
|
+
return typeof query == "string" && query == query.toLowerCase();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getSearchCursor(cm, query, pos) {
|
|
56
|
+
// Heuristic: if the query string is all lowercase, do a case insensitive search.
|
|
57
|
+
return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function persistentDialog(cm, text, deflt, onEnter, onKeyDown) {
|
|
61
|
+
cm.openDialog(text, onEnter, {
|
|
62
|
+
value: deflt,
|
|
63
|
+
selectValueOnOpen: true,
|
|
64
|
+
closeOnEnter: false,
|
|
65
|
+
onClose: function() { clearSearch(cm); },
|
|
66
|
+
onKeyDown: onKeyDown
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function dialog(cm, text, shortText, deflt, f) {
|
|
71
|
+
if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
|
|
72
|
+
else f(prompt(shortText, deflt));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function confirmDialog(cm, text, shortText, fs) {
|
|
76
|
+
if (cm.openConfirm) cm.openConfirm(text, fs);
|
|
77
|
+
else if (confirm(shortText)) fs[0]();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function parseString(string) {
|
|
81
|
+
return string.replace(/\\(.)/g, function(_, ch) {
|
|
82
|
+
if (ch == "n") return "\n"
|
|
83
|
+
if (ch == "r") return "\r"
|
|
84
|
+
return ch
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function parseQuery(query) {
|
|
89
|
+
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
|
|
90
|
+
if (isRE) {
|
|
91
|
+
try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
|
|
92
|
+
catch(e) {} // Not a regular expression after all, do a string search
|
|
93
|
+
} else {
|
|
94
|
+
query = parseString(query)
|
|
95
|
+
}
|
|
96
|
+
if (typeof query == "string" ? query == "" : query.test(""))
|
|
97
|
+
query = /x^/;
|
|
98
|
+
return query;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function startSearch(cm, state, query) {
|
|
102
|
+
state.queryText = query;
|
|
103
|
+
state.query = parseQuery(query);
|
|
104
|
+
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
|
|
105
|
+
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
|
|
106
|
+
cm.addOverlay(state.overlay);
|
|
107
|
+
if (cm.showMatchesOnScrollbar) {
|
|
108
|
+
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
|
|
109
|
+
state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function doSearch(cm, rev, persistent, immediate) {
|
|
114
|
+
var state = getSearchState(cm);
|
|
115
|
+
if (state.query) return findNext(cm, rev);
|
|
116
|
+
var q = cm.getSelection() || state.lastQuery;
|
|
117
|
+
if (q instanceof RegExp && q.source == "x^") q = null
|
|
118
|
+
if (persistent && cm.openDialog) {
|
|
119
|
+
var hiding = null
|
|
120
|
+
var searchNext = function(query, event) {
|
|
121
|
+
CodeMirror.e_stop(event);
|
|
122
|
+
if (!query) return;
|
|
123
|
+
if (query != state.queryText) {
|
|
124
|
+
startSearch(cm, state, query);
|
|
125
|
+
state.posFrom = state.posTo = cm.getCursor();
|
|
126
|
+
}
|
|
127
|
+
if (hiding) hiding.style.opacity = 1
|
|
128
|
+
findNext(cm, event.shiftKey, function(_, to) {
|
|
129
|
+
var dialog
|
|
130
|
+
if (to.line < 3 && document.querySelector &&
|
|
131
|
+
(dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) &&
|
|
132
|
+
dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top)
|
|
133
|
+
(hiding = dialog).style.opacity = .4
|
|
134
|
+
})
|
|
135
|
+
};
|
|
136
|
+
persistentDialog(cm, getQueryDialog(cm), q, searchNext, function(event, query) {
|
|
137
|
+
var keyName = CodeMirror.keyName(event)
|
|
138
|
+
var extra = cm.getOption('extraKeys'), cmd = (extra && extra[keyName]) || CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
|
|
139
|
+
if (cmd == "findNext" || cmd == "findPrev" ||
|
|
140
|
+
cmd == "findPersistentNext" || cmd == "findPersistentPrev") {
|
|
141
|
+
CodeMirror.e_stop(event);
|
|
142
|
+
startSearch(cm, getSearchState(cm), query);
|
|
143
|
+
cm.execCommand(cmd);
|
|
144
|
+
} else if (cmd == "find" || cmd == "findPersistent") {
|
|
145
|
+
CodeMirror.e_stop(event);
|
|
146
|
+
searchNext(query, event);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
if (immediate && q) {
|
|
150
|
+
startSearch(cm, state, q);
|
|
151
|
+
findNext(cm, rev);
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
dialog(cm, getQueryDialog(cm), "Search for:", q, function(query) {
|
|
155
|
+
if (query && !state.query) cm.operation(function() {
|
|
156
|
+
startSearch(cm, state, query);
|
|
157
|
+
state.posFrom = state.posTo = cm.getCursor();
|
|
158
|
+
findNext(cm, rev);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function findNext(cm, rev, callback) {cm.operation(function() {
|
|
165
|
+
var state = getSearchState(cm);
|
|
166
|
+
var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
|
|
167
|
+
if (!cursor.find(rev)) {
|
|
168
|
+
cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
|
|
169
|
+
if (!cursor.find(rev)) return;
|
|
170
|
+
}
|
|
171
|
+
cm.setSelection(cursor.from(), cursor.to());
|
|
172
|
+
cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
|
|
173
|
+
state.posFrom = cursor.from(); state.posTo = cursor.to();
|
|
174
|
+
if (callback) callback(cursor.from(), cursor.to())
|
|
175
|
+
});}
|
|
176
|
+
|
|
177
|
+
function clearSearch(cm) {cm.operation(function() {
|
|
178
|
+
var state = getSearchState(cm);
|
|
179
|
+
state.lastQuery = state.query;
|
|
180
|
+
if (!state.query) return;
|
|
181
|
+
state.query = state.queryText = null;
|
|
182
|
+
cm.removeOverlay(state.overlay);
|
|
183
|
+
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
|
|
184
|
+
});}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
function getQueryDialog(cm) {
|
|
188
|
+
return '<span class="CodeMirror-search-label">' + cm.phrase("Search:") + '</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">' + cm.phrase("(Use /re/ syntax for regexp search)") + '</span>';
|
|
189
|
+
}
|
|
190
|
+
function getReplaceQueryDialog(cm) {
|
|
191
|
+
return ' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">' + cm.phrase("(Use /re/ syntax for regexp search)") + '</span>';
|
|
192
|
+
}
|
|
193
|
+
function getReplacementQueryDialog(cm) {
|
|
194
|
+
return '<span class="CodeMirror-search-label">' + cm.phrase("With:") + '</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
|
|
195
|
+
}
|
|
196
|
+
function getDoReplaceConfirm(cm) {
|
|
197
|
+
return '<span class="CodeMirror-search-label">' + cm.phrase("Replace?") + '</span> <button>' + cm.phrase("Yes") + '</button> <button>' + cm.phrase("No") + '</button> <button>' + cm.phrase("All") + '</button> <button>' + cm.phrase("Stop") + '</button> ';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function replaceAll(cm, query, text) {
|
|
201
|
+
cm.operation(function() {
|
|
202
|
+
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
|
|
203
|
+
if (typeof query != "string") {
|
|
204
|
+
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
|
|
205
|
+
cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
|
|
206
|
+
} else cursor.replace(text);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function replace(cm, all) {
|
|
212
|
+
if (cm.getOption("readOnly")) return;
|
|
213
|
+
var query = cm.getSelection() || getSearchState(cm).lastQuery;
|
|
214
|
+
var dialogText = '<span class="CodeMirror-search-label">' + (all ? cm.phrase("Replace all:") : cm.phrase("Replace:")) + '</span>';
|
|
215
|
+
dialog(cm, dialogText + getReplaceQueryDialog(cm), dialogText, query, function(query) {
|
|
216
|
+
if (!query) return;
|
|
217
|
+
query = parseQuery(query);
|
|
218
|
+
dialog(cm, getReplacementQueryDialog(cm), cm.phrase("Replace with:"), "", function(text) {
|
|
219
|
+
text = parseString(text)
|
|
220
|
+
if (all) {
|
|
221
|
+
replaceAll(cm, query, text)
|
|
222
|
+
} else {
|
|
223
|
+
clearSearch(cm);
|
|
224
|
+
var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
|
|
225
|
+
var advance = function() {
|
|
226
|
+
var start = cursor.from(), match;
|
|
227
|
+
if (!(match = cursor.findNext())) {
|
|
228
|
+
cursor = getSearchCursor(cm, query);
|
|
229
|
+
if (!(match = cursor.findNext()) ||
|
|
230
|
+
(start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
|
|
231
|
+
}
|
|
232
|
+
cm.setSelection(cursor.from(), cursor.to());
|
|
233
|
+
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
|
|
234
|
+
confirmDialog(cm, getDoReplaceConfirm(cm), cm.phrase("Replace?"),
|
|
235
|
+
[function() {doReplace(match);}, advance,
|
|
236
|
+
function() {replaceAll(cm, query, text)}]);
|
|
237
|
+
};
|
|
238
|
+
var doReplace = function(match) {
|
|
239
|
+
cursor.replace(typeof query == "string" ? text :
|
|
240
|
+
text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
|
|
241
|
+
advance();
|
|
242
|
+
};
|
|
243
|
+
advance();
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
|
|
250
|
+
CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
|
|
251
|
+
CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);};
|
|
252
|
+
CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);};
|
|
253
|
+
CodeMirror.commands.findNext = doSearch;
|
|
254
|
+
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
|
|
255
|
+
CodeMirror.commands.clearSearch = clearSearch;
|
|
256
|
+
CodeMirror.commands.replace = replace;
|
|
257
|
+
CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
|
|
258
|
+
});
|