codemirror-rails 5.9 → 5.10

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.
@@ -108,6 +108,7 @@
108
108
  map["Shift-" + ctrl + "K"] = "deleteLine";
109
109
 
110
110
  function insertLine(cm, above) {
111
+ if (cm.isReadOnly()) return CodeMirror.Pass
111
112
  cm.operation(function() {
112
113
  var len = cm.listSelections().length, newSelection = [], last = -1;
113
114
  for (var i = 0; i < len; i++) {
@@ -123,9 +124,9 @@
123
124
  });
124
125
  }
125
126
 
126
- cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { insertLine(cm, false); };
127
+ cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { return insertLine(cm, false); };
127
128
 
128
- cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { insertLine(cm, true); };
129
+ cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { return insertLine(cm, true); };
129
130
 
130
131
  function wordAt(cm, pos) {
131
132
  var start = pos.ch, end = start, line = cm.getLine(pos.line);
@@ -192,6 +193,7 @@
192
193
  var swapLineCombo = mac ? "Cmd-Ctrl-" : "Shift-Ctrl-";
193
194
 
194
195
  cmds[map[swapLineCombo + "Up"] = "swapLineUp"] = function(cm) {
196
+ if (cm.isReadOnly()) return CodeMirror.Pass
195
197
  var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = [];
196
198
  for (var i = 0; i < ranges.length; i++) {
197
199
  var range = ranges[i], from = range.from().line - 1, to = range.to().line;
@@ -218,6 +220,7 @@
218
220
  };
219
221
 
220
222
  cmds[map[swapLineCombo + "Down"] = "swapLineDown"] = function(cm) {
223
+ if (cm.isReadOnly()) return CodeMirror.Pass
221
224
  var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1;
222
225
  for (var i = ranges.length - 1; i >= 0; i--) {
223
226
  var range = ranges[i], from = range.to().line + 1, to = range.from().line;
@@ -240,7 +243,7 @@
240
243
  });
241
244
  };
242
245
 
243
- map[ctrl + "/"] = function(cm) {
246
+ cmds[map[ctrl + "/"] = "toggleCommentIndented"] = function(cm) {
244
247
  cm.toggleComment({ indent: true });
245
248
  }
246
249
 
@@ -289,6 +292,7 @@
289
292
  map[ctrl + "T"] = "transposeChars";
290
293
 
291
294
  function sortLines(cm, caseSensitive) {
295
+ if (cm.isReadOnly()) return CodeMirror.Pass
292
296
  var ranges = cm.listSelections(), toSort = [], selected;
293
297
  for (var i = 0; i < ranges.length; i++) {
294
298
  var range = ranges[i];
@@ -292,12 +292,7 @@
292
292
  // Keypress character binding of format "'a'"
293
293
  return key.charAt(1);
294
294
  }
295
- var pieces = key.split('-');
296
- if (/-$/.test(key)) {
297
- // If the - key was typed, split will result in 2 extra empty strings
298
- // in the array. Replace them with 1 '-'.
299
- pieces.splice(-2, 2, '-');
300
- }
295
+ var pieces = key.split(/-(?!$)/);
301
296
  var lastPiece = pieces[pieces.length - 1];
302
297
  if (pieces.length == 1 && pieces[0].length == 1) {
303
298
  // No-modifier bindings use literal character bindings above. Skip.
@@ -1959,13 +1954,21 @@
1959
1954
  text = text.slice(0, - match[0].length);
1960
1955
  }
1961
1956
  }
1962
- var wasLastLine = head.line - 1 == cm.lastLine();
1963
- cm.replaceRange('', anchor, head);
1964
- if (args.linewise && !wasLastLine) {
1957
+ var prevLineEnd = new Pos(anchor.line - 1, Number.MAX_VALUE);
1958
+ var wasLastLine = cm.firstLine() == cm.lastLine();
1959
+ if (head.line > cm.lastLine() && args.linewise && !wasLastLine) {
1960
+ cm.replaceRange('', prevLineEnd, head);
1961
+ } else {
1962
+ cm.replaceRange('', anchor, head);
1963
+ }
1964
+ if (args.linewise) {
1965
1965
  // Push the next line back down, if there is a next line.
1966
- CodeMirror.commands.newlineAndIndent(cm);
1967
- // null ch so setCursor moves to end of line.
1968
- anchor.ch = null;
1966
+ if (!wasLastLine) {
1967
+ cm.setCursor(prevLineEnd);
1968
+ CodeMirror.commands.newlineAndIndent(cm);
1969
+ }
1970
+ // make sure cursor ends up at the end of the line.
1971
+ anchor.ch = Number.MAX_VALUE;
1969
1972
  }
1970
1973
  finalHead = anchor;
1971
1974
  } else {
@@ -2144,9 +2147,7 @@
2144
2147
  switch (actionArgs.position) {
2145
2148
  case 'center': y = y - (height / 2) + lineHeight;
2146
2149
  break;
2147
- case 'bottom': y = y - height + lineHeight*1.4;
2148
- break;
2149
- case 'top': y = y + lineHeight*0.4;
2150
+ case 'bottom': y = y - height + lineHeight;
2150
2151
  break;
2151
2152
  }
2152
2153
  cm.scrollTo(null, y);
@@ -262,21 +262,20 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
262
262
  var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
263
263
 
264
264
  function cppHook(stream, state) {
265
- if (!state.startOfLine) return false;
266
- for (;;) {
267
- if (stream.skipTo("\\")) {
268
- stream.next();
269
- if (stream.eol()) {
270
- state.tokenize = cppHook;
271
- break;
272
- }
273
- } else {
274
- stream.skipToEnd();
275
- state.tokenize = null;
276
- break;
265
+ if (!state.startOfLine) return false
266
+ for (var ch, next = null; ch = stream.peek();) {
267
+ if (!ch) {
268
+ break
269
+ } else if (ch == "\\" && stream.match(/^.$/)) {
270
+ next = cppHook
271
+ break
272
+ } else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
273
+ break
277
274
  }
275
+ stream.next()
278
276
  }
279
- return "meta";
277
+ state.tokenize = next
278
+ return "meta"
280
279
  }
281
280
 
282
281
  function pointerHook(_stream, state) {
@@ -0,0 +1,391 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineMode("crystal", function(config) {
15
+ function wordRegExp(words, end) {
16
+ return new RegExp((end ? "" : "^") + "(?:" + words.join("|") + ")" + (end ? "$" : "\\b"));
17
+ }
18
+
19
+ function chain(tokenize, stream, state) {
20
+ state.tokenize.push(tokenize);
21
+ return tokenize(stream, state);
22
+ }
23
+
24
+ var operators = /^(?:[-+/%|&^]|\*\*?|[<>]{2})/;
25
+ var conditionalOperators = /^(?:[=!]~|===|<=>|[<>=!]=?|[|&]{2}|~)/;
26
+ var indexingOperators = /^(?:\[\][?=]?)/;
27
+ var anotherOperators = /^(?:\.(?:\.{2})?|->|[?:])/;
28
+ var idents = /^[a-z_\u009F-\uFFFF][a-zA-Z0-9_\u009F-\uFFFF]*/;
29
+ var types = /^[A-Z_\u009F-\uFFFF][a-zA-Z0-9_\u009F-\uFFFF]*/;
30
+ var keywords = wordRegExp([
31
+ "abstract", "alias", "as", "asm", "begin", "break", "case", "class", "def", "do",
32
+ "else", "elsif", "end", "ensure", "enum", "extend", "for", "fun", "if", "ifdef",
33
+ "include", "instance_sizeof", "lib", "macro", "module", "next", "of", "out", "pointerof",
34
+ "private", "protected", "rescue", "return", "require", "sizeof", "struct",
35
+ "super", "then", "type", "typeof", "union", "unless", "until", "when", "while", "with",
36
+ "yield", "__DIR__", "__FILE__", "__LINE__"
37
+ ]);
38
+ var atomWords = wordRegExp(["true", "false", "nil", "self"]);
39
+ var indentKeywordsArray = [
40
+ "def", "fun", "macro",
41
+ "class", "module", "struct", "lib", "enum", "union",
42
+ "if", "unless", "case", "while", "until", "begin", "then",
43
+ "do",
44
+ "for", "ifdef"
45
+ ];
46
+ var indentKeywords = wordRegExp(indentKeywordsArray);
47
+ var dedentKeywordsArray = [
48
+ "end",
49
+ "else", "elsif",
50
+ "rescue", "ensure"
51
+ ];
52
+ var dedentKeywords = wordRegExp(dedentKeywordsArray);
53
+ var dedentPunctualsArray = ["\\)", "\\}", "\\]"];
54
+ var dedentPunctuals = new RegExp("^(?:" + dedentPunctualsArray.join("|") + ")$");
55
+ var nextTokenizer = {
56
+ "def": tokenFollowIdent, "fun": tokenFollowIdent, "macro": tokenMacroDef,
57
+ "class": tokenFollowType, "module": tokenFollowType, "struct": tokenFollowType,
58
+ "lib": tokenFollowType, "enum": tokenFollowType, "union": tokenFollowType
59
+ };
60
+ var matching = {"[": "]", "{": "}", "(": ")", "<": ">"};
61
+
62
+ function tokenBase(stream, state) {
63
+ if (stream.eatSpace()) {
64
+ return null;
65
+ }
66
+
67
+ // Macros
68
+ if (state.lastToken != "\\" && stream.match("{%", false)) {
69
+ return chain(tokenMacro("%", "%"), stream, state);
70
+ }
71
+
72
+ if (state.lastToken != "\\" && stream.match("{{", false)) {
73
+ return chain(tokenMacro("{", "}"), stream, state);
74
+ }
75
+
76
+ // Comments
77
+ if (stream.peek() == "#") {
78
+ stream.skipToEnd();
79
+ return "comment";
80
+ }
81
+
82
+ // Variables and keywords
83
+ var matched;
84
+ if (stream.match(idents)) {
85
+ stream.eat(/[?!]/);
86
+
87
+ matched = stream.current();
88
+ if (stream.eat(":")) {
89
+ return "atom";
90
+ } else if (state.lastToken == ".") {
91
+ return "property";
92
+ } else if (keywords.test(matched)) {
93
+ if (state.lastToken != "abstract" && indentKeywords.test(matched)) {
94
+ if (!(matched == "fun" && state.blocks.indexOf("lib") >= 0)) {
95
+ state.blocks.push(matched);
96
+ state.currentIndent += 1;
97
+ }
98
+ } else if (dedentKeywords.test(matched)) {
99
+ state.blocks.pop();
100
+ state.currentIndent -= 1;
101
+ }
102
+
103
+ if (nextTokenizer.hasOwnProperty(matched)) {
104
+ state.tokenize.push(nextTokenizer[matched]);
105
+ }
106
+
107
+ return "keyword";
108
+ } else if (atomWords.test(matched)) {
109
+ return "atom";
110
+ }
111
+
112
+ return "variable";
113
+ }
114
+
115
+ // Class variables and instance variables
116
+ // or attributes
117
+ if (stream.eat("@")) {
118
+ if (stream.peek() == "[") {
119
+ return chain(tokenNest("[", "]", "meta"), stream, state);
120
+ }
121
+
122
+ stream.eat("@");
123
+ stream.match(idents) || stream.match(types);
124
+ return "variable-2";
125
+ }
126
+
127
+ // Global variables
128
+ if (stream.eat("$")) {
129
+ stream.eat(/[0-9]+|\?/) || stream.match(idents) || stream.match(types);
130
+ return "variable-3";
131
+ }
132
+
133
+ // Constants and types
134
+ if (stream.match(types)) {
135
+ return "tag";
136
+ }
137
+
138
+ // Symbols or ':' operator
139
+ if (stream.eat(":")) {
140
+ if (stream.eat("\"")) {
141
+ return chain(tokenQuote("\"", "atom", false), stream, state);
142
+ } else if (stream.match(idents) || stream.match(types) ||
143
+ stream.match(operators) || stream.match(conditionalOperators) || stream.match(indexingOperators)) {
144
+ return "atom";
145
+ }
146
+ stream.eat(":");
147
+ return "operator";
148
+ }
149
+
150
+ // Strings
151
+ if (stream.eat("\"")) {
152
+ return chain(tokenQuote("\"", "string", true), stream, state);
153
+ }
154
+
155
+ // Strings or regexps or macro variables or '%' operator
156
+ if (stream.peek() == "%") {
157
+ var style = "string";
158
+ var embed = true;
159
+ var delim;
160
+
161
+ if (stream.match("%r")) {
162
+ // Regexps
163
+ style = "string-2";
164
+ delim = stream.next();
165
+ } else if (stream.match("%w")) {
166
+ embed = false;
167
+ delim = stream.next();
168
+ } else {
169
+ if(delim = stream.match(/^%([^\w\s=])/)) {
170
+ delim = delim[1];
171
+ } else if (stream.match(/^%[a-zA-Z0-9_\u009F-\uFFFF]*/)) {
172
+ // Macro variables
173
+ return "meta";
174
+ } else {
175
+ // '%' operator
176
+ return "operator";
177
+ }
178
+ }
179
+
180
+ if (matching.hasOwnProperty(delim)) {
181
+ delim = matching[delim];
182
+ }
183
+ return chain(tokenQuote(delim, style, embed), stream, state);
184
+ }
185
+
186
+ // Characters
187
+ if (stream.eat("'")) {
188
+ stream.match(/^(?:[^']|\\(?:[befnrtv0'"]|[0-7]{3}|u(?:[0-9a-fA-F]{4}|\{[0-9a-fA-F]{1,6}\})))/);
189
+ stream.eat("'");
190
+ return "atom";
191
+ }
192
+
193
+ // Numbers
194
+ if (stream.eat("0")) {
195
+ if (stream.eat("x")) {
196
+ stream.match(/^[0-9a-fA-F]+/);
197
+ } else if (stream.eat("o")) {
198
+ stream.match(/^[0-7]+/);
199
+ } else if (stream.eat("b")) {
200
+ stream.match(/^[01]+/);
201
+ }
202
+ return "number";
203
+ }
204
+
205
+ if (stream.eat(/\d/)) {
206
+ stream.match(/^\d*(?:\.\d+)?(?:[eE][+-]?\d+)?/);
207
+ return "number";
208
+ }
209
+
210
+ // Operators
211
+ if (stream.match(operators)) {
212
+ stream.eat("="); // Operators can follow assigin symbol.
213
+ return "operator";
214
+ }
215
+
216
+ if (stream.match(conditionalOperators) || stream.match(anotherOperators)) {
217
+ return "operator";
218
+ }
219
+
220
+ // Parens and braces
221
+ if (matched = stream.match(/[({[]/, false)) {
222
+ matched = matched[0];
223
+ return chain(tokenNest(matched, matching[matched], null), stream, state);
224
+ }
225
+
226
+ // Escapes
227
+ if (stream.eat("\\")) {
228
+ stream.next();
229
+ return "meta";
230
+ }
231
+
232
+ stream.next();
233
+ return null;
234
+ }
235
+
236
+ function tokenNest(begin, end, style, started) {
237
+ return function (stream, state) {
238
+ if (!started && stream.match(begin)) {
239
+ state.tokenize[state.tokenize.length - 1] = tokenNest(begin, end, style, true);
240
+ state.currentIndent += 1;
241
+ return style;
242
+ }
243
+
244
+ var nextStyle = tokenBase(stream, state);
245
+ if (stream.current() === end) {
246
+ state.tokenize.pop();
247
+ state.currentIndent -= 1;
248
+ nextStyle = style;
249
+ }
250
+
251
+ return nextStyle;
252
+ };
253
+ }
254
+
255
+ function tokenMacro(begin, end, started) {
256
+ return function (stream, state) {
257
+ if (!started && stream.match("{" + begin)) {
258
+ state.currentIndent += 1;
259
+ state.tokenize[state.tokenize.length - 1] = tokenMacro(begin, end, true);
260
+ return "meta";
261
+ }
262
+
263
+ if (stream.match(end + "}")) {
264
+ state.currentIndent -= 1;
265
+ state.tokenize.pop();
266
+ return "meta";
267
+ }
268
+
269
+ return tokenBase(stream, state);
270
+ };
271
+ }
272
+
273
+ function tokenMacroDef(stream, state) {
274
+ if (stream.eatSpace()) {
275
+ return null;
276
+ }
277
+
278
+ var matched;
279
+ if (matched = stream.match(idents)) {
280
+ if (matched == "def") {
281
+ return "keyword";
282
+ }
283
+ stream.eat(/[?!]/);
284
+ }
285
+
286
+ state.tokenize.pop();
287
+ return "def";
288
+ }
289
+
290
+ function tokenFollowIdent(stream, state) {
291
+ if (stream.eatSpace()) {
292
+ return null;
293
+ }
294
+
295
+ if (stream.match(idents)) {
296
+ stream.eat(/[!?]/);
297
+ } else {
298
+ stream.match(operators) || stream.match(conditionalOperators) || stream.match(indexingOperators);
299
+ }
300
+ state.tokenize.pop();
301
+ return "def";
302
+ }
303
+
304
+ function tokenFollowType(stream, state) {
305
+ if (stream.eatSpace()) {
306
+ return null;
307
+ }
308
+
309
+ stream.match(types);
310
+ state.tokenize.pop();
311
+ return "def";
312
+ }
313
+
314
+ function tokenQuote(end, style, embed) {
315
+ return function (stream, state) {
316
+ var escaped = false;
317
+
318
+ while (stream.peek()) {
319
+ if (!escaped) {
320
+ if (stream.match("{%", false)) {
321
+ state.tokenize.push(tokenMacro("%", "%"));
322
+ return style;
323
+ }
324
+
325
+ if (stream.match("{{", false)) {
326
+ state.tokenize.push(tokenMacro("{", "}"));
327
+ return style;
328
+ }
329
+
330
+ if (embed && stream.match("#{", false)) {
331
+ state.tokenize.push(tokenNest("#{", "}", "meta"));
332
+ return style;
333
+ }
334
+
335
+ var ch = stream.next();
336
+
337
+ if (ch == end) {
338
+ state.tokenize.pop();
339
+ return style;
340
+ }
341
+
342
+ escaped = ch == "\\";
343
+ } else {
344
+ stream.next();
345
+ escaped = false;
346
+ }
347
+ }
348
+
349
+ return style;
350
+ };
351
+ }
352
+
353
+ return {
354
+ startState: function () {
355
+ return {
356
+ tokenize: [tokenBase],
357
+ currentIndent: 0,
358
+ lastToken: null,
359
+ blocks: []
360
+ };
361
+ },
362
+
363
+ token: function (stream, state) {
364
+ var style = state.tokenize[state.tokenize.length - 1](stream, state);
365
+ var token = stream.current();
366
+
367
+ if (style && style != "comment") {
368
+ state.lastToken = token;
369
+ }
370
+
371
+ return style;
372
+ },
373
+
374
+ indent: function (state, textAfter) {
375
+ textAfter = textAfter.replace(/^\s*(?:\{%)?\s*|\s*(?:%\})?\s*$/g, "");
376
+
377
+ if (dedentKeywords.test(textAfter) || dedentPunctuals.test(textAfter)) {
378
+ return config.indentUnit * (state.currentIndent - 1);
379
+ }
380
+
381
+ return config.indentUnit * state.currentIndent;
382
+ },
383
+
384
+ fold: "indent",
385
+ electricInput: wordRegExp(dedentPunctualsArray.concat(dedentKeywordsArray), true),
386
+ lineComment: '#'
387
+ };
388
+ });
389
+
390
+ CodeMirror.defineMIME("text/x-crystal", "crystal");
391
+ });