codemirror-rails 3.18 → 3.19
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 +42 -19
- data/vendor/assets/javascripts/codemirror/addons/edit/closetag.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/fold/foldcode.js +6 -4
- data/vendor/assets/javascripts/codemirror/addons/fold/foldgutter.js +2 -0
- data/vendor/assets/javascripts/codemirror/addons/fold/indent-fold.js +21 -7
- data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +3 -19
- data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +105 -0
- data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +1 -0
- data/vendor/assets/javascripts/codemirror/addons/search/search.js +2 -0
- data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/wrap/hardwrap.js +99 -0
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +55 -17
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +314 -313
- data/vendor/assets/javascripts/codemirror/modes/css.js +19 -7
- data/vendor/assets/javascripts/codemirror/modes/eiffel.js +147 -0
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/gherkin.js +168 -0
- data/vendor/assets/javascripts/codemirror/modes/less.js +110 -22
- data/vendor/assets/javascripts/codemirror/modes/php.js +4 -4
- data/vendor/assets/javascripts/codemirror/modes/smartymixed.js +6 -1
- data/vendor/assets/javascripts/codemirror/modes/sql.js +15 -2
- data/vendor/assets/javascripts/codemirror/modes/xml.js +7 -3
- data/vendor/assets/stylesheets/codemirror.css +1 -1
- data/vendor/assets/stylesheets/codemirror/addons/fold/foldgutter.css +21 -0
- data/vendor/assets/stylesheets/codemirror/addons/lint/lint.css +1 -0
- data/vendor/assets/stylesheets/codemirror/themes/3024-day.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/3024-night.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/base16-dark.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/base16-light.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/cobalt.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/eclipse.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/elegant.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/mbo.css +35 -0
- data/vendor/assets/stylesheets/codemirror/themes/midnight.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/monokai.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/night.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/paraiso-dark.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/paraiso-light.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/solarized.css +7 -7
- data/vendor/assets/stylesheets/codemirror/themes/the-matrix.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/tomorrow-night-eighties.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/twilight.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/xq-dark.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/xq-light.css +1 -1
- metadata +7 -1
|
@@ -439,7 +439,7 @@
|
|
|
439
439
|
for (var file in perFile) {
|
|
440
440
|
var known = ts.docs[file], chs = perFile[file];;
|
|
441
441
|
if (!known) continue;
|
|
442
|
-
chs.sort(function(a, b) { return cmpPos(b, a); });
|
|
442
|
+
chs.sort(function(a, b) { return cmpPos(b.start, a.start); });
|
|
443
443
|
var origin = "*rename" + (++nextChangeOrig);
|
|
444
444
|
for (var i = 0; i < chs.length; ++i) {
|
|
445
445
|
var ch = chs[i];
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
var Pos = CodeMirror.Pos;
|
|
5
|
+
|
|
6
|
+
function findParagraph(cm, pos, options) {
|
|
7
|
+
var startRE = options.paragraphStart || cm.getHelper(pos, "paragraphStart");
|
|
8
|
+
for (var start = pos.line, first = cm.firstLine(); start > first; --start) {
|
|
9
|
+
var line = cm.getLine(start);
|
|
10
|
+
if (startRE && startRE.test(line)) break;
|
|
11
|
+
if (!/\S/.test(line)) { ++start; break; }
|
|
12
|
+
}
|
|
13
|
+
var endRE = options.paragraphEnd || cm.getHelper(pos, "paragraphEnd");
|
|
14
|
+
for (var end = pos.line + 1, last = cm.lastLine(); end <= last; ++end) {
|
|
15
|
+
var line = cm.getLine(end);
|
|
16
|
+
if (endRE && endRE.test(line)) { ++end; break; }
|
|
17
|
+
if (!/\S/.test(line)) break;
|
|
18
|
+
}
|
|
19
|
+
return {from: start, to: end};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
|
|
23
|
+
for (var at = column; at > 0; --at)
|
|
24
|
+
if (wrapOn.test(text.slice(at - 1, at + 1))) break;
|
|
25
|
+
if (at == 0) at = column;
|
|
26
|
+
var endOfText = at;
|
|
27
|
+
if (killTrailingSpace)
|
|
28
|
+
while (text.charAt(endOfText - 1) == " ") --endOfText;
|
|
29
|
+
return {from: endOfText, to: at};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function wrapRange(cm, from, to, options) {
|
|
33
|
+
from = cm.clipPos(from); to = cm.clipPos(to);
|
|
34
|
+
var column = options.column || 80;
|
|
35
|
+
var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/;
|
|
36
|
+
var killTrailing = options.killTrailingSpace !== false;
|
|
37
|
+
var changes = [], curLine = "", curNo = from.line;
|
|
38
|
+
var lines = cm.getRange(from, to, false);
|
|
39
|
+
for (var i = 0; i < lines.length; ++i) {
|
|
40
|
+
var text = lines[i], oldLen = curLine.length, spaceInserted = 0;
|
|
41
|
+
if (curLine && text && !wrapOn.test(curLine.charAt(curLine.length - 1) + text.charAt(0))) {
|
|
42
|
+
curLine += " ";
|
|
43
|
+
spaceInserted = 1;
|
|
44
|
+
}
|
|
45
|
+
curLine += text;
|
|
46
|
+
if (i) {
|
|
47
|
+
var firstBreak = curLine.length > column && findBreakPoint(curLine, column, wrapOn, killTrailing);
|
|
48
|
+
// If this isn't broken, or is broken at a different point, remove old break
|
|
49
|
+
if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) {
|
|
50
|
+
changes.push({text: spaceInserted ? " " : "",
|
|
51
|
+
from: Pos(curNo, oldLen),
|
|
52
|
+
to: Pos(curNo + 1, 0)});
|
|
53
|
+
} else {
|
|
54
|
+
curLine = text;
|
|
55
|
+
++curNo;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
while (curLine.length > column) {
|
|
59
|
+
var bp = findBreakPoint(curLine, column, wrapOn, killTrailing);
|
|
60
|
+
changes.push({text: "\n",
|
|
61
|
+
from: Pos(curNo, bp.from),
|
|
62
|
+
to: Pos(curNo, bp.to)});
|
|
63
|
+
curLine = curLine.slice(bp.to);
|
|
64
|
+
++curNo;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (changes.length) cm.operation(function() {
|
|
68
|
+
for (var i = 0; i < changes.length; ++i) {
|
|
69
|
+
var change = changes[i];
|
|
70
|
+
cm.replaceRange(change.text, change.from, change.to);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
CodeMirror.defineExtension("wrapParagraph", function(pos, options) {
|
|
76
|
+
options = options || {};
|
|
77
|
+
if (!pos) pos = this.getCursor();
|
|
78
|
+
var para = findParagraph(this, pos, options);
|
|
79
|
+
wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
CodeMirror.defineExtension("wrapRange", function(from, to, options) {
|
|
83
|
+
wrapRange(this, from, to, options || {});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
CodeMirror.defineExtension("wrapParagraphsInRange", function(from, to, options) {
|
|
87
|
+
options = options || {};
|
|
88
|
+
var cm = this, paras = [];
|
|
89
|
+
for (var line = from.line; line <= to.line;) {
|
|
90
|
+
var para = findParagraph(cm, Pos(line, 0), options);
|
|
91
|
+
paras.push(para);
|
|
92
|
+
line = para.to;
|
|
93
|
+
}
|
|
94
|
+
if (paras.length) cm.operation(function() {
|
|
95
|
+
for (var i = paras.length - 1; i >= 0; --i)
|
|
96
|
+
wrapRange(cm, Pos(paras[i].from, 0), Pos(paras[i].to - 1), options);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
})();
|
|
@@ -76,8 +76,10 @@
|
|
|
76
76
|
{ keys: ['<C-p>'], type: 'keyToKey', toKeys: ['k'] },
|
|
77
77
|
{ keys: ['C-['], type: 'keyToKey', toKeys: ['<Esc>'] },
|
|
78
78
|
{ keys: ['<C-c>'], type: 'keyToKey', toKeys: ['<Esc>'] },
|
|
79
|
-
{ keys: ['s'], type: 'keyToKey', toKeys: ['c', 'l'] },
|
|
80
|
-
{ keys: ['
|
|
79
|
+
{ keys: ['s'], type: 'keyToKey', toKeys: ['c', 'l'], context: 'normal' },
|
|
80
|
+
{ keys: ['s'], type: 'keyToKey', toKeys: ['x', 'i'], context: 'visual'},
|
|
81
|
+
{ keys: ['S'], type: 'keyToKey', toKeys: ['c', 'c'], context: 'normal' },
|
|
82
|
+
{ keys: ['S'], type: 'keyToKey', toKeys: ['d', 'c', 'c'], context: 'visual' },
|
|
81
83
|
{ keys: ['<Home>'], type: 'keyToKey', toKeys: ['0'] },
|
|
82
84
|
{ keys: ['<End>'], type: 'keyToKey', toKeys: ['$'] },
|
|
83
85
|
{ keys: ['<PageUp>'], type: 'keyToKey', toKeys: ['<C-b>'] },
|
|
@@ -609,6 +611,9 @@
|
|
|
609
611
|
}
|
|
610
612
|
commandDispatcher.processCommand(cm, vim, command);
|
|
611
613
|
}
|
|
614
|
+
},
|
|
615
|
+
handleEx: function(cm, input) {
|
|
616
|
+
exCommandDispatcher.processCommand(cm, input);
|
|
612
617
|
}
|
|
613
618
|
};
|
|
614
619
|
|
|
@@ -695,6 +700,9 @@
|
|
|
695
700
|
if (linewise && text.charAt(0) == '\n') {
|
|
696
701
|
text = text.slice(1) + '\n';
|
|
697
702
|
}
|
|
703
|
+
if(linewise && text.charAt(text.length - 1) !== '\n'){
|
|
704
|
+
text += '\n';
|
|
705
|
+
}
|
|
698
706
|
// Lowercase and uppercase registers refer to the same register.
|
|
699
707
|
// Uppercase just means append.
|
|
700
708
|
var register = this.isValidRegister(registerName) ?
|
|
@@ -766,44 +774,74 @@
|
|
|
766
774
|
matchCommand: function(key, keyMap, vim) {
|
|
767
775
|
var inputState = vim.inputState;
|
|
768
776
|
var keys = inputState.keyBuffer.concat(key);
|
|
777
|
+
var matchedCommands = [];
|
|
778
|
+
var selectedCharacter;
|
|
769
779
|
for (var i = 0; i < keyMap.length; i++) {
|
|
770
780
|
var command = keyMap[i];
|
|
771
781
|
if (matchKeysPartial(keys, command.keys)) {
|
|
772
|
-
if (keys.length < command.keys.length) {
|
|
773
|
-
// Matches part of a multi-key command. Buffer and wait for next
|
|
774
|
-
// stroke.
|
|
775
|
-
inputState.keyBuffer.push(key);
|
|
776
|
-
return null;
|
|
777
|
-
}
|
|
778
782
|
if (inputState.operator && command.type == 'action') {
|
|
779
783
|
// Ignore matched action commands after an operator. Operators
|
|
780
784
|
// only operate on motions. This check is really for text
|
|
781
785
|
// objects since aW, a[ etcs conflicts with a.
|
|
782
786
|
continue;
|
|
783
787
|
}
|
|
784
|
-
//
|
|
788
|
+
// Match commands that take <character> as an argument.
|
|
785
789
|
if (command.keys[keys.length - 1] == 'character') {
|
|
786
|
-
|
|
787
|
-
if(
|
|
788
|
-
switch(
|
|
790
|
+
selectedCharacter = keys[keys.length - 1];
|
|
791
|
+
if(selectedCharacter.length>1){
|
|
792
|
+
switch(selectedCharacter){
|
|
789
793
|
case '<CR>':
|
|
790
|
-
|
|
794
|
+
selectedCharacter='\n';
|
|
791
795
|
break;
|
|
792
796
|
case '<Space>':
|
|
793
|
-
|
|
797
|
+
selectedCharacter=' ';
|
|
794
798
|
break;
|
|
795
799
|
default:
|
|
796
800
|
continue;
|
|
797
801
|
}
|
|
798
802
|
}
|
|
799
803
|
}
|
|
804
|
+
// Add the command to the list of matched commands. Choose the best
|
|
805
|
+
// command later.
|
|
806
|
+
matchedCommands.push(command);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// Returns the command if it is a full match, or null if not.
|
|
811
|
+
function getFullyMatchedCommandOrNull(command) {
|
|
812
|
+
if (keys.length < command.keys.length) {
|
|
813
|
+
// Matches part of a multi-key command. Buffer and wait for next
|
|
814
|
+
// stroke.
|
|
815
|
+
inputState.keyBuffer.push(key);
|
|
816
|
+
return null;
|
|
817
|
+
} else {
|
|
818
|
+
if (command.keys[keys.length - 1] == 'character') {
|
|
819
|
+
inputState.selectedCharacter = selectedCharacter;
|
|
820
|
+
}
|
|
821
|
+
// Clear the buffer since a full match was found.
|
|
800
822
|
inputState.keyBuffer = [];
|
|
801
823
|
return command;
|
|
802
824
|
}
|
|
803
825
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
826
|
+
|
|
827
|
+
if (!matchedCommands.length) {
|
|
828
|
+
// Clear the buffer since there were no matches.
|
|
829
|
+
inputState.keyBuffer = [];
|
|
830
|
+
return null;
|
|
831
|
+
} else if (matchedCommands.length == 1) {
|
|
832
|
+
return getFullyMatchedCommandOrNull(matchedCommands[0]);
|
|
833
|
+
} else {
|
|
834
|
+
// Find the best match in the list of matchedCommands.
|
|
835
|
+
var context = vim.visualMode ? 'visual' : 'normal';
|
|
836
|
+
var bestMatch = matchedCommands[0]; // Default to first in the list.
|
|
837
|
+
for (var i = 0; i < matchedCommands.length; i++) {
|
|
838
|
+
if (matchedCommands[i].context == context) {
|
|
839
|
+
bestMatch = matchedCommands[i];
|
|
840
|
+
break;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
return getFullyMatchedCommandOrNull(bestMatch);
|
|
844
|
+
}
|
|
807
845
|
},
|
|
808
846
|
processCommand: function(cm, vim, command) {
|
|
809
847
|
vim.inputState.repeatOverride = command.repeatOverride;
|
|
@@ -2,347 +2,348 @@
|
|
|
2
2
|
* Link to the project's GitHub page:
|
|
3
3
|
* https://github.com/pickhardt/coffeescript-codemirror-mode
|
|
4
4
|
*/
|
|
5
|
-
CodeMirror.defineMode(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
} else if (lineOffset < scopeOffset) {
|
|
49
|
-
return 'dedent';
|
|
50
|
-
}
|
|
51
|
-
return null;
|
|
52
|
-
} else {
|
|
53
|
-
if (scopeOffset > 0) {
|
|
54
|
-
dedent(stream, state);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
5
|
+
CodeMirror.defineMode("coffeescript", function(conf) {
|
|
6
|
+
var ERRORCLASS = "error";
|
|
7
|
+
|
|
8
|
+
function wordRegexp(words) {
|
|
9
|
+
return new RegExp("^((" + words.join(")|(") + "))\\b");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?)/;
|
|
13
|
+
var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
|
|
14
|
+
var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
|
|
15
|
+
var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
|
|
16
|
+
|
|
17
|
+
var wordOperators = wordRegexp(["and", "or", "not",
|
|
18
|
+
"is", "isnt", "in",
|
|
19
|
+
"instanceof", "typeof"]);
|
|
20
|
+
var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
|
|
21
|
+
"switch", "try", "catch", "finally", "class"];
|
|
22
|
+
var commonKeywords = ["break", "by", "continue", "debugger", "delete",
|
|
23
|
+
"do", "in", "of", "new", "return", "then",
|
|
24
|
+
"this", "throw", "when", "until"];
|
|
25
|
+
|
|
26
|
+
var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
|
|
27
|
+
|
|
28
|
+
indentKeywords = wordRegexp(indentKeywords);
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
var stringPrefixes = /^('{3}|\"{3}|['\"])/;
|
|
32
|
+
var regexPrefixes = /^(\/{3}|\/)/;
|
|
33
|
+
var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
|
|
34
|
+
var constants = wordRegexp(commonConstants);
|
|
35
|
+
|
|
36
|
+
// Tokenizers
|
|
37
|
+
function tokenBase(stream, state) {
|
|
38
|
+
// Handle scope changes
|
|
39
|
+
if (stream.sol()) {
|
|
40
|
+
if (state.scope.align === null) state.scope.align = false;
|
|
41
|
+
var scopeOffset = state.scope.offset;
|
|
42
|
+
if (stream.eatSpace()) {
|
|
43
|
+
var lineOffset = stream.indentation();
|
|
44
|
+
if (lineOffset > scopeOffset && state.scope.type == "coffee") {
|
|
45
|
+
return "indent";
|
|
46
|
+
} else if (lineOffset < scopeOffset) {
|
|
47
|
+
return "dedent";
|
|
57
48
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
var ch = stream.peek();
|
|
63
|
-
|
|
64
|
-
// Handle docco title comment (single line)
|
|
65
|
-
if (stream.match("####")) {
|
|
66
|
-
stream.skipToEnd();
|
|
67
|
-
return 'comment';
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Handle multi line comments
|
|
71
|
-
if (stream.match("###")) {
|
|
72
|
-
state.tokenize = longComment;
|
|
73
|
-
return state.tokenize(stream, state);
|
|
49
|
+
return null;
|
|
50
|
+
} else {
|
|
51
|
+
if (scopeOffset > 0) {
|
|
52
|
+
dedent(stream, state);
|
|
74
53
|
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (stream.eatSpace()) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
75
59
|
|
|
76
|
-
|
|
77
|
-
if (ch === '#') {
|
|
78
|
-
stream.skipToEnd();
|
|
79
|
-
return 'comment';
|
|
80
|
-
}
|
|
60
|
+
var ch = stream.peek();
|
|
81
61
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
floatLiteral = true;
|
|
88
|
-
}
|
|
89
|
-
if (stream.match(/^-?\d+\.\d*/)) {
|
|
90
|
-
floatLiteral = true;
|
|
91
|
-
}
|
|
92
|
-
if (stream.match(/^-?\.\d+/)) {
|
|
93
|
-
floatLiteral = true;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (floatLiteral) {
|
|
97
|
-
// prevent from getting extra . on 1..
|
|
98
|
-
if (stream.peek() == "."){
|
|
99
|
-
stream.backUp(1);
|
|
100
|
-
}
|
|
101
|
-
return 'number';
|
|
102
|
-
}
|
|
103
|
-
// Integers
|
|
104
|
-
var intLiteral = false;
|
|
105
|
-
// Hex
|
|
106
|
-
if (stream.match(/^-?0x[0-9a-f]+/i)) {
|
|
107
|
-
intLiteral = true;
|
|
108
|
-
}
|
|
109
|
-
// Decimal
|
|
110
|
-
if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
|
|
111
|
-
intLiteral = true;
|
|
112
|
-
}
|
|
113
|
-
// Zero by itself with no other piece of number.
|
|
114
|
-
if (stream.match(/^-?0(?![\dx])/i)) {
|
|
115
|
-
intLiteral = true;
|
|
116
|
-
}
|
|
117
|
-
if (intLiteral) {
|
|
118
|
-
return 'number';
|
|
119
|
-
}
|
|
120
|
-
}
|
|
62
|
+
// Handle docco title comment (single line)
|
|
63
|
+
if (stream.match("####")) {
|
|
64
|
+
stream.skipToEnd();
|
|
65
|
+
return "comment";
|
|
66
|
+
}
|
|
121
67
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// Handle regex literals
|
|
128
|
-
if (stream.match(regexPrefixes)) {
|
|
129
|
-
if (stream.current() != '/' || stream.match(/^.*\//, false)) { // prevent highlight of division
|
|
130
|
-
state.tokenize = tokenFactory(stream.current(), 'string-2');
|
|
131
|
-
return state.tokenize(stream, state);
|
|
132
|
-
} else {
|
|
133
|
-
stream.backUp(1);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
68
|
+
// Handle multi line comments
|
|
69
|
+
if (stream.match("###")) {
|
|
70
|
+
state.tokenize = longComment;
|
|
71
|
+
return state.tokenize(stream, state);
|
|
72
|
+
}
|
|
136
73
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|| stream.match(singleOperators)
|
|
143
|
-
|| stream.match(wordOperators)) {
|
|
144
|
-
return 'operator';
|
|
145
|
-
}
|
|
146
|
-
if (stream.match(singleDelimiters)) {
|
|
147
|
-
return 'punctuation';
|
|
148
|
-
}
|
|
74
|
+
// Single line comment
|
|
75
|
+
if (ch === "#") {
|
|
76
|
+
stream.skipToEnd();
|
|
77
|
+
return "comment";
|
|
78
|
+
}
|
|
149
79
|
|
|
150
|
-
|
|
151
|
-
|
|
80
|
+
// Handle number literals
|
|
81
|
+
if (stream.match(/^-?[0-9\.]/, false)) {
|
|
82
|
+
var floatLiteral = false;
|
|
83
|
+
// Floats
|
|
84
|
+
if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
|
|
85
|
+
floatLiteral = true;
|
|
86
|
+
}
|
|
87
|
+
if (stream.match(/^-?\d+\.\d*/)) {
|
|
88
|
+
floatLiteral = true;
|
|
89
|
+
}
|
|
90
|
+
if (stream.match(/^-?\.\d+/)) {
|
|
91
|
+
floatLiteral = true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (floatLiteral) {
|
|
95
|
+
// prevent from getting extra . on 1..
|
|
96
|
+
if (stream.peek() == "."){
|
|
97
|
+
stream.backUp(1);
|
|
152
98
|
}
|
|
99
|
+
return "number";
|
|
100
|
+
}
|
|
101
|
+
// Integers
|
|
102
|
+
var intLiteral = false;
|
|
103
|
+
// Hex
|
|
104
|
+
if (stream.match(/^-?0x[0-9a-f]+/i)) {
|
|
105
|
+
intLiteral = true;
|
|
106
|
+
}
|
|
107
|
+
// Decimal
|
|
108
|
+
if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
|
|
109
|
+
intLiteral = true;
|
|
110
|
+
}
|
|
111
|
+
// Zero by itself with no other piece of number.
|
|
112
|
+
if (stream.match(/^-?0(?![\dx])/i)) {
|
|
113
|
+
intLiteral = true;
|
|
114
|
+
}
|
|
115
|
+
if (intLiteral) {
|
|
116
|
+
return "number";
|
|
117
|
+
}
|
|
118
|
+
}
|
|
153
119
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
120
|
+
// Handle strings
|
|
121
|
+
if (stream.match(stringPrefixes)) {
|
|
122
|
+
state.tokenize = tokenFactory(stream.current(), "string");
|
|
123
|
+
return state.tokenize(stream, state);
|
|
124
|
+
}
|
|
125
|
+
// Handle regex literals
|
|
126
|
+
if (stream.match(regexPrefixes)) {
|
|
127
|
+
if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
|
|
128
|
+
state.tokenize = tokenFactory(stream.current(), "string-2");
|
|
129
|
+
return state.tokenize(stream, state);
|
|
130
|
+
} else {
|
|
131
|
+
stream.backUp(1);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
157
134
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
135
|
+
// Handle operators and delimiters
|
|
136
|
+
if (stream.match(operators) || stream.match(wordOperators)) {
|
|
137
|
+
return "operator";
|
|
138
|
+
}
|
|
139
|
+
if (stream.match(delimiters)) {
|
|
140
|
+
return "punctuation";
|
|
141
|
+
}
|
|
161
142
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
143
|
+
if (stream.match(constants)) {
|
|
144
|
+
return "atom";
|
|
145
|
+
}
|
|
165
146
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return ERRORCLASS;
|
|
147
|
+
if (stream.match(keywords)) {
|
|
148
|
+
return "keyword";
|
|
169
149
|
}
|
|
170
150
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return function(stream, state) {
|
|
174
|
-
while (!stream.eol()) {
|
|
175
|
-
stream.eatWhile(/[^'"\/\\]/);
|
|
176
|
-
if (stream.eat('\\')) {
|
|
177
|
-
stream.next();
|
|
178
|
-
if (singleline && stream.eol()) {
|
|
179
|
-
return outclass;
|
|
180
|
-
}
|
|
181
|
-
} else if (stream.match(delimiter)) {
|
|
182
|
-
state.tokenize = tokenBase;
|
|
183
|
-
return outclass;
|
|
184
|
-
} else {
|
|
185
|
-
stream.eat(/['"\/]/);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
if (singleline) {
|
|
189
|
-
if (conf.mode.singleLineStringErrors) {
|
|
190
|
-
outclass = ERRORCLASS;
|
|
191
|
-
} else {
|
|
192
|
-
state.tokenize = tokenBase;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
return outclass;
|
|
196
|
-
};
|
|
151
|
+
if (stream.match(identifiers)) {
|
|
152
|
+
return "variable";
|
|
197
153
|
}
|
|
198
154
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
stream.eatWhile(/[^#]/);
|
|
202
|
-
if (stream.match("###")) {
|
|
203
|
-
state.tokenize = tokenBase;
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
stream.eatWhile("#");
|
|
207
|
-
}
|
|
208
|
-
return "comment";
|
|
155
|
+
if (stream.match(properties)) {
|
|
156
|
+
return "property";
|
|
209
157
|
}
|
|
210
158
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
159
|
+
// Handle non-detected items
|
|
160
|
+
stream.next();
|
|
161
|
+
return ERRORCLASS;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function tokenFactory(delimiter, outclass) {
|
|
165
|
+
var singleline = delimiter.length == 1;
|
|
166
|
+
return function(stream, state) {
|
|
167
|
+
while (!stream.eol()) {
|
|
168
|
+
stream.eatWhile(/[^'"\/\\]/);
|
|
169
|
+
if (stream.eat("\\")) {
|
|
170
|
+
stream.next();
|
|
171
|
+
if (singleline && stream.eol()) {
|
|
172
|
+
return outclass;
|
|
173
|
+
}
|
|
174
|
+
} else if (stream.match(delimiter)) {
|
|
175
|
+
state.tokenize = tokenBase;
|
|
176
|
+
return outclass;
|
|
221
177
|
} else {
|
|
222
|
-
|
|
178
|
+
stream.eat(/['"\/]/);
|
|
223
179
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function dedent(stream, state) {
|
|
231
|
-
if (state.scopes.length == 1) return;
|
|
232
|
-
if (state.scopes[0].type === 'coffee') {
|
|
233
|
-
var _indent = stream.indentation();
|
|
234
|
-
var _indent_index = -1;
|
|
235
|
-
for (var i = 0; i < state.scopes.length; ++i) {
|
|
236
|
-
if (_indent === state.scopes[i].offset) {
|
|
237
|
-
_indent_index = i;
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
if (_indent_index === -1) {
|
|
242
|
-
return true;
|
|
243
|
-
}
|
|
244
|
-
while (state.scopes[0].offset !== _indent) {
|
|
245
|
-
state.scopes.shift();
|
|
246
|
-
}
|
|
247
|
-
return false;
|
|
180
|
+
}
|
|
181
|
+
if (singleline) {
|
|
182
|
+
if (conf.mode.singleLineStringErrors) {
|
|
183
|
+
outclass = ERRORCLASS;
|
|
248
184
|
} else {
|
|
249
|
-
|
|
250
|
-
return false;
|
|
185
|
+
state.tokenize = tokenBase;
|
|
251
186
|
}
|
|
187
|
+
}
|
|
188
|
+
return outclass;
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function longComment(stream, state) {
|
|
193
|
+
while (!stream.eol()) {
|
|
194
|
+
stream.eatWhile(/[^#]/);
|
|
195
|
+
if (stream.match("###")) {
|
|
196
|
+
state.tokenize = tokenBase;
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
stream.eatWhile("#");
|
|
252
200
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if (
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if (current == 'then'){
|
|
288
|
-
dedent(stream, state);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if (style === 'dedent') {
|
|
293
|
-
if (dedent(stream, state)) {
|
|
294
|
-
return ERRORCLASS;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
delimiter_index = '])}'.indexOf(current);
|
|
298
|
-
if (delimiter_index !== -1) {
|
|
299
|
-
if (dedent(stream, state)) {
|
|
300
|
-
return ERRORCLASS;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'coffee') {
|
|
304
|
-
if (state.scopes.length > 1) state.scopes.shift();
|
|
305
|
-
state.dedent -= 1;
|
|
201
|
+
return "comment";
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function indent(stream, state, type) {
|
|
205
|
+
type = type || "coffee";
|
|
206
|
+
var offset = 0, align = false, alignOffset = null;
|
|
207
|
+
for (var scope = state.scope; scope; scope = scope.prev) {
|
|
208
|
+
if (scope.type === "coffee") {
|
|
209
|
+
offset = scope.offset + conf.indentUnit;
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (type !== "coffee") {
|
|
214
|
+
align = null;
|
|
215
|
+
alignOffset = stream.column() + stream.current().length;
|
|
216
|
+
}
|
|
217
|
+
state.scope = {
|
|
218
|
+
offset: offset,
|
|
219
|
+
type: type,
|
|
220
|
+
prev: state.scope,
|
|
221
|
+
align: align,
|
|
222
|
+
alignOffset: alignOffset
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function dedent(stream, state) {
|
|
227
|
+
if (!state.scope.prev) return;
|
|
228
|
+
if (state.scope.type === "coffee") {
|
|
229
|
+
var _indent = stream.indentation();
|
|
230
|
+
var matched = false;
|
|
231
|
+
for (var scope = state.scope; scope; scope = scope.prev) {
|
|
232
|
+
if (_indent === scope.offset) {
|
|
233
|
+
matched = true;
|
|
234
|
+
break;
|
|
306
235
|
}
|
|
307
|
-
|
|
308
|
-
|
|
236
|
+
}
|
|
237
|
+
if (!matched) {
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
while (state.scope.prev && state.scope.offset !== _indent) {
|
|
241
|
+
state.scope = state.scope.prev;
|
|
242
|
+
}
|
|
243
|
+
return false;
|
|
244
|
+
} else {
|
|
245
|
+
state.scope = state.scope.prev;
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function tokenLexer(stream, state) {
|
|
251
|
+
var style = state.tokenize(stream, state);
|
|
252
|
+
var current = stream.current();
|
|
253
|
+
|
|
254
|
+
// Handle "." connected identifiers
|
|
255
|
+
if (current === ".") {
|
|
256
|
+
style = state.tokenize(stream, state);
|
|
257
|
+
current = stream.current();
|
|
258
|
+
if (/^\.[\w$]+$/.test(current)) {
|
|
259
|
+
return "variable";
|
|
260
|
+
} else {
|
|
261
|
+
return ERRORCLASS;
|
|
262
|
+
}
|
|
309
263
|
}
|
|
310
264
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
},
|
|
265
|
+
// Handle scope changes.
|
|
266
|
+
if (current === "return") {
|
|
267
|
+
state.dedent += 1;
|
|
268
|
+
}
|
|
269
|
+
if (((current === "->" || current === "=>") &&
|
|
270
|
+
!state.lambda &&
|
|
271
|
+
state.scope.type == "coffee" &&
|
|
272
|
+
!stream.peek())
|
|
273
|
+
|| style === "indent") {
|
|
274
|
+
indent(stream, state);
|
|
275
|
+
}
|
|
276
|
+
var delimiter_index = "[({".indexOf(current);
|
|
277
|
+
if (delimiter_index !== -1) {
|
|
278
|
+
indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
|
|
279
|
+
}
|
|
280
|
+
if (indentKeywords.exec(current)){
|
|
281
|
+
indent(stream, state);
|
|
282
|
+
}
|
|
283
|
+
if (current == "then"){
|
|
284
|
+
dedent(stream, state);
|
|
285
|
+
}
|
|
333
286
|
|
|
334
|
-
indent: function(state) {
|
|
335
|
-
if (state.tokenize != tokenBase) {
|
|
336
|
-
return 0;
|
|
337
|
-
}
|
|
338
287
|
|
|
339
|
-
|
|
340
|
-
|
|
288
|
+
if (style === "dedent") {
|
|
289
|
+
if (dedent(stream, state)) {
|
|
290
|
+
return ERRORCLASS;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
delimiter_index = "])}".indexOf(current);
|
|
294
|
+
if (delimiter_index !== -1) {
|
|
295
|
+
if (dedent(stream, state)) {
|
|
296
|
+
return ERRORCLASS;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (state.dedent > 0 && stream.eol() && state.scope.type == "coffee") {
|
|
300
|
+
if (state.scope.prev) state.scope = state.scope.prev;
|
|
301
|
+
state.dedent -= 1;
|
|
302
|
+
}
|
|
341
303
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
304
|
+
return style;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
var external = {
|
|
308
|
+
startState: function(basecolumn) {
|
|
309
|
+
return {
|
|
310
|
+
tokenize: tokenBase,
|
|
311
|
+
scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
|
|
312
|
+
lastToken: null,
|
|
313
|
+
lambda: false,
|
|
314
|
+
dedent: 0
|
|
315
|
+
};
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
token: function(stream, state) {
|
|
319
|
+
var fillAlign = state.scope.align === null && state.scope;
|
|
320
|
+
if (fillAlign && stream.sol()) fillAlign.align = false;
|
|
321
|
+
|
|
322
|
+
var style = tokenLexer(stream, state);
|
|
323
|
+
if (fillAlign && style && style != "comment") fillAlign.align = true;
|
|
324
|
+
|
|
325
|
+
state.lastToken = {style:style, content: stream.current()};
|
|
326
|
+
|
|
327
|
+
if (stream.eol() && stream.lambda) {
|
|
328
|
+
state.lambda = false;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return style;
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
indent: function(state, text) {
|
|
335
|
+
if (state.tokenize != tokenBase) return 0;
|
|
336
|
+
var closes = state.scope.type === (text && text.charAt(0));
|
|
337
|
+
if (state.scope.align)
|
|
338
|
+
return state.scope.alignOffset - (closes ? 1 : 0);
|
|
339
|
+
else
|
|
340
|
+
return (closes ? state.scope.prev : state.scope).offset;
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
lineComment: "#",
|
|
344
|
+
fold: "indent"
|
|
345
|
+
};
|
|
346
|
+
return external;
|
|
346
347
|
});
|
|
347
348
|
|
|
348
|
-
CodeMirror.defineMIME(
|
|
349
|
+
CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
|