codemirror-rails 3.13 → 3.14
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.
- checksums.yaml +4 -4
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +328 -250
- data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +7 -6
- data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +33 -7
- data/vendor/assets/javascripts/codemirror/addons/edit/matchbrackets.js +14 -10
- data/vendor/assets/javascripts/codemirror/addons/edit/trailingspace.js +15 -0
- data/vendor/assets/javascripts/codemirror/addons/fold/brace-fold.js +70 -17
- data/vendor/assets/javascripts/codemirror/addons/fold/foldcode.js +56 -20
- data/vendor/assets/javascripts/codemirror/addons/fold/xml-fold.js +135 -39
- data/vendor/assets/javascripts/codemirror/addons/hint/html-hint.js +324 -571
- data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +199 -109
- data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +60 -113
- data/vendor/assets/javascripts/codemirror/addons/lint/coffeescript-lint.js +24 -0
- data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +431 -0
- data/vendor/assets/javascripts/codemirror/addons/mode/multiplex.js +7 -1
- data/vendor/assets/javascripts/codemirror/addons/search/match-highlighter.js +46 -20
- data/vendor/assets/javascripts/codemirror/addons/search/search.js +1 -1
- data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +370 -13
- data/vendor/assets/javascripts/codemirror/keymaps/extra.js +43 -0
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +535 -214
- data/vendor/assets/javascripts/codemirror/modes/clike.js +56 -0
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +19 -14
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +67 -16
- data/vendor/assets/javascripts/codemirror/modes/smarty.js +167 -110
- data/vendor/assets/javascripts/codemirror/modes/sql.js +97 -15
- data/vendor/assets/javascripts/codemirror/modes/xml.js +14 -18
- data/vendor/assets/stylesheets/codemirror.css +0 -1
- data/vendor/assets/stylesheets/codemirror/addons/merge/merge.css +82 -0
- metadata +7 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
CodeMirror.multiplexingMode = function(outer /*, others */) {
|
2
|
-
// Others should be {open, close, mode [, delimStyle]} objects
|
2
|
+
// Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects
|
3
3
|
var others = Array.prototype.slice.call(arguments, 1);
|
4
4
|
var n_others = others.length;
|
5
5
|
|
@@ -58,6 +58,12 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
|
|
58
58
|
if (found > -1) stream.string = oldContent;
|
59
59
|
var cur = stream.current(), found = cur.indexOf(curInner.close);
|
60
60
|
if (found > -1) stream.backUp(cur.length - found);
|
61
|
+
|
62
|
+
if (curInner.innerStyle) {
|
63
|
+
if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle;
|
64
|
+
else innerToken = curInner.innerStyle;
|
65
|
+
}
|
66
|
+
|
61
67
|
return innerToken;
|
62
68
|
}
|
63
69
|
},
|
@@ -5,35 +5,49 @@
|
|
5
5
|
// document.
|
6
6
|
//
|
7
7
|
// The option can be set to true to simply enable it, or to a
|
8
|
-
// {minChars, style} object to explicitly configure it.
|
9
|
-
// the minimum amount of characters that should be
|
10
|
-
// behavior to occur, and style is the token style to
|
11
|
-
// matches. This will be prefixed by "cm-" to create an
|
12
|
-
// class name.
|
8
|
+
// {minChars, style, showToken} object to explicitly configure it.
|
9
|
+
// minChars is the minimum amount of characters that should be
|
10
|
+
// selected for the behavior to occur, and style is the token style to
|
11
|
+
// apply to the matches. This will be prefixed by "cm-" to create an
|
12
|
+
// actual CSS class name. showToken, when enabled, will cause the
|
13
|
+
// current token to be highlighted when nothing is selected.
|
13
14
|
|
14
15
|
(function() {
|
15
16
|
var DEFAULT_MIN_CHARS = 2;
|
16
17
|
var DEFAULT_TOKEN_STYLE = "matchhighlight";
|
17
18
|
|
18
19
|
function State(options) {
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
if (typeof options == "object") {
|
21
|
+
this.minChars = options.minChars;
|
22
|
+
this.style = options.style;
|
23
|
+
this.showToken = options.showToken;
|
24
|
+
}
|
25
|
+
if (this.style == null) this.style = DEFAULT_TOKEN_STYLE;
|
26
|
+
if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS;
|
27
|
+
this.overlay = this.timeout = null;
|
22
28
|
}
|
23
29
|
|
24
30
|
CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
|
25
|
-
|
26
|
-
if (val && !prev) {
|
27
|
-
cm.state.matchHighlighter = new State(val);
|
28
|
-
cm.on("cursorActivity", highlightMatches);
|
29
|
-
} else if (!val && prev) {
|
31
|
+
if (old && old != CodeMirror.Init) {
|
30
32
|
var over = cm.state.matchHighlighter.overlay;
|
31
33
|
if (over) cm.removeOverlay(over);
|
34
|
+
clearTimeout(cm.state.matchHighlighter.timeout);
|
32
35
|
cm.state.matchHighlighter = null;
|
33
|
-
cm.off("cursorActivity",
|
36
|
+
cm.off("cursorActivity", cursorActivity);
|
37
|
+
}
|
38
|
+
if (val) {
|
39
|
+
cm.state.matchHighlighter = new State(val);
|
40
|
+
highlightMatches(cm);
|
41
|
+
cm.on("cursorActivity", cursorActivity);
|
34
42
|
}
|
35
43
|
});
|
36
44
|
|
45
|
+
function cursorActivity(cm) {
|
46
|
+
var state = cm.state.matchHighlighter;
|
47
|
+
clearTimeout(state.timeout);
|
48
|
+
state.timeout = setTimeout(function() {highlightMatches(cm);}, 100);
|
49
|
+
}
|
50
|
+
|
37
51
|
function highlightMatches(cm) {
|
38
52
|
cm.operation(function() {
|
39
53
|
var state = cm.state.matchHighlighter;
|
@@ -42,17 +56,29 @@
|
|
42
56
|
state.overlay = null;
|
43
57
|
}
|
44
58
|
|
45
|
-
if (!cm.somethingSelected())
|
59
|
+
if (!cm.somethingSelected() && state.showToken) {
|
60
|
+
var tok = cm.getTokenAt(cm.getCursor()).string;
|
61
|
+
if (/\w/.test(tok))
|
62
|
+
cm.addOverlay(state.overlay = makeOverlay(tok, true, state.style));
|
63
|
+
return;
|
64
|
+
}
|
65
|
+
if (cm.getCursor("head").line != cm.getCursor("anchor").line) return;
|
46
66
|
var selection = cm.getSelection().replace(/^\s+|\s+$/g, "");
|
47
|
-
if (selection.length
|
48
|
-
|
49
|
-
cm.addOverlay(state.overlay = makeOverlay(selection, state.style));
|
67
|
+
if (selection.length >= state.minChars)
|
68
|
+
cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style));
|
50
69
|
});
|
51
70
|
}
|
52
71
|
|
53
|
-
function
|
72
|
+
function boundariesAround(stream) {
|
73
|
+
return (stream.start || /.\b./.test(stream.string.slice(stream.start - 1, stream.start + 1))) &&
|
74
|
+
(stream.pos == stream.string.length || /.\b./.test(stream.string.slice(stream.pos - 1, stream.pos + 1)));
|
75
|
+
}
|
76
|
+
|
77
|
+
function makeOverlay(query, wordBoundaries, style) {
|
54
78
|
return {token: function(stream) {
|
55
|
-
if (stream.match(query)
|
79
|
+
if (stream.match(query) &&
|
80
|
+
(!wordBoundaries || boundariesAround(stream)))
|
81
|
+
return style;
|
56
82
|
stream.next();
|
57
83
|
stream.skipTo(query.charAt(0)) || stream.skipToEnd();
|
58
84
|
}};
|
@@ -55,7 +55,7 @@
|
|
55
55
|
if (!query || state.query) return;
|
56
56
|
state.query = parseQuery(query);
|
57
57
|
cm.removeOverlay(state.overlay);
|
58
|
-
state.overlay = searchOverlay(query);
|
58
|
+
state.overlay = searchOverlay(state.query);
|
59
59
|
cm.addOverlay(state.overlay);
|
60
60
|
state.posFrom = state.posTo = cm.getCursor();
|
61
61
|
findNext(cm, rev);
|
@@ -1,30 +1,387 @@
|
|
1
|
-
// TODO number prefixes
|
2
1
|
(function() {
|
3
|
-
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
var Pos = CodeMirror.Pos;
|
5
|
+
function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }
|
6
|
+
|
7
|
+
// Kill 'ring'
|
8
|
+
|
4
9
|
var killRing = [];
|
5
10
|
function addToRing(str) {
|
6
11
|
killRing.push(str);
|
7
12
|
if (killRing.length > 50) killRing.shift();
|
8
13
|
}
|
9
|
-
function
|
14
|
+
function growRingTop(str) {
|
15
|
+
if (!killRing.length) return addToRing(str);
|
16
|
+
killRing[killRing.length - 1] += str;
|
17
|
+
}
|
18
|
+
function getFromRing(n) { return killRing[killRing.length - (n ? Math.min(n, 1) : 1)] || ""; }
|
10
19
|
function popFromRing() { if (killRing.length > 1) killRing.pop(); return getFromRing(); }
|
11
20
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
21
|
+
var lastKill = null;
|
22
|
+
|
23
|
+
function kill(cm, from, to, mayGrow, text) {
|
24
|
+
if (text == null) text = cm.getRange(from, to);
|
25
|
+
|
26
|
+
if (mayGrow && lastKill && lastKill.cm == cm && posEq(from, lastKill.pos) && cm.isClean(lastKill.gen))
|
27
|
+
growRingTop(text);
|
28
|
+
else
|
29
|
+
addToRing(text);
|
30
|
+
cm.replaceRange("", from, to, "+delete");
|
31
|
+
|
32
|
+
if (mayGrow) lastKill = {cm: cm, pos: from, gen: cm.changeGeneration()};
|
33
|
+
else lastKill = null;
|
34
|
+
}
|
35
|
+
|
36
|
+
// Boundaries of various units
|
37
|
+
|
38
|
+
function byChar(cm, pos, dir) {
|
39
|
+
return cm.findPosH(pos, dir, "char", true);
|
40
|
+
}
|
41
|
+
|
42
|
+
function byWord(cm, pos, dir) {
|
43
|
+
return cm.findPosH(pos, dir, "word", true);
|
44
|
+
}
|
45
|
+
|
46
|
+
function byLine(cm, pos, dir) {
|
47
|
+
return cm.findPosV(pos, dir, "line", cm.doc.sel.goalColumn);
|
48
|
+
}
|
49
|
+
|
50
|
+
function byPage(cm, pos, dir) {
|
51
|
+
return cm.findPosV(pos, dir, "page", cm.doc.sel.goalColumn);
|
52
|
+
}
|
53
|
+
|
54
|
+
function byParagraph(cm, pos, dir) {
|
55
|
+
var no = pos.line, line = cm.getLine(no);
|
56
|
+
var sawText = /\S/.test(dir < 0 ? line.slice(0, pos.ch) : line.slice(pos.ch));
|
57
|
+
var fst = cm.firstLine(), lst = cm.lastLine();
|
58
|
+
for (;;) {
|
59
|
+
no += dir;
|
60
|
+
if (no < fst || no > lst)
|
61
|
+
return cm.clipPos(Pos(no - dir, dir < 0 ? 0 : null));
|
62
|
+
line = cm.getLine(no);
|
63
|
+
var hasText = /\S/.test(line);
|
64
|
+
if (hasText) sawText = true;
|
65
|
+
else if (sawText) return Pos(no, 0);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
function bySentence(cm, pos, dir) {
|
70
|
+
var line = pos.line, ch = pos.ch;
|
71
|
+
var text = cm.getLine(pos.line), sawWord = false;
|
72
|
+
for (;;) {
|
73
|
+
var next = text.charAt(ch + (dir < 0 ? -1 : 0));
|
74
|
+
if (!next) { // End/beginning of line reached
|
75
|
+
if (line == (dir < 0 ? cm.firstLine() : cm.lastLine())) return Pos(line, ch);
|
76
|
+
text = cm.getLine(line + dir);
|
77
|
+
if (!/\S/.test(text)) return Pos(line, ch);
|
78
|
+
line += dir;
|
79
|
+
ch = dir < 0 ? text.length : 0;
|
80
|
+
continue;
|
81
|
+
}
|
82
|
+
if (sawWord && /[!?.]/.test(next)) return Pos(line, ch + (dir > 0 ? 1 : 0));
|
83
|
+
if (!sawWord) sawWord = /\w/.test(next);
|
84
|
+
ch += dir;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
function byExpr(cm, pos, dir) {
|
89
|
+
var wrap;
|
90
|
+
if (cm.findMatchingBracket && (wrap = cm.findMatchingBracket(pos, true))
|
91
|
+
&& wrap.match && (wrap.forward ? 1 : -1) == dir)
|
92
|
+
return dir > 0 ? Pos(wrap.to.line, wrap.to.ch + 1) : wrap.to;
|
93
|
+
|
94
|
+
for (var first = true;; first = false) {
|
95
|
+
var token = cm.getTokenAt(pos);
|
96
|
+
var after = Pos(pos.line, dir < 0 ? token.start : token.end);
|
97
|
+
if (first && dir > 0 && token.end == pos.ch || !/\w/.test(token.string)) {
|
98
|
+
var newPos = cm.findPosH(after, dir, "char");
|
99
|
+
if (posEq(after, newPos)) return pos;
|
100
|
+
else pos = newPos;
|
101
|
+
} else {
|
102
|
+
return after;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
// Prefixes (only crudely supported)
|
108
|
+
|
109
|
+
function getPrefix(cm, precise) {
|
110
|
+
var digits = cm.state.emacsPrefix;
|
111
|
+
if (!digits) return precise ? null : 1;
|
112
|
+
clearPrefix(cm);
|
113
|
+
return digits == "-" ? -1 : Number(digits);
|
114
|
+
}
|
115
|
+
|
116
|
+
function repeated(cmd) {
|
117
|
+
var f = typeof cmd == "string" ? function(cm) { cm.execCommand(cmd); } : cmd;
|
118
|
+
return function(cm) {
|
119
|
+
var prefix = getPrefix(cm);
|
120
|
+
f(cm);
|
121
|
+
for (var i = 1; i < prefix; ++i) f(cm);
|
122
|
+
};
|
123
|
+
}
|
124
|
+
|
125
|
+
function findEnd(cm, by, dir) {
|
126
|
+
var pos = cm.getCursor(), prefix = getPrefix(cm);
|
127
|
+
if (prefix < 0) { dir = -dir; prefix = -prefix; }
|
128
|
+
for (var i = 0; i < prefix; ++i) {
|
129
|
+
var newPos = by(cm, pos, dir);
|
130
|
+
if (posEq(newPos, pos)) break;
|
131
|
+
pos = newPos;
|
132
|
+
}
|
133
|
+
return pos;
|
134
|
+
}
|
135
|
+
|
136
|
+
function move(by, dir) {
|
137
|
+
var f = function(cm) {
|
138
|
+
cm.extendSelection(findEnd(cm, by, dir));
|
139
|
+
};
|
140
|
+
f.motion = true;
|
141
|
+
return f;
|
142
|
+
}
|
143
|
+
|
144
|
+
function killTo(cm, by, dir) {
|
145
|
+
kill(cm, cm.getCursor(), findEnd(cm, by, dir), true);
|
146
|
+
}
|
147
|
+
|
148
|
+
function addPrefix(cm, digit) {
|
149
|
+
if (cm.state.emacsPrefix) {
|
150
|
+
if (digit != "-") cm.state.emacsPrefix += digit;
|
151
|
+
return;
|
152
|
+
}
|
153
|
+
// Not active yet
|
154
|
+
cm.state.emacsPrefix = digit;
|
155
|
+
cm.on("keyHandled", maybeClearPrefix);
|
156
|
+
cm.on("inputRead", maybeDuplicateInput);
|
157
|
+
}
|
158
|
+
|
159
|
+
var prefixPreservingKeys = {"Alt-G": true, "Ctrl-X": true, "Ctrl-Q": true, "Ctrl-U": true};
|
160
|
+
|
161
|
+
function maybeClearPrefix(cm, arg) {
|
162
|
+
if (!cm.state.emacsPrefixMap && !prefixPreservingKeys.hasOwnProperty(arg))
|
163
|
+
clearPrefix(cm);
|
164
|
+
}
|
165
|
+
|
166
|
+
function clearPrefix(cm) {
|
167
|
+
cm.state.emacsPrefix = null;
|
168
|
+
cm.off("keyHandled", maybeClearPrefix);
|
169
|
+
cm.off("inputRead", maybeDuplicateInput);
|
170
|
+
}
|
171
|
+
|
172
|
+
function maybeDuplicateInput(cm, event) {
|
173
|
+
var dup = getPrefix(cm);
|
174
|
+
if (dup > 1 && event.origin == "+input") {
|
175
|
+
var one = event.text.join("\n"), txt = "";
|
176
|
+
for (var i = 1; i < dup; ++i) txt += one;
|
177
|
+
cm.replaceSelection(txt, "end", "+input");
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
function addPrefixMap(cm) {
|
182
|
+
cm.state.emacsPrefixMap = true;
|
183
|
+
cm.addKeyMap(prefixMap);
|
184
|
+
cm.on("keyHandled", maybeRemovePrefixMap);
|
185
|
+
cm.on("inputRead", maybeRemovePrefixMap);
|
186
|
+
}
|
187
|
+
|
188
|
+
function maybeRemovePrefixMap(cm, arg) {
|
189
|
+
if (typeof arg == "string" && (/^\d$/.test(arg) || arg == "Ctrl-U")) return;
|
190
|
+
cm.removeKeyMap(prefixMap);
|
191
|
+
cm.state.emacsPrefixMap = false;
|
192
|
+
cm.off("keyHandled", maybeRemovePrefixMap);
|
193
|
+
cm.off("inputRead", maybeRemovePrefixMap);
|
194
|
+
}
|
195
|
+
|
196
|
+
// Utilities
|
197
|
+
|
198
|
+
function setMark(cm) {
|
199
|
+
cm.setCursor(cm.getCursor());
|
200
|
+
cm.setExtending(true);
|
201
|
+
cm.on("change", function() { cm.setExtending(false); });
|
202
|
+
}
|
203
|
+
|
204
|
+
function getInput(cm, msg, f) {
|
205
|
+
if (cm.openDialog)
|
206
|
+
cm.openDialog(msg + ": <input type=\"text\" style=\"width: 10em\"/>", f, {bottom: true});
|
207
|
+
else
|
208
|
+
f(prompt(msg, ""));
|
209
|
+
}
|
210
|
+
|
211
|
+
function operateOnWord(cm, op) {
|
212
|
+
var start = cm.getCursor(), end = cm.findPosH(start, 1, "word");
|
213
|
+
cm.replaceRange(op(cm.getRange(start, end)), start, end);
|
214
|
+
cm.setCursor(end);
|
215
|
+
}
|
216
|
+
|
217
|
+
function toEnclosingExpr(cm) {
|
218
|
+
var pos = cm.getCursor(), line = pos.line, ch = pos.ch;
|
219
|
+
var stack = [];
|
220
|
+
while (line >= cm.firstLine()) {
|
221
|
+
var text = cm.getLine(line);
|
222
|
+
for (var i = ch == null ? text.length : ch; i > 0;) {
|
223
|
+
var ch = text.charAt(--i);
|
224
|
+
if (ch == ")")
|
225
|
+
stack.push("(");
|
226
|
+
else if (ch == "]")
|
227
|
+
stack.push("[");
|
228
|
+
else if (ch == "}")
|
229
|
+
stack.push("{");
|
230
|
+
else if (/[\(\{\[]/.test(ch) && (!stack.length || stack.pop() != ch))
|
231
|
+
return cm.extendSelection(Pos(line, i));
|
232
|
+
}
|
233
|
+
--line; ch = null;
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
// Actual keymap
|
238
|
+
|
239
|
+
var keyMap = CodeMirror.keyMap.emacs = {
|
240
|
+
"Ctrl-W": function(cm) {kill(cm, cm.getCursor("start"), cm.getCursor("end"));},
|
241
|
+
"Ctrl-K": repeated(function(cm) {
|
242
|
+
var start = cm.getCursor(), end = cm.clipPos(Pos(start.line));
|
243
|
+
var text = cm.getRange(start, end);
|
244
|
+
if (!/\S/.test(text)) {
|
245
|
+
text += "\n";
|
246
|
+
end = Pos(start.line + 1, 0);
|
247
|
+
}
|
248
|
+
kill(cm, start, end, true, text);
|
249
|
+
}),
|
250
|
+
"Alt-W": function(cm) {
|
251
|
+
addToRing(cm.getSelection());
|
252
|
+
},
|
253
|
+
"Ctrl-Y": function(cm) {
|
254
|
+
var start = cm.getCursor();
|
255
|
+
cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste");
|
256
|
+
cm.setSelection(start, cm.getCursor());
|
257
|
+
},
|
18
258
|
"Alt-Y": function(cm) {cm.replaceSelection(popFromRing());},
|
19
|
-
|
259
|
+
|
260
|
+
"Ctrl-Space": setMark, "Ctrl-Shift-2": setMark,
|
261
|
+
|
262
|
+
"Ctrl-F": move(byChar, 1), "Ctrl-B": move(byChar, -1),
|
263
|
+
"Right": move(byChar, 1), "Left": move(byChar, -1),
|
264
|
+
"Ctrl-D": function(cm) { killTo(cm, byChar, 1); },
|
265
|
+
"Delete": function(cm) { killTo(cm, byChar, 1); },
|
266
|
+
"Ctrl-H": function(cm) { killTo(cm, byChar, -1); },
|
267
|
+
"Backspace": function(cm) { killTo(cm, byChar, -1); },
|
268
|
+
|
269
|
+
"Alt-F": move(byWord, 1), "Alt-B": move(byWord, -1),
|
270
|
+
"Alt-D": function(cm) { killTo(cm, byWord, 1); },
|
271
|
+
"Alt-Backspace": function(cm) { killTo(cm, byWord, -1); },
|
272
|
+
|
273
|
+
"Ctrl-N": move(byLine, 1), "Ctrl-P": move(byLine, -1),
|
274
|
+
"Down": move(byLine, 1), "Up": move(byLine, -1),
|
275
|
+
"Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
|
276
|
+
"End": "goLineEnd", "Home": "goLineStart",
|
277
|
+
|
278
|
+
"Alt-V": move(byPage, -1), "Ctrl-V": move(byPage, 1),
|
279
|
+
"PageUp": move(byPage, -1), "PageDown": move(byPage, 1),
|
280
|
+
|
281
|
+
"Ctrl-Up": move(byParagraph, -1), "Ctrl-Down": move(byParagraph, 1),
|
282
|
+
|
283
|
+
"Alt-A": move(bySentence, -1), "Alt-E": move(bySentence, 1),
|
284
|
+
"Alt-K": function(cm) { killTo(cm, bySentence, 1); },
|
285
|
+
|
286
|
+
"Ctrl-Alt-K": function(cm) { killTo(cm, byExpr, 1); },
|
287
|
+
"Ctrl-Alt-Backspace": function(cm) { killTo(cm, byExpr, -1); },
|
288
|
+
"Ctrl-Alt-F": move(byExpr, 1), "Ctrl-Alt-B": move(byExpr, -1),
|
289
|
+
|
290
|
+
"Shift-Ctrl-Alt-2": function(cm) {
|
291
|
+
cm.setSelection(findEnd(cm, byExpr, 1), cm.getCursor());
|
292
|
+
},
|
293
|
+
"Ctrl-Alt-T": function(cm) {
|
294
|
+
var leftStart = byExpr(cm, cm.getCursor(), -1), leftEnd = byExpr(cm, leftStart, 1);
|
295
|
+
var rightEnd = byExpr(cm, leftEnd, 1), rightStart = byExpr(cm, rightEnd, -1);
|
296
|
+
cm.replaceRange(cm.getRange(rightStart, rightEnd) + cm.getRange(leftEnd, rightStart) +
|
297
|
+
cm.getRange(leftStart, leftEnd), leftStart, rightEnd);
|
298
|
+
},
|
299
|
+
"Ctrl-Alt-U": repeated(toEnclosingExpr),
|
300
|
+
|
301
|
+
"Alt-Space": function(cm) {
|
302
|
+
var pos = cm.getCursor(), from = pos.ch, to = pos.ch, text = cm.getLine(pos.line);
|
303
|
+
while (from && /\s/.test(text.charAt(from - 1))) --from;
|
304
|
+
while (to < text.length && /\s/.test(text.charAt(to))) ++to;
|
305
|
+
cm.replaceRange(" ", Pos(pos.line, from), Pos(pos.line, to));
|
306
|
+
},
|
307
|
+
"Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }),
|
308
|
+
"Ctrl-T": repeated(function(cm) {
|
309
|
+
var pos = cm.getCursor();
|
310
|
+
if (pos.ch < cm.getLine(pos.line).length) pos = Pos(pos.line, pos.ch + 1);
|
311
|
+
var from = cm.findPosH(pos, -2, "char");
|
312
|
+
var range = cm.getRange(from, pos);
|
313
|
+
if (range.length != 2) return;
|
314
|
+
cm.setSelection(from, pos);
|
315
|
+
cm.replaceSelection(range.charAt(1) + range.charAt(0), "end");
|
316
|
+
}),
|
317
|
+
|
318
|
+
"Alt-C": repeated(function(cm) {
|
319
|
+
operateOnWord(cm, function(w) {
|
320
|
+
var letter = w.search(/\w/);
|
321
|
+
if (letter == -1) return w;
|
322
|
+
return w.slice(0, letter) + w.charAt(letter).toUpperCase() + w.slice(letter + 1).toLowerCase();
|
323
|
+
});
|
324
|
+
}),
|
325
|
+
"Alt-U": repeated(function(cm) {
|
326
|
+
operateOnWord(cm, function(w) { return w.toUpperCase(); });
|
327
|
+
}),
|
328
|
+
"Alt-L": repeated(function(cm) {
|
329
|
+
operateOnWord(cm, function(w) { return w.toLowerCase(); });
|
330
|
+
}),
|
331
|
+
|
332
|
+
"Alt-;": "toggleComment",
|
333
|
+
|
334
|
+
"Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"),
|
335
|
+
"Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"),
|
336
|
+
"Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
|
20
337
|
"Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": "clearSearch", "Shift-Alt-5": "replace",
|
21
|
-
"
|
338
|
+
"Alt-/": "autocomplete",
|
22
339
|
"Ctrl-J": "newlineAndIndent", "Enter": false, "Tab": "indentAuto",
|
23
|
-
|
340
|
+
|
341
|
+
"Alt-G": function(cm) {cm.setOption("keyMap", "emacs-Alt-G");},
|
342
|
+
"Ctrl-X": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-X");},
|
343
|
+
"Ctrl-Q": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-Q");},
|
344
|
+
"Ctrl-U": addPrefixMap
|
24
345
|
};
|
25
346
|
|
26
347
|
CodeMirror.keyMap["emacs-Ctrl-X"] = {
|
27
|
-
"
|
348
|
+
"Tab": function(cm) {
|
349
|
+
cm.indentSelection(getPrefix(cm, true) || cm.getOption("indentUnit"));
|
350
|
+
},
|
351
|
+
"Ctrl-X": function(cm) {
|
352
|
+
cm.setSelection(cm.getCursor("head"), cm.getCursor("anchor"));
|
353
|
+
},
|
354
|
+
|
355
|
+
"Ctrl-S": "save", "Ctrl-W": "save", "S": "saveAll", "F": "open", "U": repeated("undo"), "K": "close",
|
356
|
+
"Delete": function(cm) { kill(cm, cm.getCursor(), sentenceEnd(cm, 1), true); },
|
357
|
+
auto: "emacs", nofallthrough: true, disableInput: true
|
358
|
+
};
|
359
|
+
|
360
|
+
CodeMirror.keyMap["emacs-Alt-G"] = {
|
361
|
+
"G": function(cm) {
|
362
|
+
var prefix = getPrefix(cm, true);
|
363
|
+
if (prefix != null && prefix > 0) return cm.setCursor(prefix - 1);
|
364
|
+
|
365
|
+
getInput(cm, "Goto line", function(str) {
|
366
|
+
var num;
|
367
|
+
if (str && !isNaN(num = Number(str)) && num == num|0 && num > 0)
|
368
|
+
cm.setCursor(num - 1);
|
369
|
+
});
|
370
|
+
},
|
371
|
+
auto: "emacs", nofallthrough: true, disableInput: true
|
372
|
+
};
|
373
|
+
|
374
|
+
CodeMirror.keyMap["emacs-Ctrl-Q"] = {
|
375
|
+
"Tab": repeated("insertTab"),
|
28
376
|
auto: "emacs", nofallthrough: true
|
29
377
|
};
|
378
|
+
|
379
|
+
var prefixMap = {"Ctrl-G": clearPrefix};
|
380
|
+
function regPrefix(d) {
|
381
|
+
prefixMap[d] = function(cm) { addPrefix(cm, d); };
|
382
|
+
keyMap["Ctrl-" + d] = function(cm) { addPrefix(cm, d); };
|
383
|
+
prefixPreservingKeys["Ctrl-" + d] = true;
|
384
|
+
}
|
385
|
+
for (var i = 0; i < 10; ++i) regPrefix(String(i));
|
386
|
+
regPrefix("-");
|
30
387
|
})();
|