codemirror-rails 3.16 → 3.17

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/lib/codemirror/rails/version.rb +2 -2
  4. data/vendor/assets/javascripts/codemirror.js +104 -48
  5. data/vendor/assets/javascripts/codemirror/addons/comment/continuecomment.js +25 -15
  6. data/vendor/assets/javascripts/codemirror/addons/edit/closetag.js +28 -27
  7. data/vendor/assets/javascripts/codemirror/addons/edit/matchtags.js +10 -5
  8. data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +50 -0
  9. data/vendor/assets/javascripts/codemirror/addons/hint/html-hint.js +0 -0
  10. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +10 -7
  11. data/vendor/assets/javascripts/codemirror/addons/lint/css-lint.js +17 -0
  12. data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +1 -1
  13. data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +32 -6
  14. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode-standalone.js +1 -1
  15. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +1 -1
  16. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +1 -1
  17. data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +2 -2
  18. data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +29 -6
  19. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +13 -0
  20. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +1 -1
  21. data/vendor/assets/javascripts/codemirror/modes/css.js +15 -13
  22. data/vendor/assets/javascripts/codemirror/modes/d.js +0 -0
  23. data/vendor/assets/javascripts/codemirror/modes/dtd.js +127 -0
  24. data/vendor/assets/javascripts/codemirror/modes/fortran.js +173 -0
  25. data/vendor/assets/javascripts/codemirror/modes/haskell.js +5 -1
  26. data/vendor/assets/javascripts/codemirror/modes/less.js +47 -49
  27. data/vendor/assets/javascripts/codemirror/modes/octave.js +118 -0
  28. data/vendor/assets/javascripts/codemirror/modes/sql.js +8 -5
  29. data/vendor/assets/javascripts/codemirror/modes/toml.js +71 -0
  30. data/vendor/assets/stylesheets/codemirror.css +7 -3
  31. data/vendor/assets/stylesheets/codemirror/addons/display/fullscreen.css +1 -1
  32. data/vendor/assets/stylesheets/codemirror/addons/lint/lint.css +3 -27
  33. data/vendor/assets/stylesheets/codemirror/themes/solarized.css +2 -24
  34. metadata +24 -21
  35. data/vendor/assets/javascripts/codemirror/addons/edit/continuecomment.js +0 -44
  36. data/vendor/assets/javascripts/codemirror/addons/merge/dep/diff_match_patch.js +0 -50
  37. data/vendor/assets/javascripts/codemirror/modes/scss_test.js +0 -80
@@ -259,7 +259,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
259
259
  if (current === '.') {
260
260
  style = state.tokenize(stream, state);
261
261
  current = stream.current();
262
- if (style === 'variable') {
262
+ if (/^\.[\w$]+$/.test(current)) {
263
263
  return 'variable';
264
264
  } else {
265
265
  return ERRORCLASS;
@@ -1,10 +1,8 @@
1
- CodeMirror.defineMode("css", function(config) {
2
- return CodeMirror.getMode(config, "text/css");
3
- });
4
-
5
- CodeMirror.defineMode("css-base", function(config, parserConfig) {
1
+ CodeMirror.defineMode("css", function(config, parserConfig) {
6
2
  "use strict";
7
3
 
4
+ if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
5
+
8
6
  var indentUnit = config.indentUnit,
9
7
  hooks = parserConfig.hooks || {},
10
8
  atMediaTypes = parserConfig.atMediaTypes || {},
@@ -39,7 +37,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
39
37
  stream.match(/^\s*\w*/);
40
38
  return ret("keyword", "important");
41
39
  }
42
- else if (/\d/.test(ch)) {
40
+ else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
43
41
  stream.eatWhile(/[\w.%]/);
44
42
  return ret("number", "unit");
45
43
  }
@@ -277,16 +275,14 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
277
275
  state.stack[state.stack.length-1] = "@mediaType";
278
276
  state.stack.push("@mediaType(");
279
277
  }
278
+ else state.stack.push("(");
280
279
  }
281
280
  else if (type == ")") {
282
- if (context == "propertyValue" && state.stack[state.stack.length-2] == "@mediaType(") {
281
+ if (context == "propertyValue") {
283
282
  // In @mediaType( without closing ; after propertyValue
284
283
  state.stack.pop();
285
- state.stack.pop();
286
- }
287
- else if (context == "@mediaType(") {
288
- state.stack.pop();
289
284
  }
285
+ state.stack.pop();
290
286
  }
291
287
  else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
292
288
  else if (context == "propertyValue" && type == ";") state.stack.pop();
@@ -582,7 +578,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
582
578
  return false;
583
579
  }
584
580
  },
585
- name: "css-base"
581
+ name: "css"
586
582
  });
587
583
 
588
584
  CodeMirror.defineMIME("text/x-scss", {
@@ -593,6 +589,12 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
593
589
  valueKeywords: valueKeywords,
594
590
  allowNested: true,
595
591
  hooks: {
592
+ ":": function(stream) {
593
+ if (stream.match(/\s*{/)) {
594
+ return [null, "{"];
595
+ }
596
+ return false;
597
+ },
596
598
  "$": function(stream) {
597
599
  stream.match(/^[\w-]+/);
598
600
  if (stream.peek() == ":") {
@@ -620,6 +622,6 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
620
622
  }
621
623
  }
622
624
  },
623
- name: "css-base"
625
+ name: "css"
624
626
  });
625
627
  })();
File without changes
@@ -0,0 +1,127 @@
1
+ /*
2
+ DTD mode
3
+ Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
4
+ Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues
5
+ GitHub: @peterkroon
6
+ */
7
+
8
+ CodeMirror.defineMode("dtd", function(config) {
9
+ var indentUnit = config.indentUnit, type;
10
+ function ret(style, tp) {type = tp; return style;}
11
+
12
+ function tokenBase(stream, state) {
13
+ var ch = stream.next();
14
+
15
+ if (ch == "<" && stream.eat("!") ) {
16
+ if (stream.eatWhile(/[\-]/)) {
17
+ state.tokenize = tokenSGMLComment;
18
+ return tokenSGMLComment(stream, state);
19
+ } else if (stream.eatWhile(/[\w]/)) return ret("keyword", "doindent");
20
+ } else if (ch == "<" && stream.eat("?")) { //xml declaration
21
+ state.tokenize = inBlock("meta", "?>");
22
+ return ret("meta", ch);
23
+ } else if (ch == "#" && stream.eatWhile(/[\w]/)) return ret("atom", "tag");
24
+ else if (ch == "|") return ret("keyword", "seperator");
25
+ else if (ch.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, ch);//if(ch === ">") return ret(null, "endtag"); else
26
+ else if (ch.match(/[\[\]]/)) return ret("rule", ch);
27
+ else if (ch == "\"" || ch == "'") {
28
+ state.tokenize = tokenString(ch);
29
+ return state.tokenize(stream, state);
30
+ } else if (stream.eatWhile(/[a-zA-Z\?\+\d]/)) {
31
+ var sc = stream.current();
32
+ if( sc.substr(sc.length-1,sc.length).match(/\?|\+/) !== null )stream.backUp(1);
33
+ return ret("tag", "tag");
34
+ } else if (ch == "%" || ch == "*" ) return ret("number", "number");
35
+ else {
36
+ stream.eatWhile(/[\w\\\-_%.{,]/);
37
+ return ret(null, null);
38
+ }
39
+ }
40
+
41
+ function tokenSGMLComment(stream, state) {
42
+ var dashes = 0, ch;
43
+ while ((ch = stream.next()) != null) {
44
+ if (dashes >= 2 && ch == ">") {
45
+ state.tokenize = tokenBase;
46
+ break;
47
+ }
48
+ dashes = (ch == "-") ? dashes + 1 : 0;
49
+ }
50
+ return ret("comment", "comment");
51
+ }
52
+
53
+ function tokenString(quote) {
54
+ return function(stream, state) {
55
+ var escaped = false, ch;
56
+ while ((ch = stream.next()) != null) {
57
+ if (ch == quote && !escaped) {
58
+ state.tokenize = tokenBase;
59
+ break;
60
+ }
61
+ escaped = !escaped && ch == "\\";
62
+ }
63
+ return ret("string", "tag");
64
+ };
65
+ }
66
+
67
+ function inBlock(style, terminator) {
68
+ return function(stream, state) {
69
+ while (!stream.eol()) {
70
+ if (stream.match(terminator)) {
71
+ state.tokenize = tokenBase;
72
+ break;
73
+ }
74
+ stream.next();
75
+ }
76
+ return style;
77
+ };
78
+ }
79
+
80
+ return {
81
+ startState: function(base) {
82
+ return {tokenize: tokenBase,
83
+ baseIndent: base || 0,
84
+ stack: []};
85
+ },
86
+
87
+ token: function(stream, state) {
88
+ if (stream.eatSpace()) return null;
89
+ var style = state.tokenize(stream, state);
90
+
91
+ var context = state.stack[state.stack.length-1];
92
+ if (stream.current() == "[" || type === "doindent" || type == "[") state.stack.push("rule");
93
+ else if (type === "endtag") state.stack[state.stack.length-1] = "endtag";
94
+ else if (stream.current() == "]" || type == "]" || (type == ">" && context == "rule")) state.stack.pop();
95
+ else if (type == "[") state.stack.push("[");
96
+ return style;
97
+ },
98
+
99
+ indent: function(state, textAfter) {
100
+ var n = state.stack.length;
101
+
102
+ if( textAfter.match(/\]\s+|\]/) )n=n-1;
103
+ else if(textAfter.substr(textAfter.length-1, textAfter.length) === ">"){
104
+ if(textAfter.substr(0,1) === "<")n;
105
+ else if( type == "doindent" && textAfter.length > 1 )n;
106
+ else if( type == "doindent")n--;
107
+ else if( type == ">" && textAfter.length > 1)n;
108
+ else if( type == "tag" && textAfter !== ">")n;
109
+ else if( type == "tag" && state.stack[state.stack.length-1] == "rule")n--;
110
+ else if( type == "tag")n++;
111
+ else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule" && type === ">")n--;
112
+ else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule")n;
113
+ else if( textAfter.substr(0,1) !== "<" && textAfter.substr(0,1) === ">" )n=n-1;
114
+ else if( textAfter === ">")n;
115
+ else n=n-1;
116
+ //over rule them all
117
+ if(type == null || type == "]")n--;
118
+ }
119
+
120
+ return state.baseIndent + n * indentUnit;
121
+ },
122
+
123
+ electricChars: "]>"
124
+ };
125
+ });
126
+
127
+ CodeMirror.defineMIME("application/xml-dtd", "dtd");
@@ -0,0 +1,173 @@
1
+ CodeMirror.defineMode("fortran", function() {
2
+ function words(array) {
3
+ var keys = {};
4
+ for (var i = 0; i < array.length; ++i) {
5
+ keys[array[i]] = true;
6
+ }
7
+ return keys;
8
+ }
9
+
10
+ var keywords = words([
11
+ "abstract", "accept", "allocatable", "allocate",
12
+ "array", "assign", "asynchronous", "backspace",
13
+ "bind", "block", "byte", "call", "case",
14
+ "class", "close", "common", "contains",
15
+ "continue", "cycle", "data", "deallocate",
16
+ "decode", "deferred", "dimension", "do",
17
+ "elemental", "else", "encode", "end",
18
+ "endif", "entry", "enumerator", "equivalence",
19
+ "exit", "external", "extrinsic", "final",
20
+ "forall", "format", "function", "generic",
21
+ "go", "goto", "if", "implicit", "import", "include",
22
+ "inquire", "intent", "interface", "intrinsic",
23
+ "module", "namelist", "non_intrinsic",
24
+ "non_overridable", "none", "nopass",
25
+ "nullify", "open", "optional", "options",
26
+ "parameter", "pass", "pause", "pointer",
27
+ "print", "private", "program", "protected",
28
+ "public", "pure", "read", "recursive", "result",
29
+ "return", "rewind", "save", "select", "sequence",
30
+ "stop", "subroutine", "target", "then", "to", "type",
31
+ "use", "value", "volatile", "where", "while",
32
+ "write"]);
33
+ var builtins = words(["abort", "abs", "access", "achar", "acos",
34
+ "adjustl", "adjustr", "aimag", "aint", "alarm",
35
+ "all", "allocated", "alog", "amax", "amin",
36
+ "amod", "and", "anint", "any", "asin",
37
+ "associated", "atan", "besj", "besjn", "besy",
38
+ "besyn", "bit_size", "btest", "cabs", "ccos",
39
+ "ceiling", "cexp", "char", "chdir", "chmod",
40
+ "clog", "cmplx", "command_argument_count",
41
+ "complex", "conjg", "cos", "cosh", "count",
42
+ "cpu_time", "cshift", "csin", "csqrt", "ctime",
43
+ "c_funloc", "c_loc", "c_associated", "c_null_ptr",
44
+ "c_null_funptr", "c_f_pointer", "c_null_char",
45
+ "c_alert", "c_backspace", "c_form_feed",
46
+ "c_new_line", "c_carriage_return",
47
+ "c_horizontal_tab", "c_vertical_tab", "dabs",
48
+ "dacos", "dasin", "datan", "date_and_time",
49
+ "dbesj", "dbesj", "dbesjn", "dbesy", "dbesy",
50
+ "dbesyn", "dble", "dcos", "dcosh", "ddim", "derf",
51
+ "derfc", "dexp", "digits", "dim", "dint", "dlog",
52
+ "dlog", "dmax", "dmin", "dmod", "dnint",
53
+ "dot_product", "dprod", "dsign", "dsinh",
54
+ "dsin", "dsqrt", "dtanh", "dtan", "dtime",
55
+ "eoshift", "epsilon", "erf", "erfc", "etime",
56
+ "exit", "exp", "exponent", "extends_type_of",
57
+ "fdate", "fget", "fgetc", "float", "floor",
58
+ "flush", "fnum", "fputc", "fput", "fraction",
59
+ "fseek", "fstat", "ftell", "gerror", "getarg",
60
+ "get_command", "get_command_argument",
61
+ "get_environment_variable", "getcwd",
62
+ "getenv", "getgid", "getlog", "getpid",
63
+ "getuid", "gmtime", "hostnm", "huge", "iabs",
64
+ "iachar", "iand", "iargc", "ibclr", "ibits",
65
+ "ibset", "ichar", "idate", "idim", "idint",
66
+ "idnint", "ieor", "ierrno", "ifix", "imag",
67
+ "imagpart", "index", "int", "ior", "irand",
68
+ "isatty", "ishft", "ishftc", "isign",
69
+ "iso_c_binding", "is_iostat_end", "is_iostat_eor",
70
+ "itime", "kill", "kind", "lbound", "len", "len_trim",
71
+ "lge", "lgt", "link", "lle", "llt", "lnblnk", "loc",
72
+ "log", "logical", "long", "lshift", "lstat", "ltime",
73
+ "matmul", "max", "maxexponent", "maxloc", "maxval",
74
+ "mclock", "merge", "move_alloc", "min", "minexponent",
75
+ "minloc", "minval", "mod", "modulo", "mvbits",
76
+ "nearest", "new_line", "nint", "not", "or", "pack",
77
+ "perror", "precision", "present", "product", "radix",
78
+ "rand", "random_number", "random_seed", "range",
79
+ "real", "realpart", "rename", "repeat", "reshape",
80
+ "rrspacing", "rshift", "same_type_as", "scale",
81
+ "scan", "second", "selected_int_kind",
82
+ "selected_real_kind", "set_exponent", "shape",
83
+ "short", "sign", "signal", "sinh", "sin", "sleep",
84
+ "sngl", "spacing", "spread", "sqrt", "srand", "stat",
85
+ "sum", "symlnk", "system", "system_clock", "tan",
86
+ "tanh", "time", "tiny", "transfer", "transpose",
87
+ "trim", "ttynam", "ubound", "umask", "unlink",
88
+ "unpack", "verify", "xor", "zabs", "zcos", "zexp",
89
+ "zlog", "zsin", "zsqrt"]);
90
+
91
+ var dataTypes = words(["c_bool", "c_char", "c_double", "c_double_complex",
92
+ "c_float", "c_float_complex", "c_funptr", "c_int",
93
+ "c_int16_t", "c_int32_t", "c_int64_t", "c_int8_t",
94
+ "c_int_fast16_t", "c_int_fast32_t", "c_int_fast64_t",
95
+ "c_int_fast8_t", "c_int_least16_t", "c_int_least32_t",
96
+ "c_int_least64_t", "c_int_least8_t", "c_intmax_t",
97
+ "c_intptr_t", "c_long", "c_long_double",
98
+ "c_long_double_complex", "c_long_long", "c_ptr",
99
+ "c_short", "c_signed_char", "c_size_t", "character",
100
+ "complex", "double", "integer", "logical", "real"]);
101
+ var isOperatorChar = /[+\-*&=<>\/\:]/;
102
+ var litOperator = new RegExp("(\.and\.|\.or\.|\.eq\.|\.lt\.|\.le\.|\.gt\.|\.ge\.|\.ne\.|\.not\.|\.eqv\.|\.neqv\.)", "i");
103
+
104
+ function tokenBase(stream, state) {
105
+
106
+ if (stream.match(litOperator)){
107
+ return 'operator';
108
+ }
109
+
110
+ var ch = stream.next();
111
+ if (ch == "!") {
112
+ stream.skipToEnd();
113
+ return "comment";
114
+ }
115
+ if (ch == '"' || ch == "'") {
116
+ state.tokenize = tokenString(ch);
117
+ return state.tokenize(stream, state);
118
+ }
119
+ if (/[\[\]\(\),]/.test(ch)) {
120
+ return null;
121
+ }
122
+ if (/\d/.test(ch)) {
123
+ stream.eatWhile(/[\w\.]/);
124
+ return "number";
125
+ }
126
+ if (isOperatorChar.test(ch)) {
127
+ stream.eatWhile(isOperatorChar);
128
+ return "operator";
129
+ }
130
+ stream.eatWhile(/[\w\$_]/);
131
+ var word = stream.current().toLowerCase();
132
+
133
+ if (keywords.hasOwnProperty(word)){
134
+ return 'keyword';
135
+ }
136
+ if (builtins.hasOwnProperty(word) || dataTypes.hasOwnProperty(word)) {
137
+ return 'builtin';
138
+ }
139
+ return "variable";
140
+ }
141
+
142
+ function tokenString(quote) {
143
+ return function(stream, state) {
144
+ var escaped = false, next, end = false;
145
+ while ((next = stream.next()) != null) {
146
+ if (next == quote && !escaped) {
147
+ end = true;
148
+ break;
149
+ }
150
+ escaped = !escaped && next == "\\";
151
+ }
152
+ if (end || !escaped) state.tokenize = null;
153
+ return "string";
154
+ };
155
+ }
156
+
157
+ // Interface
158
+
159
+ return {
160
+ startState: function() {
161
+ return {tokenize: null};
162
+ },
163
+
164
+ token: function(stream, state) {
165
+ if (stream.eatSpace()) return null;
166
+ var style = (state.tokenize || tokenBase)(stream, state);
167
+ if (style == "comment" || style == "meta") return style;
168
+ return style;
169
+ }
170
+ };
171
+ });
172
+
173
+ CodeMirror.defineMIME("text/x-fortran", "fortran");
@@ -1,4 +1,4 @@
1
- CodeMirror.defineMode("haskell", function() {
1
+ CodeMirror.defineMode("haskell", function(_config, modeConfig) {
2
2
 
3
3
  function switchState(source, setState, f) {
4
4
  setState(f);
@@ -221,6 +221,10 @@ CodeMirror.defineMode("haskell", function() {
221
221
  "unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip",
222
222
  "zip3", "zipWith", "zipWith3");
223
223
 
224
+ var override = modeConfig.overrideKeywords;
225
+ if (override) for (var word in override) if (override.hasOwnProperty(word))
226
+ wkw[word] = override[word];
227
+
224
228
  return wkw;
225
229
  })();
226
230
 
@@ -1,7 +1,8 @@
1
1
  /*
2
2
  LESS mode - http://www.lesscss.org/
3
3
  Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
4
- Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues GitHub: @peterkroon
4
+ Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues
5
+ GitHub: @peterkroon
5
6
  */
6
7
 
7
8
  CodeMirror.defineMode("less", function(config) {
@@ -17,68 +18,60 @@ CodeMirror.defineMode("less", function(config) {
17
18
  else if (ch == "/" && stream.eat("*")) {
18
19
  state.tokenize = tokenCComment;
19
20
  return tokenCComment(stream, state);
20
- }
21
- else if (ch == "<" && stream.eat("!")) {
21
+ } else if (ch == "<" && stream.eat("!")) {
22
22
  state.tokenize = tokenSGMLComment;
23
23
  return tokenSGMLComment(stream, state);
24
- }
25
- else if (ch == "=") ret(null, "compare");
24
+ } else if (ch == "=") ret(null, "compare");
26
25
  else if (ch == "|" && stream.eat("=")) return ret(null, "compare");
27
26
  else if (ch == "\"" || ch == "'") {
28
27
  state.tokenize = tokenString(ch);
29
28
  return state.tokenize(stream, state);
30
- }
31
- else if (ch == "/") { // e.g.: .png will not be parsed as a class
29
+ } else if (ch == "/") { // e.g.: .png will not be parsed as a class
32
30
  if(stream.eat("/")){
33
31
  state.tokenize = tokenSComment;
34
32
  return tokenSComment(stream, state);
35
- }else{
36
- if(type == "string" || type == "(")return ret("string", "string");
37
- if(state.stack[state.stack.length-1] != undefined)return ret(null, ch);
33
+ } else {
34
+ if(type == "string" || type == "(") return ret("string", "string");
35
+ if(state.stack[state.stack.length-1] != undefined) return ret(null, ch);
38
36
  stream.eatWhile(/[\a-zA-Z0-9\-_.\s]/);
39
37
  if( /\/|\)|#/.test(stream.peek() || (stream.eatSpace() && stream.peek() == ")")) || stream.eol() )return ret("string", "string"); // let url(/images/logo.png) without quotes return as string
40
38
  }
41
- }
42
- else if (ch == "!") {
39
+ } else if (ch == "!") {
43
40
  stream.match(/^\s*\w*/);
44
41
  return ret("keyword", "important");
45
- }
46
- else if (/\d/.test(ch)) {
42
+ } else if (/\d/.test(ch)) {
47
43
  stream.eatWhile(/[\w.%]/);
48
44
  return ret("number", "unit");
49
- }
50
- else if (/[,+<>*\/]/.test(ch)) {
45
+ } else if (/[,+<>*\/]/.test(ch)) {
51
46
  if(stream.peek() == "=" || type == "a")return ret("string", "string");
47
+ if(ch === ",")return ret(null, ch);
52
48
  return ret(null, "select-op");
53
- }
54
- else if (/[;{}:\[\]()~\|]/.test(ch)) {
49
+ } else if (/[;{}:\[\]()~\|]/.test(ch)) {
55
50
  if(ch == ":"){
56
51
  stream.eatWhile(/[a-z\\\-]/);
57
52
  if( selectors.test(stream.current()) ){
58
53
  return ret("tag", "tag");
59
- }else if(stream.peek() == ":"){//::-webkit-search-decoration
54
+ } else if(stream.peek() == ":"){//::-webkit-search-decoration
60
55
  stream.next();
61
56
  stream.eatWhile(/[a-z\\\-]/);
62
57
  if(stream.current().match(/\:\:\-(o|ms|moz|webkit)\-/))return ret("string", "string");
63
58
  if( selectors.test(stream.current().substring(1)) )return ret("tag", "tag");
64
59
  return ret(null, ch);
65
- }else{
60
+ } else {
66
61
  return ret(null, ch);
67
62
  }
68
- }else if(ch == "~"){
63
+ } else if(ch == "~"){
69
64
  if(type == "r")return ret("string", "string");
70
- }else{
65
+ } else {
71
66
  return ret(null, ch);
72
67
  }
73
- }
74
- else if (ch == ".") {
68
+ } else if (ch == ".") {
75
69
  if(type == "(" || type == "string")return ret("string", "string"); // allow url(../image.png)
76
70
  stream.eatWhile(/[\a-zA-Z0-9\-_]/);
77
71
  if(stream.peek() == " ")stream.eatSpace();
78
72
  if(stream.peek() == ")")return ret("number", "unit");//rgba(0,0,0,.25);
79
73
  return ret("tag", "tag");
80
- }
81
- else if (ch == "#") {
74
+ } else if (ch == "#") {
82
75
  //we don't eat white-space, we want the hex color and or id only
83
76
  stream.eatWhile(/[A-Za-z0-9]/);
84
77
  //check if there is a proper hex color length e.g. #eee || #eeeEEE
@@ -93,43 +86,41 @@ CodeMirror.defineMode("less", function(config) {
93
86
  //#time { color: #aaa }
94
87
  else if(stream.peek() == "}" )return ret("number", "unit");
95
88
  //we have a valid hex color value, parse as id whenever an element/class is defined after the hex(id) value e.g. #eee aaa || #eee .aaa
96
- else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag");
89
+ else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag");
97
90
  //when a hex value is on the end of a line, parse as id
98
- else if(stream.eol())return ret("atom", "tag");
91
+ else if(stream.eol())return ret("atom", "tag");
99
92
  //default
100
- else return ret("number", "unit");
101
- }else{//when not a valid hexvalue in the current stream e.g. #footer
93
+ else return ret("number", "unit");
94
+ } else {//when not a valid hexvalue in the current stream e.g. #footer
102
95
  stream.eatWhile(/[\w\\\-]/);
103
96
  return ret("atom", "tag");
104
97
  }
105
- }else{//when not a valid hexvalue length
98
+ } else {//when not a valid hexvalue length
106
99
  stream.eatWhile(/[\w\\\-]/);
107
100
  return ret("atom", "tag");
108
101
  }
109
- }
110
- else if (ch == "&") {
102
+ } else if (ch == "&") {
111
103
  stream.eatWhile(/[\w\-]/);
112
104
  return ret(null, ch);
113
- }
114
- else {
105
+ } else {
115
106
  stream.eatWhile(/[\w\\\-_%.{]/);
116
107
  if(type == "string"){
117
108
  return ret("string", "string");
118
- }else if(stream.current().match(/(^http$|^https$)/) != null){
109
+ } else if(stream.current().match(/(^http$|^https$)/) != null){
119
110
  stream.eatWhile(/[\w\\\-_%.{:\/]/);
120
111
  return ret("string", "string");
121
- }else if(stream.peek() == "<" || stream.peek() == ">"){
112
+ } else if(stream.peek() == "<" || stream.peek() == ">" || stream.peek() == "+"){
122
113
  return ret("tag", "tag");
123
- }else if( /\(/.test(stream.peek()) ){
114
+ } else if( /\(/.test(stream.peek()) ){
124
115
  return ret(null, ch);
125
- }else if (stream.peek() == "/" && state.stack[state.stack.length-1] != undefined){ // url(dir/center/image.png)
116
+ } else if (stream.peek() == "/" && state.stack[state.stack.length-1] != undefined){ // url(dir/center/image.png)
126
117
  return ret("string", "string");
127
- }else if( stream.current().match(/\-\d|\-.\d/) ){ // match e.g.: -5px -0.4 etc... only colorize the minus sign
118
+ } else if( stream.current().match(/\-\d|\-.\d/) ){ // match e.g.: -5px -0.4 etc... only colorize the minus sign
128
119
  //commment out these 2 comment if you want the minus sign to be parsed as null -500px
129
120
  //stream.backUp(stream.current().length-1);
130
- //return ret(null, ch); //console.log( stream.current() );
121
+ //return ret(null, ch);
131
122
  return ret("number", "unit");
132
- }else if( /\/|[\s\)]/.test(stream.peek() || stream.eol() || (stream.eatSpace() && stream.peek() == "/")) && stream.current().indexOf(".") !== -1){
123
+ } else if( /\/|[\s\)]/.test(stream.peek() || stream.eol() || (stream.eatSpace() && stream.peek() == "/")) && stream.current().indexOf(".") !== -1){
133
124
  if(stream.current().substring(stream.current().length-1,stream.current().length) == "{"){
134
125
  stream.backUp(1);
135
126
  return ret("tag", "tag");
@@ -137,14 +128,15 @@ CodeMirror.defineMode("less", function(config) {
137
128
  stream.eatSpace();
138
129
  if( /[{<>.a-zA-Z\/]/.test(stream.peek()) || stream.eol() )return ret("tag", "tag"); // e.g. button.icon-plus
139
130
  return ret("string", "string"); // let url(/images/logo.png) without quotes return as string
140
- }else if( stream.eol() || stream.peek() == "[" || stream.peek() == "#" || type == "tag" ){
131
+ } else if( stream.eol() || stream.peek() == "[" || stream.peek() == "#" || type == "tag" ){
141
132
  if(stream.current().substring(stream.current().length-1,stream.current().length) == "{")stream.backUp(1);
142
133
  return ret("tag", "tag");
143
- }else if(type == "compare" || type == "a" || type == "("){
134
+ } else if(type == "compare" || type == "a" || type == "("){
144
135
  return ret("string", "string");
145
- }else if(type == "|" || stream.current() == "-" || type == "["){
136
+ } else if(type == "|" || stream.current() == "-" || type == "["){
137
+ if(type == "|" )return ret("tag", "tag");
146
138
  return ret(null, ch);
147
- }else if(stream.peek() == ":") {
139
+ } else if(stream.peek() == ":") {
148
140
  stream.next();
149
141
  var t_v = stream.peek() == ":" ? true : false;
150
142
  if(!t_v){
@@ -156,11 +148,14 @@ CodeMirror.defineMode("less", function(config) {
156
148
  stream.backUp(new_pos-(old_pos-1));
157
149
  return ret("tag", "tag");
158
150
  } else stream.backUp(new_pos-(old_pos-1));
159
- }else{
151
+ } else {
160
152
  stream.backUp(1);
161
153
  }
162
154
  if(t_v)return ret("tag", "tag"); else return ret("variable", "variable");
163
- }else{
155
+ } else if(state.stack[state.stack.length-1] === "font-family"){
156
+ return ret(null, null);
157
+ } else {
158
+ if(state.stack[state.stack.length-1] === "{" || type === "select-op" || (state.stack[state.stack.length-1] === "rule" && type === ",") )return ret("tag", "tag");
164
159
  return ret("variable", "variable");
165
160
  }
166
161
  }
@@ -238,12 +233,15 @@ CodeMirror.defineMode("less", function(config) {
238
233
  }
239
234
  else if (type == "}") state.stack.pop();
240
235
  else if (type == "@media") state.stack.push("@media");
241
- else if (context == "{" && type != "comment") state.stack.push("rule");
236
+ else if (stream.current() === "font-family") state.stack[state.stack.length-1] = "font-family";
237
+ else if (context == "{" && type != "comment" && type !== "tag") state.stack.push("rule");
238
+ else if (stream.peek() === ":" && stream.current().match(/@|#/) === null) style = type;
242
239
  return style;
243
240
  },
244
241
 
245
242
  indent: function(state, textAfter) {
246
243
  var n = state.stack.length;
244
+
247
245
  if (/^\}/.test(textAfter))
248
246
  n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
249
247
  return state.baseIndent + n * indentUnit;