codemirror-rails 3.20 → 3.21

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +240 -135
  4. data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +6 -2
  5. data/vendor/assets/javascripts/codemirror/addons/comment/continuecomment.js +1 -1
  6. data/vendor/assets/javascripts/codemirror/addons/dialog/dialog.js +1 -0
  7. data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +5 -3
  8. data/vendor/assets/javascripts/codemirror/addons/edit/closetag.js +10 -6
  9. data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +2 -0
  10. data/vendor/assets/javascripts/codemirror/addons/edit/matchbrackets.js +1 -1
  11. data/vendor/assets/javascripts/codemirror/addons/fold/comment-fold.js +3 -1
  12. data/vendor/assets/javascripts/codemirror/addons/fold/foldcode.js +13 -2
  13. data/vendor/assets/javascripts/codemirror/addons/fold/foldgutter.js +1 -1
  14. data/vendor/assets/javascripts/codemirror/addons/fold/indent-fold.js +2 -2
  15. data/vendor/assets/javascripts/codemirror/addons/fold/xml-fold.js +6 -0
  16. data/vendor/assets/javascripts/codemirror/addons/hint/anyword-hint.js +3 -5
  17. data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +29 -33
  18. data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +1 -1
  19. data/vendor/assets/javascripts/codemirror/addons/hint/pig-hint.js +1 -1
  20. data/vendor/assets/javascripts/codemirror/addons/hint/python-hint.js +1 -5
  21. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +58 -9
  22. data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +58 -17
  23. data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +5 -5
  24. data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +1 -1
  25. data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +6 -1
  26. data/vendor/assets/javascripts/codemirror/addons/mode/multiplex.js +5 -3
  27. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode-standalone.js +26 -11
  28. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +1 -1
  29. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +22 -11
  30. data/vendor/assets/javascripts/codemirror/addons/search/search.js +22 -9
  31. data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +48 -24
  32. data/vendor/assets/javascripts/codemirror/addons/selection/active-line.js +15 -9
  33. data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +3 -3
  34. data/vendor/assets/javascripts/codemirror/addons/wrap/hardwrap.js +21 -9
  35. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +12 -1
  36. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +110 -28
  37. data/vendor/assets/javascripts/codemirror/modes/clike.js +28 -9
  38. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +3 -4
  39. data/vendor/assets/javascripts/codemirror/modes/css.js +341 -297
  40. data/vendor/assets/javascripts/codemirror/modes/erlang.js +302 -179
  41. data/vendor/assets/javascripts/codemirror/modes/gfm.js +10 -5
  42. data/vendor/assets/javascripts/codemirror/modes/gherkin.js +45 -50
  43. data/vendor/assets/javascripts/codemirror/modes/haml.js +0 -4
  44. data/vendor/assets/javascripts/codemirror/modes/haskell.js +5 -3
  45. data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +0 -2
  46. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +0 -2
  47. data/vendor/assets/javascripts/codemirror/modes/javascript.js +43 -30
  48. data/vendor/assets/javascripts/codemirror/modes/jinja2.js +13 -3
  49. data/vendor/assets/javascripts/codemirror/modes/less.js +7 -6
  50. data/vendor/assets/javascripts/codemirror/modes/markdown.js +231 -45
  51. data/vendor/assets/javascripts/codemirror/modes/{ocaml.js → mllike.js} +88 -13
  52. data/vendor/assets/javascripts/codemirror/modes/pegjs.js +5 -9
  53. data/vendor/assets/javascripts/codemirror/modes/php.js +6 -7
  54. data/vendor/assets/javascripts/codemirror/modes/python.js +6 -0
  55. data/vendor/assets/javascripts/codemirror/modes/r.js +5 -1
  56. data/vendor/assets/javascripts/codemirror/modes/rpm-spec.js +1 -1
  57. data/vendor/assets/javascripts/codemirror/modes/ruby.js +3 -1
  58. data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +4 -2
  59. data/vendor/assets/javascripts/codemirror/modes/smartymixed.js +0 -2
  60. data/vendor/assets/javascripts/codemirror/modes/sql.js +5 -4
  61. data/vendor/assets/javascripts/codemirror/modes/xml.js +87 -100
  62. data/vendor/assets/stylesheets/codemirror/themes/mbo.css +1 -1
  63. data/vendor/assets/stylesheets/codemirror/themes/midnight.css +1 -1
  64. data/vendor/assets/stylesheets/codemirror/themes/pastel-on-dark.css +49 -0
  65. data/vendor/assets/stylesheets/codemirror/themes/the-matrix.css +1 -1
  66. metadata +3 -2
@@ -1,4 +1,4 @@
1
- CodeMirror.defineMode("gfm", function(config) {
1
+ CodeMirror.defineMode("gfm", function(config, modeConfig) {
2
2
  var codeDepth = 0;
3
3
  function blankLine(state) {
4
4
  state.code = false;
@@ -75,7 +75,7 @@ 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
79
  stream.string.slice(stream.start - 2, stream.start) != "](") {
80
80
  // URLs
81
81
  // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
@@ -87,11 +87,16 @@ CodeMirror.defineMode("gfm", function(config) {
87
87
  },
88
88
  blankLine: blankLine
89
89
  };
90
- CodeMirror.defineMIME("gfmBase", {
91
- name: "markdown",
90
+
91
+ var markdownConfig = {
92
92
  underscoresBreakWords: false,
93
93
  taskLists: true,
94
94
  fencedCodeBlocks: true
95
- });
95
+ };
96
+ for (var attr in modeConfig) {
97
+ markdownConfig[attr] = modeConfig[attr];
98
+ }
99
+ markdownConfig.name = "markdown";
100
+ CodeMirror.defineMIME("gfmBase", markdownConfig);
96
101
  return CodeMirror.overlayMode(CodeMirror.getMode(config, "gfmBase"), gfmOverlay);
97
102
  }, "markdown");
@@ -18,31 +18,40 @@ CodeMirror.defineMode("gherkin", function () {
18
18
  startState: function () {
19
19
  return {
20
20
  lineNumber: 0,
21
- tableHeaderLine: null,
21
+ tableHeaderLine: false,
22
22
  allowFeature: true,
23
23
  allowBackground: false,
24
24
  allowScenario: false,
25
25
  allowSteps: false,
26
26
  allowPlaceholders: false,
27
- inMultilineArgument: false,
27
+ allowMultilineArgument: false,
28
28
  inMultilineString: false,
29
- inMultilineTable: false
29
+ inMultilineTable: false,
30
+ inKeywordLine: false
30
31
  };
31
32
  },
32
33
  token: function (stream, state) {
33
34
  if (stream.sol()) {
34
35
  state.lineNumber++;
36
+ state.inKeywordLine = false;
37
+ if (state.inMultilineTable) {
38
+ state.tableHeaderLine = false;
39
+ if (!stream.match(/\s*\|/, false)) {
40
+ state.allowMultilineArgument = false;
41
+ state.inMultilineTable = false;
42
+ }
43
+ }
35
44
  }
45
+
36
46
  stream.eatSpace();
37
47
 
38
- // INSIDE OF MULTILINE ARGUMENTS
39
- if (state.inMultilineArgument) {
48
+ if (state.allowMultilineArgument) {
40
49
 
41
50
  // STRING
42
51
  if (state.inMultilineString) {
43
52
  if (stream.match('"""')) {
44
53
  state.inMultilineString = false;
45
- state.inMultilineArgument = false;
54
+ state.allowMultilineArgument = false;
46
55
  } else {
47
56
  stream.match(/.*/);
48
57
  }
@@ -51,19 +60,11 @@ CodeMirror.defineMode("gherkin", function () {
51
60
 
52
61
  // TABLE
53
62
  if (state.inMultilineTable) {
54
- // New table, assume first row is headers
55
- if (state.tableHeaderLine === null) {
56
- state.tableHeaderLine = state.lineNumber;
57
- }
58
-
59
63
  if (stream.match(/\|\s*/)) {
60
- if (stream.eol()) {
61
- state.inMultilineTable = false;
62
- }
63
64
  return "bracket";
64
65
  } else {
65
66
  stream.match(/[^\|]*/);
66
- return state.tableHeaderLine === state.lineNumber ? "property" : "string";
67
+ return state.tableHeaderLine ? "header" : "string";
67
68
  }
68
69
  }
69
70
 
@@ -75,15 +76,10 @@ CodeMirror.defineMode("gherkin", function () {
75
76
  } else if (stream.match("|")) {
76
77
  // Table
77
78
  state.inMultilineTable = true;
79
+ state.tableHeaderLine = true;
78
80
  return "bracket";
79
- } else {
80
- // Or abort
81
- state.inMultilineArgument = false;
82
- state.tableHeaderLine = null;
83
81
  }
84
82
 
85
-
86
- return null;
87
83
  }
88
84
 
89
85
  // LINE COMMENT
@@ -91,76 +87,75 @@ CodeMirror.defineMode("gherkin", function () {
91
87
  return "comment";
92
88
 
93
89
  // TAG
94
- } else if (stream.match(/@\S+/)) {
95
- return "def";
90
+ } else if (!state.inKeywordLine && stream.match(/@\S+/)) {
91
+ return "tag";
96
92
 
97
93
  // FEATURE
98
- } else if (state.allowFeature && stream.match(/Feature:/)) {
94
+ } else if (!state.inKeywordLine && state.allowFeature && stream.match(/(機能|功能|フィーチャ|기능|โครงหลัก|ความสามารถ|ความต้องการทางธุรกิจ|ಹೆಚ್ಚಳ|గుణము|ਮੁਹਾਂਦਰਾ|ਨਕਸ਼ ਨੁਹਾਰ|ਖਾਸੀਅਤ|रूप लेख|وِیژگی|خاصية|תכונה|Функціонал|Функция|Функционалност|Функционал|Үзенчәлеклелек|Свойство|Особина|Мөмкинлек|Могућност|Λειτουργία|Δυνατότητα|Właściwość|Vlastnosť|Trajto|Tính năng|Savybė|Pretty much|Požiadavka|Požadavek|Potrzeba biznesowa|Özellik|Osobina|Ominaisuus|Omadus|OH HAI|Mogućnost|Mogucnost|Jellemző|Hwæt|Hwaet|Funzionalità|Funktionalitéit|Funktionalität|Funkcja|Funkcionalnost|Funkcionalitāte|Funkcia|Fungsi|Functionaliteit|Funcționalitate|Funcţionalitate|Functionalitate|Funcionalitat|Funcionalidade|Fonctionnalité|Fitur|Fīča|Feature|Eiginleiki|Egenskap|Egenskab|Característica|Caracteristica|Business Need|Aspekt|Arwedd|Ahoy matey!|Ability):/)) {
99
95
  state.allowScenario = true;
100
96
  state.allowBackground = true;
101
97
  state.allowPlaceholders = false;
102
98
  state.allowSteps = false;
99
+ state.allowMultilineArgument = false;
100
+ state.inKeywordLine = true;
103
101
  return "keyword";
104
102
 
105
103
  // BACKGROUND
106
- } else if (state.allowBackground && stream.match("Background:")) {
104
+ } else if (!state.inKeywordLine && state.allowBackground && stream.match(/(背景|배경|แนวคิด|ಹಿನ್ನೆಲೆ|నేపథ్యం|ਪਿਛੋਕੜ|पृष्ठभूमि|زمینه|الخلفية|רקע|Тарих|Предыстория|Предистория|Позадина|Передумова|Основа|Контекст|Кереш|Υπόβαθρο|Założenia|Yo\-ho\-ho|Tausta|Taust|Situācija|Rerefons|Pozadina|Pozadie|Pozadí|Osnova|Latar Belakang|Kontext|Konteksts|Kontekstas|Kontekst|Háttér|Hannergrond|Grundlage|Geçmiş|Fundo|Fono|First off|Dis is what went down|Dasar|Contexto|Contexte|Context|Contesto|Cenário de Fundo|Cenario de Fundo|Cefndir|Bối cảnh|Bakgrunnur|Bakgrunn|Bakgrund|Baggrund|Background|B4|Antecedents|Antecedentes|Ær|Aer|Achtergrond):/)) {
107
105
  state.allowPlaceholders = false;
108
106
  state.allowSteps = true;
109
107
  state.allowBackground = false;
108
+ state.allowMultilineArgument = false;
109
+ state.inKeywordLine = true;
110
110
  return "keyword";
111
111
 
112
112
  // SCENARIO OUTLINE
113
- } else if (state.allowScenario && stream.match("Scenario Outline:")) {
113
+ } else if (!state.inKeywordLine && state.allowScenario && stream.match(/(場景大綱|场景大纲|劇本大綱|剧本大纲|テンプレ|シナリオテンプレート|シナリオテンプレ|シナリオアウトライン|시나리오 개요|สรุปเหตุการณ์|โครงสร้างของเหตุการณ์|ವಿವರಣೆ|కథనం|ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ|ਪਟਕਥਾ ਢਾਂਚਾ|परिदृश्य रूपरेखा|سيناريو مخطط|الگوی سناریو|תבנית תרחיש|Сценарийның төзелеше|Сценарий структураси|Структура сценарію|Структура сценария|Структура сценарија|Скица|Рамка на сценарий|Концепт|Περιγραφή Σεναρίου|Wharrimean is|Template Situai|Template Senario|Template Keadaan|Tapausaihio|Szenariogrundriss|Szablon scenariusza|Swa hwær swa|Swa hwaer swa|Struktura scenarija|Structură scenariu|Structura scenariu|Skica|Skenario konsep|Shiver me timbers|Senaryo taslağı|Schema dello scenario|Scenariomall|Scenariomal|Scenario Template|Scenario Outline|Scenario Amlinellol|Scenārijs pēc parauga|Scenarijaus šablonas|Reckon it's like|Raamstsenaarium|Plang vum Szenario|Plan du Scénario|Plan du scénario|Osnova scénáře|Osnova Scenára|Náčrt Scenáru|Náčrt Scénáře|Náčrt Scenára|MISHUN SRSLY|Menggariskan Senario|Lýsing Dæma|Lýsing Atburðarásar|Konturo de la scenaro|Koncept|Khung tình huống|Khung kịch bản|Forgatókönyv vázlat|Esquema do Cenário|Esquema do Cenario|Esquema del escenario|Esquema de l'escenari|Esbozo do escenario|Delineação do Cenário|Delineacao do Cenario|All y'all|Abstrakt Scenario|Abstract Scenario):/)) {
114
114
  state.allowPlaceholders = true;
115
115
  state.allowSteps = true;
116
+ state.allowMultilineArgument = false;
117
+ state.inKeywordLine = true;
116
118
  return "keyword";
117
119
 
118
120
  // EXAMPLES
119
- } else if (state.allowScenario && stream.match("Examples:")) {
121
+ } else if (state.allowScenario && stream.match(/(例子|例|サンプル|예|ชุดของเหตุการณ์|ชุดของตัวอย่าง|ಉದಾಹರಣೆಗಳು|ఉదాహరణలు|ਉਦਾਹਰਨਾਂ|उदाहरण|نمونه ها|امثلة|דוגמאות|Үрнәкләр|Сценарији|Примеры|Примери|Приклади|Мисоллар|Мисаллар|Σενάρια|Παραδείγματα|You'll wanna|Voorbeelden|Variantai|Tapaukset|Se þe|Se the|Se ðe|Scenarios|Scenariji|Scenarijai|Przykłady|Primjeri|Primeri|Příklady|Príklady|Piemēri|Példák|Pavyzdžiai|Paraugs|Örnekler|Juhtumid|Exemplos|Exemples|Exemple|Exempel|EXAMPLZ|Examples|Esempi|Enghreifftiau|Ekzemploj|Eksempler|Ejemplos|Dữ liệu|Dead men tell no tales|Dæmi|Contoh|Cenários|Cenarios|Beispiller|Beispiele|Atburðarásir):/)) {
120
122
  state.allowPlaceholders = false;
121
123
  state.allowSteps = true;
122
124
  state.allowBackground = false;
123
- state.inMultilineArgument = true;
125
+ state.allowMultilineArgument = true;
124
126
  return "keyword";
125
127
 
126
128
  // SCENARIO
127
- } else if (state.allowScenario && stream.match(/Scenario:/)) {
129
+ } else if (!state.inKeywordLine && state.allowScenario && stream.match(/(場景|场景|劇本|剧本|シナリオ|시나리오|เหตุการณ์|ಕಥಾಸಾರಾಂಶ|సన్నివేశం|ਪਟਕਥਾ|परिदृश्य|سيناريو|سناریو|תרחיש|Сценарій|Сценарио|Сценарий|Пример|Σενάριο|Tình huống|The thing of it is|Tapaus|Szenario|Swa|Stsenaarium|Skenario|Situai|Senaryo|Senario|Scenaro|Scenariusz|Scenariu|Scénario|Scenario|Scenarijus|Scenārijs|Scenarij|Scenarie|Scénář|Scenár|Primer|MISHUN|Kịch bản|Keadaan|Heave to|Forgatókönyv|Escenario|Escenari|Cenário|Cenario|Awww, look mate|Atburðarás):/)) {
128
130
  state.allowPlaceholders = false;
129
131
  state.allowSteps = true;
130
132
  state.allowBackground = false;
133
+ state.allowMultilineArgument = false;
134
+ state.inKeywordLine = true;
131
135
  return "keyword";
132
136
 
133
137
  // STEPS
134
- } else if (state.allowSteps && stream.match(/(Given|When|Then|And|But)/)) {
138
+ } else if (!state.inKeywordLine && state.allowSteps && stream.match(/(那麼|那么|而且|當|当|并且|同時|同时|前提|假设|假設|假定|假如|但是|但し|並且|もし|ならば|ただし|しかし|かつ|하지만|조건|먼저|만일|만약|단|그리고|그러면|และ |เมื่อ |แต่ |ดังนั้น |กำหนดให้ |ಸ್ಥಿತಿಯನ್ನು |ಮತ್ತು |ನೀಡಿದ |ನಂತರ |ಆದರೆ |మరియు |చెప్పబడినది |కాని |ఈ పరిస్థితిలో |అప్పుడు |ਪਰ |ਤਦ |ਜੇਕਰ |ਜਿਵੇਂ ਕਿ |ਜਦੋਂ |ਅਤੇ |यदि |परन्तु |पर |तब |तदा |तथा |जब |चूंकि |किन्तु |कदा |और |अगर |و |هنگامی |متى |لكن |عندما |ثم |بفرض |با فرض |اما |اذاً |آنگاه |כאשר |וגם |בהינתן |אזי |אז |אבל |Якщо |Һәм |Унда |Тоді |Тогда |То |Также |Та |Пусть |Припустимо, що |Припустимо |Онда |Но |Нехай |Нәтиҗәдә |Лекин |Ләкин |Коли |Когда |Когато |Када |Кад |К тому же |І |И |Задато |Задати |Задате |Если |Допустим |Дано |Дадено |Вә |Ва |Бирок |Әмма |Әйтик |Әгәр |Аммо |Али |Але |Агар |А також |А |Τότε |Όταν |Και |Δεδομένου |Αλλά |Þurh |Þegar |Þa þe |Þá |Þa |Zatati |Zakładając |Zadato |Zadate |Zadano |Zadani |Zadan |Za předpokladu |Za predpokladu |Youse know when youse got |Youse know like when |Yna |Yeah nah |Y'know |Y |Wun |Wtedy |When y'all |When |Wenn |WEN |wann |Ve |Và |Und |Un |ugeholl |Too right |Thurh |Thì |Then y'all |Then |Tha the |Tha |Tetapi |Tapi |Tak |Tada |Tad |Stel |Soit |Siis |Și |Şi |Si |Sed |Se |Så |Quando |Quand |Quan |Pryd |Potom |Pokud |Pokiaľ |Però |Pero |Pak |Oraz |Onda |Ond |Oletetaan |Og |Och |O zaman |Niin |Nhưng |När |Når |Mutta |Men |Mas |Maka |Majd |Mając |Mais |Maar |mä |Ma |Lorsque |Lorsqu'|Logo |Let go and haul |Kun |Kuid |Kui |Kiedy |Khi |Ketika |Kemudian |Keď |Když |Kaj |Kai |Kada |Kad |Jeżeli |Jeśli |Ja |It's just unbelievable |Ir |I CAN HAZ |I |Ha |Givun |Givet |Given y'all |Given |Gitt |Gegeven |Gegeben seien |Gegeben sei |Gdy |Gangway! |Fakat |Étant donnés |Etant donnés |Étant données |Etant données |Étant donnée |Etant donnée |Étant donné |Etant donné |Et |És |Entonces |Entón |Então |Entao |En |Eğer ki |Ef |Eeldades |E |Ðurh |Duota |Dun |Donitaĵo |Donat |Donada |Do |Diyelim ki |Diberi |Dengan |Den youse gotta |DEN |De |Dato |Dați fiind |Daţi fiind |Dati fiind |Dati |Date fiind |Date |Data |Dat fiind |Dar |Dann |dann |Dan |Dados |Dado |Dadas |Dada |Ða ðe |Ða |Cuando |Cho |Cando |Când |Cand |Cal |But y'all |But at the end of the day I reckon |BUT |But |Buh |Blimey! |Biết |Bet |Bagi |Aye |awer |Avast! |Atunci |Atesa |Atès |Apabila |Anrhegedig a |Angenommen |And y'all |And |AN |An |an |Amikor |Amennyiben |Ama |Als |Alors |Allora |Ali |Aleshores |Ale |Akkor |Ak |Adott |Ac |Aber |A zároveň |A tiež |A taktiež |A také |A |a |7 |\* )/)) {
139
+ state.inStep = true;
140
+ state.allowPlaceholders = true;
141
+ state.allowMultilineArgument = true;
142
+ state.inKeywordLine = true;
135
143
  return "keyword";
136
144
 
137
145
  // INLINE STRING
138
- } else if (!state.inMultilineArgument && stream.match(/"/)) {
139
- stream.match(/.*?"/);
146
+ } else if (stream.match(/"[^"]*"?/)) {
140
147
  return "string";
141
148
 
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
- }
149
+ // PLACEHOLDER
150
+ } else if (state.allowPlaceholders && stream.match(/<[^>]*>?/)) {
151
+ return "variable";
157
152
 
158
153
  // Fall through
159
154
  } else {
160
- stream.eatWhile(/[^":<]/);
155
+ stream.next();
156
+ stream.eatWhile(/[^@"<#]/);
157
+ return null;
161
158
  }
162
-
163
- return null;
164
159
  }
165
160
  };
166
161
  });
@@ -141,10 +141,6 @@
141
141
  style = null;
142
142
  }
143
143
  return style;
144
- },
145
-
146
- indent: function(state) {
147
- return state.indented;
148
144
  }
149
145
  };
150
146
  }, "htmlmixed", "ruby");
@@ -8,7 +8,7 @@ CodeMirror.defineMode("haskell", function(_config, modeConfig) {
8
8
  // These should all be Unicode extended, as per the Haskell 2010 report
9
9
  var smallRE = /[a-z_]/;
10
10
  var largeRE = /[A-Z]/;
11
- var digitRE = /[0-9]/;
11
+ var digitRE = /\d/;
12
12
  var hexitRE = /[0-9A-Fa-f]/;
13
13
  var octitRE = /[0-7]/;
14
14
  var idRE = /[a-z_A-Z0-9']/;
@@ -76,9 +76,8 @@ CodeMirror.defineMode("haskell", function(_config, modeConfig) {
76
76
  }
77
77
  source.eatWhile(digitRE);
78
78
  var t = "number";
79
- if (source.eat('.')) {
79
+ if (source.match(/^\.\d+/)) {
80
80
  t = "number";
81
- source.eatWhile(digitRE); // should require at least 1
82
81
  }
83
82
  if (source.eat(/[eE]/)) {
84
83
  t = "number";
@@ -88,6 +87,9 @@ CodeMirror.defineMode("haskell", function(_config, modeConfig) {
88
87
  return t;
89
88
  }
90
89
 
90
+ if (ch == "." && source.eat("."))
91
+ return "keyword";
92
+
91
93
  if (symbolRE.test(ch)) {
92
94
  if (ch == '-' && source.eat(/-/)) {
93
95
  source.eatWhile(/-/);
@@ -58,8 +58,6 @@ CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
58
58
  };
59
59
  },
60
60
 
61
- electricChars: "/{}:",
62
-
63
61
  innerMode: function(state) {
64
62
  if (state.token == scriptingDispatch) return {state: state.scriptState, mode: scriptingMode};
65
63
  else return {state: state.htmlState, mode: htmlMixedMode};
@@ -93,8 +93,6 @@ CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
93
93
  return CodeMirror.Pass;
94
94
  },
95
95
 
96
- electricChars: "/{}:",
97
-
98
96
  innerMode: function(state) {
99
97
  return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
100
98
  }
@@ -15,7 +15,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
15
15
 
16
16
  var jsKeywords = {
17
17
  "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
18
- "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
18
+ "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
19
19
  "var": kw("var"), "const": kw("var"), "let": kw("var"),
20
20
  "function": kw("function"), "catch": kw("catch"),
21
21
  "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
@@ -54,14 +54,16 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
54
54
 
55
55
  var isOperatorChar = /[+\-*&%=<>!?|~^]/;
56
56
 
57
- function nextUntilUnescaped(stream, end) {
58
- var escaped = false, next;
57
+ function readRegexp(stream) {
58
+ var escaped = false, next, inSet = false;
59
59
  while ((next = stream.next()) != null) {
60
- if (next == end && !escaped)
61
- return false;
60
+ if (!escaped) {
61
+ if (next == "/" && !inSet) return;
62
+ if (next == "[") inSet = true;
63
+ else if (inSet && next == "]") inSet = false;
64
+ }
62
65
  escaped = !escaped && next == "\\";
63
66
  }
64
- return escaped;
65
67
  }
66
68
 
67
69
  // Used as scratch variables to communicate multiple values without
@@ -83,7 +85,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
83
85
  } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
84
86
  return ret(ch);
85
87
  } else if (ch == "=" && stream.eat(">")) {
86
- return ret("=>");
88
+ return ret("=>", "operator");
87
89
  } else if (ch == "0" && stream.eat(/x/i)) {
88
90
  stream.eatWhile(/[\da-f]/i);
89
91
  return ret("number", "number");
@@ -99,12 +101,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
99
101
  return ret("comment", "comment");
100
102
  } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
101
103
  state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
102
- nextUntilUnescaped(stream, "/");
104
+ readRegexp(stream);
103
105
  stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
104
106
  return ret("regexp", "string-2");
105
107
  } else {
106
108
  stream.eatWhile(isOperatorChar);
107
- return ret("operator", null, stream.current());
109
+ return ret("operator", "operator", stream.current());
108
110
  }
109
111
  } else if (ch == "`") {
110
112
  state.tokenize = tokenQuasi;
@@ -114,7 +116,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
114
116
  return ret("error", "error");
115
117
  } else if (isOperatorChar.test(ch)) {
116
118
  stream.eatWhile(isOperatorChar);
117
- return ret("operator", null, stream.current());
119
+ return ret("operator", "operator", stream.current());
118
120
  } else {
119
121
  stream.eatWhile(/[\w\$_]/);
120
122
  var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
@@ -125,8 +127,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
125
127
 
126
128
  function tokenString(quote) {
127
129
  return function(stream, state) {
128
- if (!nextUntilUnescaped(stream, quote))
129
- state.tokenize = tokenBase;
130
+ var escaped = false, next;
131
+ while ((next = stream.next()) != null) {
132
+ if (next == quote && !escaped) break;
133
+ escaped = !escaped && next == "\\";
134
+ }
135
+ if (!escaped) state.tokenize = tokenBase;
130
136
  return ret("string", "string");
131
137
  };
132
138
  }
@@ -304,7 +310,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
304
310
  if (type == ";") return cont();
305
311
  if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
306
312
  if (type == "function") return cont(functiondef);
307
- if (type == "for") return cont(pushlex("form"), forspec, poplex, statement, poplex);
313
+ if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
308
314
  if (type == "variable") return cont(pushlex("stat"), maybelabel);
309
315
  if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
310
316
  block, poplex, poplex);
@@ -327,7 +333,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
327
333
  function expressionInner(type, noComma) {
328
334
  if (cx.state.fatArrowAt == cx.stream.start) {
329
335
  var body = noComma ? arrowBodyNoComma : arrowBody;
330
- if (type == "(") return cont(pushcontext, commasep(pattern, ")"), expect("=>"), body, popcontext);
336
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
331
337
  else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
332
338
  }
333
339
 
@@ -337,8 +343,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
337
343
  if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
338
344
  if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
339
345
  if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
340
- if (type == "[") return cont(pushlex("]"), expressionNoComma, maybeArrayComprehension, poplex, maybeop);
341
- if (type == "{") return cont(commasep(objprop, "}"), maybeop);
346
+ if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
347
+ if (type == "{") return contCommasep(objprop, "}", null, maybeop);
342
348
  return cont();
343
349
  }
344
350
  function maybeexpression(type) {
@@ -365,12 +371,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
365
371
  }
366
372
  if (type == "quasi") { cx.cc.push(me); return quasi(value); }
367
373
  if (type == ";") return;
368
- if (type == "(") return cont(commasep(expressionNoComma, ")", "call"), me);
374
+ if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
369
375
  if (type == ".") return cont(property, me);
370
376
  if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
371
377
  }
372
378
  function quasi(value) {
373
- if (!value) debugger;
374
379
  if (value.slice(value.length - 2) != "${") return cont();
375
380
  return cont(expression, continueQuasi);
376
381
  }
@@ -418,7 +423,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
418
423
  if (type == ":") return cont(expressionNoComma);
419
424
  if (type == "(") return pass(functiondef);
420
425
  }
421
- function commasep(what, end, info) {
426
+ function commasep(what, end) {
422
427
  function proceed(type) {
423
428
  if (type == ",") {
424
429
  var lex = cx.state.lexical;
@@ -430,10 +435,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
430
435
  }
431
436
  return function(type) {
432
437
  if (type == end) return cont();
433
- if (info === false) return pass(what, proceed);
434
- return pass(pushlex(end, info), what, proceed, poplex);
438
+ return pass(what, proceed);
435
439
  };
436
440
  }
441
+ function contCommasep(what, end, info) {
442
+ for (var i = 3; i < arguments.length; i++)
443
+ cx.cc.push(arguments[i]);
444
+ return cont(pushlex(end, info), commasep(what, end), poplex);
445
+ }
437
446
  function block(type) {
438
447
  if (type == "}") return cont();
439
448
  return pass(statement, block);
@@ -449,8 +458,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
449
458
  }
450
459
  function pattern(type, value) {
451
460
  if (type == "variable") { register(value); return cont(); }
452
- if (type == "[") return cont(commasep(pattern, "]"));
453
- if (type == "{") return cont(commasep(proppattern, "}"));
461
+ if (type == "[") return contCommasep(pattern, "]");
462
+ if (type == "{") return contCommasep(proppattern, "}");
454
463
  }
455
464
  function proppattern(type, value) {
456
465
  if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
@@ -470,7 +479,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
470
479
  if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
471
480
  }
472
481
  function forspec(type) {
473
- if (type == "(") return cont(pushlex(")"), forspec1, expect(")"));
482
+ if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
474
483
  }
475
484
  function forspec1(type) {
476
485
  if (type == "var") return cont(vardef, expect(";"), forspec2);
@@ -493,7 +502,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
493
502
  function functiondef(type, value) {
494
503
  if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
495
504
  if (type == "variable") {register(value); return cont(functiondef);}
496
- if (type == "(") return cont(pushcontext, commasep(funarg, ")"), statement, popcontext);
505
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
497
506
  }
498
507
  function funarg(type) {
499
508
  if (type == "spread") return cont(funarg);
@@ -506,7 +515,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
506
515
  if (value == "extends") return cont(expression);
507
516
  }
508
517
  function objlit(type) {
509
- if (type == "{") return cont(commasep(objprop, "}"));
518
+ if (type == "{") return contCommasep(objprop, "}");
510
519
  }
511
520
  function afterModule(type, value) {
512
521
  if (type == "string") return cont(statement);
@@ -522,17 +531,21 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
522
531
  return pass(importSpec, maybeFrom);
523
532
  }
524
533
  function importSpec(type, value) {
525
- if (type == "{") return cont(commasep(importSpec, "}"));
534
+ if (type == "{") return contCommasep(importSpec, "}");
526
535
  if (type == "variable") register(value);
527
536
  return cont();
528
537
  }
529
538
  function maybeFrom(_type, value) {
530
539
  if (value == "from") { cx.marked = "keyword"; return cont(expression); }
531
540
  }
541
+ function arrayLiteral(type) {
542
+ if (type == "]") return cont();
543
+ return pass(expressionNoComma, maybeArrayComprehension);
544
+ }
532
545
  function maybeArrayComprehension(type) {
533
- if (type == "for") return pass(comprehension);
534
- if (type == ",") return cont(commasep(expressionNoComma, "]", false));
535
- return pass(commasep(expressionNoComma, "]", false));
546
+ if (type == "for") return pass(comprehension, expect("]"));
547
+ if (type == ",") return cont(commasep(expressionNoComma, "]"));
548
+ return pass(commasep(expressionNoComma, "]"));
536
549
  }
537
550
  function comprehension(type) {
538
551
  if (type == "for") return cont(forspec, comprehension);