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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +42 -19
  4. data/vendor/assets/javascripts/codemirror/addons/edit/closetag.js +1 -1
  5. data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +1 -1
  6. data/vendor/assets/javascripts/codemirror/addons/fold/foldcode.js +6 -4
  7. data/vendor/assets/javascripts/codemirror/addons/fold/foldgutter.js +2 -0
  8. data/vendor/assets/javascripts/codemirror/addons/fold/indent-fold.js +21 -7
  9. data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +3 -19
  10. data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +105 -0
  11. data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +1 -0
  12. data/vendor/assets/javascripts/codemirror/addons/search/search.js +2 -0
  13. data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +1 -1
  14. data/vendor/assets/javascripts/codemirror/addons/wrap/hardwrap.js +99 -0
  15. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +55 -17
  16. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +314 -313
  17. data/vendor/assets/javascripts/codemirror/modes/css.js +19 -7
  18. data/vendor/assets/javascripts/codemirror/modes/eiffel.js +147 -0
  19. data/vendor/assets/javascripts/codemirror/modes/gfm.js +2 -1
  20. data/vendor/assets/javascripts/codemirror/modes/gherkin.js +168 -0
  21. data/vendor/assets/javascripts/codemirror/modes/less.js +110 -22
  22. data/vendor/assets/javascripts/codemirror/modes/php.js +4 -4
  23. data/vendor/assets/javascripts/codemirror/modes/smartymixed.js +6 -1
  24. data/vendor/assets/javascripts/codemirror/modes/sql.js +15 -2
  25. data/vendor/assets/javascripts/codemirror/modes/xml.js +7 -3
  26. data/vendor/assets/stylesheets/codemirror.css +1 -1
  27. data/vendor/assets/stylesheets/codemirror/addons/fold/foldgutter.css +21 -0
  28. data/vendor/assets/stylesheets/codemirror/addons/lint/lint.css +1 -0
  29. data/vendor/assets/stylesheets/codemirror/themes/3024-day.css +1 -1
  30. data/vendor/assets/stylesheets/codemirror/themes/3024-night.css +1 -1
  31. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +1 -1
  32. data/vendor/assets/stylesheets/codemirror/themes/base16-dark.css +1 -1
  33. data/vendor/assets/stylesheets/codemirror/themes/base16-light.css +1 -1
  34. data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +1 -1
  35. data/vendor/assets/stylesheets/codemirror/themes/cobalt.css +1 -1
  36. data/vendor/assets/stylesheets/codemirror/themes/eclipse.css +1 -1
  37. data/vendor/assets/stylesheets/codemirror/themes/elegant.css +1 -1
  38. data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +1 -1
  39. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +1 -1
  40. data/vendor/assets/stylesheets/codemirror/themes/mbo.css +35 -0
  41. data/vendor/assets/stylesheets/codemirror/themes/midnight.css +1 -1
  42. data/vendor/assets/stylesheets/codemirror/themes/monokai.css +1 -1
  43. data/vendor/assets/stylesheets/codemirror/themes/night.css +1 -1
  44. data/vendor/assets/stylesheets/codemirror/themes/paraiso-dark.css +1 -1
  45. data/vendor/assets/stylesheets/codemirror/themes/paraiso-light.css +1 -1
  46. data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +1 -1
  47. data/vendor/assets/stylesheets/codemirror/themes/solarized.css +7 -7
  48. data/vendor/assets/stylesheets/codemirror/themes/the-matrix.css +1 -1
  49. data/vendor/assets/stylesheets/codemirror/themes/tomorrow-night-eighties.css +1 -1
  50. data/vendor/assets/stylesheets/codemirror/themes/twilight.css +1 -1
  51. data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +1 -1
  52. data/vendor/assets/stylesheets/codemirror/themes/xq-dark.css +1 -1
  53. data/vendor/assets/stylesheets/codemirror/themes/xq-light.css +1 -1
  54. metadata +7 -1
@@ -3,7 +3,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
3
3
 
4
4
  if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
5
5
 
6
- var indentUnit = config.indentUnit,
6
+ var indentUnit = config.indentUnit || config.tabSize || 2,
7
7
  hooks = parserConfig.hooks || {},
8
8
  atMediaTypes = parserConfig.atMediaTypes || {},
9
9
  atMediaFeatures = parserConfig.atMediaFeatures || {},
@@ -259,8 +259,13 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
259
259
  }
260
260
  else if (type == "}") {
261
261
  if (context == "interpolation") style = "operator";
262
- state.stack.pop();
263
- if (context == "propertyValue") state.stack.pop();
262
+ // Pop off end of array until { is reached
263
+ while(state.stack.length){
264
+ var removed = state.stack.pop();
265
+ if(removed.indexOf("{") > -1){
266
+ break;
267
+ }
268
+ }
264
269
  }
265
270
  else if (type == "interpolation") state.stack.push("interpolation");
266
271
  else if (type == "@media") state.stack.push("@media");
@@ -278,11 +283,13 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
278
283
  else state.stack.push("(");
279
284
  }
280
285
  else if (type == ")") {
281
- if (context == "propertyValue") {
282
- // In @mediaType( without closing ; after propertyValue
283
- state.stack.pop();
286
+ // Pop off end of array until ( is reached
287
+ while(state.stack.length){
288
+ var removed = state.stack.pop();
289
+ if(removed.indexOf("(") > -1){
290
+ break;
291
+ }
284
292
  }
285
- state.stack.pop();
286
293
  }
287
294
  else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
288
295
  else if (context == "propertyValue" && type == ";") state.stack.pop();
@@ -602,6 +609,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
602
609
  }
603
610
  return ["variable", "variable"];
604
611
  },
612
+ ",": function(_stream, state) {
613
+ if (state.stack[state.stack.length - 1] == "propertyValue") {
614
+ return ["operator", ";"];
615
+ }
616
+ },
605
617
  "/": function(stream, state) {
606
618
  if (stream.eat("/")) {
607
619
  stream.skipToEnd();
@@ -0,0 +1,147 @@
1
+ CodeMirror.defineMode("eiffel", function() {
2
+ function wordObj(words) {
3
+ var o = {};
4
+ for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
5
+ return o;
6
+ }
7
+ var keywords = wordObj([
8
+ 'note',
9
+ 'across',
10
+ 'when',
11
+ 'variant',
12
+ 'until',
13
+ 'unique',
14
+ 'undefine',
15
+ 'then',
16
+ 'strip',
17
+ 'select',
18
+ 'retry',
19
+ 'rescue',
20
+ 'require',
21
+ 'rename',
22
+ 'reference',
23
+ 'redefine',
24
+ 'prefix',
25
+ 'once',
26
+ 'old',
27
+ 'obsolete',
28
+ 'loop',
29
+ 'local',
30
+ 'like',
31
+ 'is',
32
+ 'inspect',
33
+ 'infix',
34
+ 'include',
35
+ 'if',
36
+ 'frozen',
37
+ 'from',
38
+ 'external',
39
+ 'export',
40
+ 'ensure',
41
+ 'end',
42
+ 'elseif',
43
+ 'else',
44
+ 'do',
45
+ 'creation',
46
+ 'create',
47
+ 'check',
48
+ 'alias',
49
+ 'agent',
50
+ 'separate',
51
+ 'invariant',
52
+ 'inherit',
53
+ 'indexing',
54
+ 'feature',
55
+ 'expanded',
56
+ 'deferred',
57
+ 'class',
58
+ 'Void',
59
+ 'True',
60
+ 'Result',
61
+ 'Precursor',
62
+ 'False',
63
+ 'Current',
64
+ 'create',
65
+ 'attached',
66
+ 'detachable',
67
+ 'as',
68
+ 'and',
69
+ 'implies',
70
+ 'not',
71
+ 'or'
72
+ ]);
73
+ var operators = wordObj([":=", "and then","and", "or","<<",">>"]);
74
+ var curPunc;
75
+
76
+ function chain(newtok, stream, state) {
77
+ state.tokenize.push(newtok);
78
+ return newtok(stream, state);
79
+ }
80
+
81
+ function tokenBase(stream, state) {
82
+ curPunc = null;
83
+ if (stream.eatSpace()) return null;
84
+ var ch = stream.next();
85
+ if (ch == '"'||ch == "'") {
86
+ return chain(readQuoted(ch, "string"), stream, state);
87
+ } else if (ch == "-"&&stream.eat("-")) {
88
+ stream.skipToEnd();
89
+ return "comment";
90
+ } else if (ch == ":"&&stream.eat("=")) {
91
+ return "operator";
92
+ } else if (/[0-9]/.test(ch)) {
93
+ stream.eatWhile(/[xXbBCc0-9\.]/);
94
+ stream.eat(/[\?\!]/);
95
+ return "ident";
96
+ } else if (/[a-zA-Z_0-9]/.test(ch)) {
97
+ stream.eatWhile(/[a-zA-Z_0-9]/);
98
+ stream.eat(/[\?\!]/);
99
+ return "ident";
100
+ } else if (/[=+\-\/*^%<>~]/.test(ch)) {
101
+ stream.eatWhile(/[=+\-\/*^%<>~]/);
102
+ return "operator";
103
+ } else {
104
+ return null;
105
+ }
106
+ }
107
+
108
+ function readQuoted(quote, style, unescaped) {
109
+ return function(stream, state) {
110
+ var escaped = false, ch;
111
+ while ((ch = stream.next()) != null) {
112
+ if (ch == quote && (unescaped || !escaped)) {
113
+ state.tokenize.pop();
114
+ break;
115
+ }
116
+ escaped = !escaped && ch == "%";
117
+ }
118
+ return style;
119
+ };
120
+ }
121
+
122
+ return {
123
+ startState: function() {
124
+ return {tokenize: [tokenBase]};
125
+ },
126
+
127
+ token: function(stream, state) {
128
+ var style = state.tokenize[state.tokenize.length-1](stream, state);
129
+ if (style == "ident") {
130
+ var word = stream.current();
131
+ style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
132
+ : operators.propertyIsEnumerable(stream.current()) ? "operator"
133
+ : /^[A-Z][A-Z_0-9]*$/g.test(word) ? "tag"
134
+ : /^0[bB][0-1]+$/g.test(word) ? "number"
135
+ : /^0[cC][0-7]+$/g.test(word) ? "number"
136
+ : /^0[xX][a-fA-F0-9]+$/g.test(word) ? "number"
137
+ : /^([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)$/g.test(word) ? "number"
138
+ : /^[0-9]+$/g.test(word) ? "number"
139
+ : "variable";
140
+ }
141
+ return style;
142
+ },
143
+ lineComment: "--"
144
+ };
145
+ });
146
+
147
+ CodeMirror.defineMIME("text/x-eiffel", "eiffel");
@@ -75,7 +75,8 @@ CodeMirror.defineMode("gfm", function(config) {
75
75
  return "link";
76
76
  }
77
77
  }
78
- if (stream.match(/^((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i)) {
78
+ if (stream.match(/^((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i) &&
79
+ stream.string.slice(stream.start - 2, stream.start) != "](") {
79
80
  // URLs
80
81
  // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
81
82
  // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine
@@ -0,0 +1,168 @@
1
+ /*
2
+ Gherkin mode - http://www.cukes.info/
3
+ Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues
4
+ */
5
+
6
+ // Following Objs from Brackets implementation: https://github.com/tregusti/brackets-gherkin/blob/master/main.js
7
+ //var Quotes = {
8
+ // SINGLE: 1,
9
+ // DOUBLE: 2
10
+ //};
11
+
12
+ //var regex = {
13
+ // keywords: /(Feature| {2}(Scenario|In order to|As|I)| {4}(Given|When|Then|And))/
14
+ //};
15
+
16
+ CodeMirror.defineMode("gherkin", function () {
17
+ return {
18
+ startState: function () {
19
+ return {
20
+ lineNumber: 0,
21
+ tableHeaderLine: null,
22
+ allowFeature: true,
23
+ allowBackground: false,
24
+ allowScenario: false,
25
+ allowSteps: false,
26
+ allowPlaceholders: false,
27
+ inMultilineArgument: false,
28
+ inMultilineString: false,
29
+ inMultilineTable: false
30
+ };
31
+ },
32
+ token: function (stream, state) {
33
+ if (stream.sol()) {
34
+ state.lineNumber++;
35
+ }
36
+ stream.eatSpace();
37
+
38
+ // INSIDE OF MULTILINE ARGUMENTS
39
+ if (state.inMultilineArgument) {
40
+
41
+ // STRING
42
+ if (state.inMultilineString) {
43
+ if (stream.match('"""')) {
44
+ state.inMultilineString = false;
45
+ state.inMultilineArgument = false;
46
+ } else {
47
+ stream.match(/.*/);
48
+ }
49
+ return "string";
50
+ }
51
+
52
+ // TABLE
53
+ if (state.inMultilineTable) {
54
+ // New table, assume first row is headers
55
+ if (state.tableHeaderLine === null) {
56
+ state.tableHeaderLine = state.lineNumber;
57
+ }
58
+
59
+ if (stream.match(/\|\s*/)) {
60
+ if (stream.eol()) {
61
+ state.inMultilineTable = false;
62
+ }
63
+ return "bracket";
64
+ } else {
65
+ stream.match(/[^\|]*/);
66
+ return state.tableHeaderLine === state.lineNumber ? "property" : "string";
67
+ }
68
+ }
69
+
70
+ // DETECT START
71
+ if (stream.match('"""')) {
72
+ // String
73
+ state.inMultilineString = true;
74
+ return "string";
75
+ } else if (stream.match("|")) {
76
+ // Table
77
+ state.inMultilineTable = true;
78
+ return "bracket";
79
+ } else {
80
+ // Or abort
81
+ state.inMultilineArgument = false;
82
+ state.tableHeaderLine = null;
83
+ }
84
+
85
+
86
+ return null;
87
+ }
88
+
89
+ // LINE COMMENT
90
+ if (stream.match(/#.*/)) {
91
+ return "comment";
92
+
93
+ // TAG
94
+ } else if (stream.match(/@\S+/)) {
95
+ return "def";
96
+
97
+ // FEATURE
98
+ } else if (state.allowFeature && stream.match(/Feature:/)) {
99
+ state.allowScenario = true;
100
+ state.allowBackground = true;
101
+ state.allowPlaceholders = false;
102
+ state.allowSteps = false;
103
+ return "keyword";
104
+
105
+ // BACKGROUND
106
+ } else if (state.allowBackground && stream.match("Background:")) {
107
+ state.allowPlaceholders = false;
108
+ state.allowSteps = true;
109
+ state.allowBackground = false;
110
+ return "keyword";
111
+
112
+ // SCENARIO OUTLINE
113
+ } else if (state.allowScenario && stream.match("Scenario Outline:")) {
114
+ state.allowPlaceholders = true;
115
+ state.allowSteps = true;
116
+ return "keyword";
117
+
118
+ // EXAMPLES
119
+ } else if (state.allowScenario && stream.match("Examples:")) {
120
+ state.allowPlaceholders = false;
121
+ state.allowSteps = true;
122
+ state.allowBackground = false;
123
+ state.inMultilineArgument = true;
124
+ return "keyword";
125
+
126
+ // SCENARIO
127
+ } else if (state.allowScenario && stream.match(/Scenario:/)) {
128
+ state.allowPlaceholders = false;
129
+ state.allowSteps = true;
130
+ state.allowBackground = false;
131
+ return "keyword";
132
+
133
+ // STEPS
134
+ } else if (state.allowSteps && stream.match(/(Given|When|Then|And|But)/)) {
135
+ return "keyword";
136
+
137
+ // INLINE STRING
138
+ } else if (!state.inMultilineArgument && stream.match(/"/)) {
139
+ stream.match(/.*?"/);
140
+ return "string";
141
+
142
+ // MULTILINE ARGUMENTS
143
+ } else if (state.allowSteps && stream.eat(":")) {
144
+ if (stream.match(/\s*$/)) {
145
+ state.inMultilineArgument = true;
146
+ return "keyword";
147
+ } else {
148
+ return null;
149
+ }
150
+
151
+ } else if (state.allowSteps && stream.match("<")) {
152
+ if (stream.match(/.*?>/)) {
153
+ return "property";
154
+ } else {
155
+ return null;
156
+ }
157
+
158
+ // Fall through
159
+ } else {
160
+ stream.eatWhile(/[^":<]/);
161
+ }
162
+
163
+ return null;
164
+ }
165
+ };
166
+ });
167
+
168
+ CodeMirror.defineMIME("text/x-feature", "gherkin");
@@ -32,9 +32,9 @@ CodeMirror.defineMode("less", function(config) {
32
32
  return tokenSComment(stream, state);
33
33
  } else {
34
34
  if(type == "string" || type == "(") return ret("string", "string");
35
- if(state.stack[state.stack.length-1] != undefined) return ret(null, ch);
35
+ if(state.stack[state.stack.length-1] !== undefined) return ret(null, ch);
36
36
  stream.eatWhile(/[\a-zA-Z0-9\-_.\s]/);
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
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
38
38
  }
39
39
  } else if (ch == "!") {
40
40
  stream.match(/^\s*\w*/);
@@ -66,10 +66,11 @@ CodeMirror.defineMode("less", function(config) {
66
66
  return ret(null, ch);
67
67
  }
68
68
  } else if (ch == ".") {
69
- if(type == "(" || type == "string")return ret("string", "string"); // allow url(../image.png)
69
+ if(type == "(")return ret("string", "string"); // allow url(../image.png)
70
70
  stream.eatWhile(/[\a-zA-Z0-9\-_]/);
71
- if(stream.peek() == " ")stream.eatSpace();
72
- if(stream.peek() == ")")return ret("number", "unit");//rgba(0,0,0,.25);
71
+ if(stream.peek() === " ")stream.eatSpace();
72
+ if(stream.peek() === ")" || type === ":")return ret("number", "unit");//rgba(0,0,0,.25);
73
+ else if(state.stack[state.stack.length-1] === "rule" && stream.peek().match(/{|,|\+|\(/) === null)return ret("number", "unit");
73
74
  return ret("tag", "tag");
74
75
  } else if (ch == "#") {
75
76
  //we don't eat white-space, we want the hex color and or id only
@@ -82,21 +83,24 @@ CodeMirror.defineMode("less", function(config) {
82
83
  //eat white-space
83
84
  stream.eatSpace();
84
85
  //when hex value declaration doesn't end with [;,] but is does with a slash/cc comment treat it as an id, just like the other hex values that don't end with[;,]
85
- if( /[\/<>.(){!$%^&*_\-\\?=+\|#'~`]/.test(stream.peek()) )return ret("atom", "tag");
86
+ if( /[\/<>.(){!$%^&*_\-\\?=+\|#'~`]/.test(stream.peek()) ){
87
+ if(type === "select-op")return ret("number", "unit"); else return ret("atom", "tag");
88
+ }
86
89
  //#time { color: #aaa }
87
90
  else if(stream.peek() == "}" )return ret("number", "unit");
88
91
  //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
89
- else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag");
92
+ else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag");
90
93
  //when a hex value is on the end of a line, parse as id
91
- else if(stream.eol())return ret("atom", "tag");
94
+ else if(stream.eol())return ret("atom", "tag");
92
95
  //default
93
- else return ret("number", "unit");
96
+ else return ret("number", "unit");
94
97
  } else {//when not a valid hexvalue in the current stream e.g. #footer
95
98
  stream.eatWhile(/[\w\\\-]/);
96
- return ret("atom", "tag");
99
+ return ret("atom", stream.current());
97
100
  }
98
101
  } else {//when not a valid hexvalue length
99
102
  stream.eatWhile(/[\w\\\-]/);
103
+ if(state.stack[state.stack.length-1] === "rule")return ret("atom", stream.current());return ret("atom", stream.current());
100
104
  return ret("atom", "tag");
101
105
  }
102
106
  } else if (ch == "&") {
@@ -104,17 +108,33 @@ CodeMirror.defineMode("less", function(config) {
104
108
  return ret(null, ch);
105
109
  } else {
106
110
  stream.eatWhile(/[\w\\\-_%.{]/);
107
- if(type == "string"){
108
- return ret("string", "string");
111
+ if(stream.current().match(/\\/) !== null){
112
+ if(stream.current().charAt(stream.current().length-1) === "\\"){
113
+ stream.eat(/\'|\"|\)|\(/);
114
+ while(stream.eatWhile(/[\w\\\-_%.{]/)){
115
+ stream.eat(/\'|\"|\)|\(/);
116
+ }
117
+ return ret("string", stream.current());
118
+ }
119
+ } //else if(type === "tag")return ret("tag", "tag");
120
+ else if(type == "string"){
121
+ if(state.stack[state.stack.length-1] === "{" && stream.peek() === ":")return ret("variable", "variable");
122
+ if(stream.peek() === "/")stream.eatWhile(/[\w\\\-_%.{:\/]/);
123
+ return ret(type, stream.current());
109
124
  } else if(stream.current().match(/(^http$|^https$)/) != null){
110
125
  stream.eatWhile(/[\w\\\-_%.{:\/]/);
126
+ if(stream.peek() === "/")stream.eatWhile(/[\w\\\-_%.{:\/]/);
111
127
  return ret("string", "string");
112
128
  } else if(stream.peek() == "<" || stream.peek() == ">" || stream.peek() == "+"){
129
+ if(type === "(" && (stream.current() === "n" || stream.current() === "-n"))return ret("string", stream.current());
113
130
  return ret("tag", "tag");
114
131
  } else if( /\(/.test(stream.peek()) ){
132
+ if(stream.current() === "when")return ret("variable","variable");
133
+ else if(state.stack[state.stack.length-1] === "@media" && stream.current() === "and")return ret("variable",stream.current());
115
134
  return ret(null, ch);
116
- } else if (stream.peek() == "/" && state.stack[state.stack.length-1] != undefined){ // url(dir/center/image.png)
117
- return ret("string", "string");
135
+ } else if (stream.peek() == "/" && state.stack[state.stack.length-1] !== undefined){ // url(dir/center/image.png)
136
+ if(stream.peek() === "/")stream.eatWhile(/[\w\\\-_%.{:\/]/);
137
+ return ret("string", stream.current());
118
138
  } else if( stream.current().match(/\-\d|\-.\d/) ){ // match e.g.: -5px -0.4 etc... only colorize the minus sign
119
139
  //commment out these 2 comment if you want the minus sign to be parsed as null -500px
120
140
  //stream.backUp(stream.current().length-1);
@@ -129,14 +149,33 @@ CodeMirror.defineMode("less", function(config) {
129
149
  if( /[{<>.a-zA-Z\/]/.test(stream.peek()) || stream.eol() )return ret("tag", "tag"); // e.g. button.icon-plus
130
150
  return ret("string", "string"); // let url(/images/logo.png) without quotes return as string
131
151
  } else if( stream.eol() || stream.peek() == "[" || stream.peek() == "#" || type == "tag" ){
152
+
132
153
  if(stream.current().substring(stream.current().length-1,stream.current().length) == "{")stream.backUp(1);
154
+ else if(state.stack[state.stack.length-1] === "border-color" || state.stack[state.stack.length-1] === "background-position" || state.stack[state.stack.length-1] === "font-family")return ret(null, stream.current());
155
+ else if(type === "tag")return ret("tag", "tag");
156
+ else if((type === ":" || type === "unit") && state.stack[state.stack.length-1] === "rule")return ret(null, stream.current());
157
+ else if(state.stack[state.stack.length-1] === "rule" && type === "tag")return ret("string", stream.current());
158
+ else if(state.stack[state.stack.length-1] === ";" && type === ":")return ret(null, stream.current());
159
+ //else if(state.stack[state.stack.length-1] === ";" || type === "")return ret("variable", stream.current());
160
+ else if(stream.peek() === "#" && type !== undefined && type.match(/\+|,|tag|select\-op|}|{|;/g) === null)return ret("string", stream.current());
161
+ else if(type === "variable")return ret(null, stream.current());
162
+ else if(state.stack[state.stack.length-1] === "{" && type === "comment")return ret("variable", stream.current());
163
+ else if(state.stack.length === 0 && (type === ";" || type === "comment"))return ret("tag", stream.current());
164
+ else if((state.stack[state.stack.length-1] === "{" || type === ";") && state.stack[state.stack.length-1] !== "@media{")return ret("variable", stream.current());
165
+ else if(state.stack[state.stack.length-2] === "{" && state.stack[state.stack.length-1] === ";")return ret("variable", stream.current());
166
+
133
167
  return ret("tag", "tag");
134
168
  } else if(type == "compare" || type == "a" || type == "("){
135
169
  return ret("string", "string");
136
170
  } else if(type == "|" || stream.current() == "-" || type == "["){
137
- if(type == "|" )return ret("tag", "tag");
171
+ if(type == "|" && stream.peek().match(/\]|=|\~/) !== null)return ret("number", stream.current());
172
+ else if(type == "|" )return ret("tag", "tag");
173
+ else if(type == "["){
174
+ stream.eatWhile(/\w\-/);
175
+ return ret("number", stream.current());
176
+ }
138
177
  return ret(null, ch);
139
- } else if(stream.peek() == ":") {
178
+ } else if((stream.peek() == ":") || ( stream.eatSpace() && stream.peek() == ":")) {
140
179
  stream.next();
141
180
  var t_v = stream.peek() == ":" ? true : false;
142
181
  if(!t_v){
@@ -152,11 +191,50 @@ CodeMirror.defineMode("less", function(config) {
152
191
  stream.backUp(1);
153
192
  }
154
193
  if(t_v)return ret("tag", "tag"); else return ret("variable", "variable");
155
- } else if(state.stack[state.stack.length-1] === "font-family"){
194
+ } else if(state.stack[state.stack.length-1] === "font-family" || state.stack[state.stack.length-1] === "background-position" || state.stack[state.stack.length-1] === "border-color"){
156
195
  return ret(null, null);
157
196
  } else {
158
- if(state.stack[state.stack.length-1] === "{" || type === "select-op" || (state.stack[state.stack.length-1] === "rule" && type === ",") )return ret("tag", "tag");
159
- return ret("variable", "variable");
197
+
198
+ if(state.stack[state.stack.length-1] === null && type === ":")return ret(null, stream.current());
199
+
200
+ //else if((type === ")" && state.stack[state.stack.length-1] === "rule") || (state.stack[state.stack.length-2] === "{" && state.stack[state.stack.length-1] === "rule" && type === "variable"))return ret(null, stream.current());
201
+
202
+ else if(/\^|\$/.test(stream.current()) && stream.peek().match(/\~|=/) !== null)return ret("string", "string");//att^=val
203
+
204
+ else if(type === "unit" && state.stack[state.stack.length-1] === "rule")return ret(null, "unit");
205
+ else if(type === "unit" && state.stack[state.stack.length-1] === ";")return ret(null, "unit");
206
+ else if(type === ")" && state.stack[state.stack.length-1] === "rule")return ret(null, "unit");
207
+ else if(type.match("@") !== null && state.stack[state.stack.length-1] === "rule")return ret(null, "unit");
208
+ //else if(type === "unit" && state.stack[state.stack.length-1] === "rule")return ret(null, stream.current());
209
+
210
+ else if((type === ";" || type === "}" || type === ",") && state.stack[state.stack.length-1] === ";")return ret("tag", stream.current());
211
+ else if((type === ";" && stream.peek() !== undefined && stream.peek().match(/{|./) === null) || (type === ";" && stream.eatSpace() && stream.peek().match(/{|./) === null))return ret("variable", stream.current());
212
+ else if((type === "@media" && state.stack[state.stack.length-1] === "@media") || type === "@namespace")return ret("tag", stream.current());
213
+
214
+ else if(type === "{" && state.stack[state.stack.length-1] === ";" && stream.peek() === "{")return ret("tag", "tag");
215
+ else if((type === "{" || type === ":") && state.stack[state.stack.length-1] === ";")return ret(null, stream.current());
216
+ else if((state.stack[state.stack.length-1] === "{" && stream.eatSpace() && stream.peek().match(/.|#/) === null) || type === "select-op" || (state.stack[state.stack.length-1] === "rule" && type === ",") )return ret("tag", "tag");
217
+ else if(type === "variable" && state.stack[state.stack.length-1] === "rule")return ret("tag", "tag");
218
+ else if((stream.eatSpace() && stream.peek() === "{") || stream.eol() || stream.peek() === "{")return ret("tag", "tag");
219
+ //this one messes up indentation
220
+ //else if((type === "}" && stream.peek() !== ":") || (type === "}" && stream.eatSpace() && stream.peek() !== ":"))return(type, "tag");
221
+
222
+ else if(type === ")" && (stream.current() == "and" || stream.current() == "and "))return ret("variable", "variable");
223
+ else if(type === ")" && (stream.current() == "when" || stream.current() == "when "))return ret("variable", "variable");
224
+ else if(type === ")" || type === "comment" || type === "{")return ret("tag", "tag");
225
+ else if(stream.sol())return ret("tag", "tag");
226
+ else if((stream.eatSpace() && stream.peek() === "#") || stream.peek() === "#")return ret("tag", "tag");
227
+ else if(state.stack.length === 0)return ret("tag", "tag");
228
+ else if(type === ";" && stream.peek() !== undefined && stream.peek().match(/^[.|\#]/g) !== null)return ret("tag", "tag");
229
+
230
+ else if(type === ":"){stream.eatSpace();return ret(null, stream.current());}
231
+
232
+ else if(stream.current() === "and " || stream.current() === "and")return ret("variable", stream.current());
233
+ else if(type === ";" && state.stack[state.stack.length-1] === "{")return ret("variable", stream.current());
234
+
235
+ else if(state.stack[state.stack.length-1] === "rule")return ret(null, stream.current());
236
+
237
+ return ret("tag", stream.current());
160
238
  }
161
239
  }
162
240
  }
@@ -234,20 +312,30 @@ CodeMirror.defineMode("less", function(config) {
234
312
  else if (type == "}") state.stack.pop();
235
313
  else if (type == "@media") state.stack.push("@media");
236
314
  else if (stream.current() === "font-family") state.stack[state.stack.length-1] = "font-family";
315
+ else if (stream.current() === "background-position") state.stack[state.stack.length-1] = "background-position";
316
+ else if (stream.current() === "border-color") state.stack[state.stack.length-1] = "border-color";
237
317
  else if (context == "{" && type != "comment" && type !== "tag") state.stack.push("rule");
238
318
  else if (stream.peek() === ":" && stream.current().match(/@|#/) === null) style = type;
319
+ if(type === ";" && (state.stack[state.stack.length-1] == "font-family" || state.stack[state.stack.length-1] == "background-position" || state.stack[state.stack.length-1] == "border-color"))state.stack[state.stack.length-1] = stream.current();
320
+ else if(type === "tag" && stream.peek() === ")" && stream.current().match(/\:/) === null){type = null; style = null;}
321
+ // ????
322
+ else if((type === "variable" && stream.peek() === ")") || (type === "variable" && stream.eatSpace() && stream.peek() === ")"))return ret(null,stream.current());
239
323
  return style;
240
324
  },
241
325
 
242
326
  indent: function(state, textAfter) {
243
327
  var n = state.stack.length;
244
-
245
328
  if (/^\}/.test(textAfter))
246
- n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
329
+ n -= state.stack[state.stack.length-1] === "rule" ? 2 : 1;
330
+ else if (state.stack[state.stack.length-2] === "{")
331
+ n -= state.stack[state.stack.length-1] === "rule" ? 1 : 0;
247
332
  return state.baseIndent + n * indentUnit;
248
333
  },
249
334
 
250
- electricChars: "}"
335
+ electricChars: "}",
336
+ blockCommentStart: "/*",
337
+ blockCommentEnd: "*/",
338
+ lineComment: "//"
251
339
  };
252
340
  });
253
341