marty 2.4.7 → 2.4.8

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 (225) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile.dummy +8 -5
  3. data/Gemfile.lock +1 -1
  4. data/README.md +8 -0
  5. data/app/assets/javascripts/marty/application.js +1 -0
  6. data/app/assets/javascripts/marty/codemirror/codemirror.js +9730 -0
  7. data/app/{components/marty/script_form/client → assets/javascripts/marty/codemirror}/mode/delorean/delorean.js +0 -0
  8. data/app/assets/javascripts/marty/codemirror/mode/javascript/javascript.js +900 -0
  9. data/app/assets/javascripts/marty/codemirror/mode/python/python.js +399 -0
  10. data/app/{components/marty/script_form/client → assets/javascripts/marty/codemirror}/mode/ruby/ruby.js +135 -34
  11. data/app/{components/marty/script_form/client/Ext.ux.form.field.CodeMirror.js → assets/javascripts/marty/extjs/extensions/marty.js} +87 -6
  12. data/app/assets/stylesheets/marty/application.css +1 -13
  13. data/app/assets/stylesheets/marty/codemirror/codemirror.css +346 -0
  14. data/app/{components/marty/script_form/client → assets/stylesheets/marty/codemirror}/delorean.css +0 -0
  15. data/app/components/marty/auth_app/client/auth_app.js +82 -80
  16. data/app/components/marty/data_grid_view.rb +1 -54
  17. data/app/components/marty/data_grid_view/client/data_grid_view.js +49 -0
  18. data/app/components/marty/form.rb +1 -5
  19. data/app/components/marty/form/client/form.js +5 -0
  20. data/app/components/marty/grid.rb +1 -146
  21. data/app/components/marty/grid/client/grid.js +146 -0
  22. data/app/components/marty/import_view.rb +1 -32
  23. data/app/components/marty/import_view/client/import_view.js +32 -0
  24. data/app/components/marty/live_search_grid_panel.rb +1 -21
  25. data/app/components/marty/live_search_grid_panel/client/live_search_grid_panel.js +27 -0
  26. data/app/components/marty/main_auth_app.rb +4 -145
  27. data/app/components/marty/main_auth_app/client/main_auth_app.js +124 -0
  28. data/app/components/marty/mcfly_grid_panel.rb +1 -17
  29. data/app/components/marty/mcfly_grid_panel/client/mcfly_grid_panel.js +37 -0
  30. data/app/components/marty/new_posting_form.rb +1 -6
  31. data/app/components/marty/new_posting_form/client/new_posting_form.js +6 -0
  32. data/app/components/marty/panel.rb +1 -5
  33. data/app/components/marty/panel/client/panel.js +5 -0
  34. data/app/components/marty/posting_grid.rb +4 -55
  35. data/app/components/marty/posting_grid/client/posting_grid.js +50 -0
  36. data/app/components/marty/promise_view.rb +2 -75
  37. data/app/components/marty/promise_view/client/promise_view.css +12 -9
  38. data/app/components/marty/promise_view/client/promise_view.js +57 -0
  39. data/app/components/marty/report_form.rb +3 -69
  40. data/app/components/marty/report_form/client/report_form.js +78 -0
  41. data/app/components/marty/report_select.rb +1 -45
  42. data/app/components/marty/report_select/client/report_select.js +50 -0
  43. data/app/components/marty/reporting.rb +1 -8
  44. data/app/components/marty/reporting/client/reporting.js +8 -0
  45. data/app/components/marty/script_form.rb +2 -63
  46. data/app/components/marty/script_form/client/script_form.js +44 -0
  47. data/app/components/marty/script_tester.rb +1 -7
  48. data/app/components/marty/script_tester/client/script_tester.js +7 -0
  49. data/app/components/marty/scripting.rb +1 -55
  50. data/app/components/marty/scripting/client/scripting.js +62 -0
  51. data/app/components/marty/simple_app/client/simple_app.js +21 -13
  52. data/app/models/marty/promise.rb +22 -1
  53. data/app/views/layouts/marty/application.html.erb +8 -6
  54. data/docker-compose.dummy.yml +2 -0
  55. data/lib/marty/monkey.rb +0 -16
  56. data/lib/marty/version.rb +1 -1
  57. data/spec/dummy/config/initializers/assets.rb +1 -0
  58. data/spec/features/reporting_spec.rb +1 -0
  59. data/spec/features/scripting_spec.rb +4 -4
  60. data/spec/spec_helper.rb +1 -0
  61. data/spec/support/chromedriver.rb +5 -1
  62. data/spec/support/shared_connection_db_helpers.rb +42 -2
  63. metadata +29 -168
  64. data/app/assets/images/marty/.gitkeep +0 -0
  65. data/app/components/marty/mcfly_grid_panel/client/dup_in_form.js +0 -20
  66. data/app/components/marty/script_form/client/codemirror.css +0 -172
  67. data/app/components/marty/script_form/client/codemirror.js +0 -3130
  68. data/app/components/marty/script_form/client/mode/clike/clike.js +0 -284
  69. data/app/components/marty/script_form/client/mode/clike/index.html +0 -102
  70. data/app/components/marty/script_form/client/mode/clike/scala.html +0 -766
  71. data/app/components/marty/script_form/client/mode/clojure/clojure.js +0 -206
  72. data/app/components/marty/script_form/client/mode/clojure/index.html +0 -67
  73. data/app/components/marty/script_form/client/mode/coffeescript/LICENSE +0 -22
  74. data/app/components/marty/script_form/client/mode/coffeescript/coffeescript.js +0 -346
  75. data/app/components/marty/script_form/client/mode/coffeescript/index.html +0 -728
  76. data/app/components/marty/script_form/client/mode/commonlisp/commonlisp.js +0 -101
  77. data/app/components/marty/script_form/client/mode/commonlisp/index.html +0 -165
  78. data/app/components/marty/script_form/client/mode/css/css.js +0 -448
  79. data/app/components/marty/script_form/client/mode/css/index.html +0 -58
  80. data/app/components/marty/script_form/client/mode/css/test.js +0 -501
  81. data/app/components/marty/script_form/client/mode/diff/diff.js +0 -32
  82. data/app/components/marty/script_form/client/mode/diff/index.html +0 -105
  83. data/app/components/marty/script_form/client/mode/ecl/ecl.js +0 -203
  84. data/app/components/marty/script_form/client/mode/ecl/index.html +0 -42
  85. data/app/components/marty/script_form/client/mode/erlang/erlang.js +0 -463
  86. data/app/components/marty/script_form/client/mode/erlang/index.html +0 -63
  87. data/app/components/marty/script_form/client/mode/gfm/gfm.js +0 -150
  88. data/app/components/marty/script_form/client/mode/gfm/index.html +0 -48
  89. data/app/components/marty/script_form/client/mode/go/go.js +0 -170
  90. data/app/components/marty/script_form/client/mode/go/index.html +0 -73
  91. data/app/components/marty/script_form/client/mode/groovy/groovy.js +0 -210
  92. data/app/components/marty/script_form/client/mode/groovy/index.html +0 -72
  93. data/app/components/marty/script_form/client/mode/haskell/haskell.js +0 -242
  94. data/app/components/marty/script_form/client/mode/haskell/index.html +0 -61
  95. data/app/components/marty/script_form/client/mode/haxe/haxe.js +0 -429
  96. data/app/components/marty/script_form/client/mode/haxe/index.html +0 -91
  97. data/app/components/marty/script_form/client/mode/htmlembedded/htmlembedded.js +0 -72
  98. data/app/components/marty/script_form/client/mode/htmlembedded/index.html +0 -50
  99. data/app/components/marty/script_form/client/mode/htmlmixed/htmlmixed.js +0 -84
  100. data/app/components/marty/script_form/client/mode/htmlmixed/index.html +0 -52
  101. data/app/components/marty/script_form/client/mode/javascript/index.html +0 -78
  102. data/app/components/marty/script_form/client/mode/javascript/javascript.js +0 -361
  103. data/app/components/marty/script_form/client/mode/jinja2/index.html +0 -38
  104. data/app/components/marty/script_form/client/mode/jinja2/jinja2.js +0 -42
  105. data/app/components/marty/script_form/client/mode/less/index.html +0 -740
  106. data/app/components/marty/script_form/client/mode/less/less.js +0 -266
  107. data/app/components/marty/script_form/client/mode/lua/index.html +0 -73
  108. data/app/components/marty/script_form/client/mode/lua/lua.js +0 -140
  109. data/app/components/marty/script_form/client/mode/markdown/index.html +0 -343
  110. data/app/components/marty/script_form/client/mode/markdown/markdown.js +0 -382
  111. data/app/components/marty/script_form/client/mode/markdown/test.js +0 -1084
  112. data/app/components/marty/script_form/client/mode/mysql/index.html +0 -42
  113. data/app/components/marty/script_form/client/mode/mysql/mysql.js +0 -186
  114. data/app/components/marty/script_form/client/mode/ntriples/index.html +0 -33
  115. data/app/components/marty/script_form/client/mode/ntriples/ntriples.js +0 -172
  116. data/app/components/marty/script_form/client/mode/ocaml/index.html +0 -130
  117. data/app/components/marty/script_form/client/mode/ocaml/ocaml.js +0 -114
  118. data/app/components/marty/script_form/client/mode/pascal/LICENSE +0 -7
  119. data/app/components/marty/script_form/client/mode/pascal/index.html +0 -49
  120. data/app/components/marty/script_form/client/mode/pascal/pascal.js +0 -94
  121. data/app/components/marty/script_form/client/mode/perl/LICENSE +0 -19
  122. data/app/components/marty/script_form/client/mode/perl/index.html +0 -63
  123. data/app/components/marty/script_form/client/mode/perl/perl.js +0 -816
  124. data/app/components/marty/script_form/client/mode/php/index.html +0 -49
  125. data/app/components/marty/script_form/client/mode/php/php.js +0 -148
  126. data/app/components/marty/script_form/client/mode/pig/index.html +0 -43
  127. data/app/components/marty/script_form/client/mode/pig/pig.js +0 -172
  128. data/app/components/marty/script_form/client/mode/plsql/index.html +0 -63
  129. data/app/components/marty/script_form/client/mode/plsql/plsql.js +0 -217
  130. data/app/components/marty/script_form/client/mode/properties/index.html +0 -41
  131. data/app/components/marty/script_form/client/mode/properties/properties.js +0 -63
  132. data/app/components/marty/script_form/client/mode/python/LICENSE.txt +0 -21
  133. data/app/components/marty/script_form/client/mode/python/index.html +0 -123
  134. data/app/components/marty/script_form/client/mode/python/python.js +0 -338
  135. data/app/components/marty/script_form/client/mode/r/LICENSE +0 -24
  136. data/app/components/marty/script_form/client/mode/r/index.html +0 -74
  137. data/app/components/marty/script_form/client/mode/r/r.js +0 -141
  138. data/app/components/marty/script_form/client/mode/rpm/changes/changes.js +0 -19
  139. data/app/components/marty/script_form/client/mode/rpm/changes/index.html +0 -54
  140. data/app/components/marty/script_form/client/mode/rpm/spec/index.html +0 -100
  141. data/app/components/marty/script_form/client/mode/rpm/spec/spec.css +0 -5
  142. data/app/components/marty/script_form/client/mode/rpm/spec/spec.js +0 -66
  143. data/app/components/marty/script_form/client/mode/rst/index.html +0 -526
  144. data/app/components/marty/script_form/client/mode/rst/rst.js +0 -326
  145. data/app/components/marty/script_form/client/mode/ruby/LICENSE +0 -24
  146. data/app/components/marty/script_form/client/mode/ruby/index.html +0 -172
  147. data/app/components/marty/script_form/client/mode/rust/index.html +0 -49
  148. data/app/components/marty/script_form/client/mode/rust/rust.js +0 -432
  149. data/app/components/marty/script_form/client/mode/scheme/index.html +0 -65
  150. data/app/components/marty/script_form/client/mode/scheme/scheme.js +0 -230
  151. data/app/components/marty/script_form/client/mode/shell/index.html +0 -50
  152. data/app/components/marty/script_form/client/mode/shell/shell.js +0 -118
  153. data/app/components/marty/script_form/client/mode/sieve/LICENSE +0 -23
  154. data/app/components/marty/script_form/client/mode/sieve/index.html +0 -81
  155. data/app/components/marty/script_form/client/mode/sieve/sieve.js +0 -156
  156. data/app/components/marty/script_form/client/mode/smalltalk/index.html +0 -56
  157. data/app/components/marty/script_form/client/mode/smalltalk/smalltalk.js +0 -139
  158. data/app/components/marty/script_form/client/mode/smarty/index.html +0 -83
  159. data/app/components/marty/script_form/client/mode/smarty/smarty.js +0 -148
  160. data/app/components/marty/script_form/client/mode/sparql/index.html +0 -41
  161. data/app/components/marty/script_form/client/mode/sparql/sparql.js +0 -143
  162. data/app/components/marty/script_form/client/mode/stex/index.html +0 -98
  163. data/app/components/marty/script_form/client/mode/stex/stex.js +0 -182
  164. data/app/components/marty/script_form/client/mode/stex/test.js +0 -343
  165. data/app/components/marty/script_form/client/mode/tiddlywiki/index.html +0 -141
  166. data/app/components/marty/script_form/client/mode/tiddlywiki/tiddlywiki.css +0 -14
  167. data/app/components/marty/script_form/client/mode/tiddlywiki/tiddlywiki.js +0 -384
  168. data/app/components/marty/script_form/client/mode/tiki/index.html +0 -83
  169. data/app/components/marty/script_form/client/mode/tiki/tiki.css +0 -26
  170. data/app/components/marty/script_form/client/mode/tiki/tiki.js +0 -309
  171. data/app/components/marty/script_form/client/mode/vb/LICENSE.txt +0 -21
  172. data/app/components/marty/script_form/client/mode/vb/index.html +0 -89
  173. data/app/components/marty/script_form/client/mode/vb/vb.js +0 -260
  174. data/app/components/marty/script_form/client/mode/vbscript/index.html +0 -43
  175. data/app/components/marty/script_form/client/mode/vbscript/vbscript.js +0 -26
  176. data/app/components/marty/script_form/client/mode/velocity/index.html +0 -104
  177. data/app/components/marty/script_form/client/mode/velocity/velocity.js +0 -146
  178. data/app/components/marty/script_form/client/mode/verilog/index.html +0 -211
  179. data/app/components/marty/script_form/client/mode/verilog/verilog.js +0 -194
  180. data/app/components/marty/script_form/client/mode/xml/index.html +0 -45
  181. data/app/components/marty/script_form/client/mode/xml/xml.js +0 -318
  182. data/app/components/marty/script_form/client/mode/xquery/LICENSE +0 -20
  183. data/app/components/marty/script_form/client/mode/xquery/index.html +0 -223
  184. data/app/components/marty/script_form/client/mode/xquery/test/index.html +0 -27
  185. data/app/components/marty/script_form/client/mode/xquery/test/testBase.js +0 -42
  186. data/app/components/marty/script_form/client/mode/xquery/test/testEmptySequenceKeyword.js +0 -16
  187. data/app/components/marty/script_form/client/mode/xquery/test/testMultiAttr.js +0 -16
  188. data/app/components/marty/script_form/client/mode/xquery/test/testNamespaces.js +0 -91
  189. data/app/components/marty/script_form/client/mode/xquery/test/testProcessingInstructions.js +0 -16
  190. data/app/components/marty/script_form/client/mode/xquery/test/testQuotes.js +0 -19
  191. data/app/components/marty/script_form/client/mode/xquery/xquery.js +0 -451
  192. data/app/components/marty/script_form/client/mode/yaml/index.html +0 -68
  193. data/app/components/marty/script_form/client/mode/yaml/yaml.js +0 -95
  194. data/app/components/marty/script_form/client/theme/ambiance.css +0 -81
  195. data/app/components/marty/script_form/client/theme/blackboard.css +0 -25
  196. data/app/components/marty/script_form/client/theme/cobalt.css +0 -18
  197. data/app/components/marty/script_form/client/theme/eclipse.css +0 -25
  198. data/app/components/marty/script_form/client/theme/elegant.css +0 -10
  199. data/app/components/marty/script_form/client/theme/erlang-dark.css +0 -21
  200. data/app/components/marty/script_form/client/theme/lesser-dark.css +0 -44
  201. data/app/components/marty/script_form/client/theme/monokai.css +0 -28
  202. data/app/components/marty/script_form/client/theme/neat.css +0 -9
  203. data/app/components/marty/script_form/client/theme/night.css +0 -21
  204. data/app/components/marty/script_form/client/theme/rubyblue.css +0 -21
  205. data/app/components/marty/script_form/client/theme/vibrant-ink.css +0 -27
  206. data/app/components/marty/script_form/client/theme/xq-dark.css +0 -46
  207. data/app/components/marty/script_form/client/util/closetag.js +0 -164
  208. data/app/components/marty/script_form/client/util/dialog.css +0 -27
  209. data/app/components/marty/script_form/client/util/dialog.js +0 -70
  210. data/app/components/marty/script_form/client/util/foldcode.js +0 -196
  211. data/app/components/marty/script_form/client/util/formatting.js +0 -193
  212. data/app/components/marty/script_form/client/util/javascript-hint.js +0 -134
  213. data/app/components/marty/script_form/client/util/loadmode.js +0 -51
  214. data/app/components/marty/script_form/client/util/match-highlighter.js +0 -44
  215. data/app/components/marty/script_form/client/util/multiplex.js +0 -77
  216. data/app/components/marty/script_form/client/util/overlay.js +0 -54
  217. data/app/components/marty/script_form/client/util/pig-hint.js +0 -123
  218. data/app/components/marty/script_form/client/util/runmode-standalone.js +0 -90
  219. data/app/components/marty/script_form/client/util/runmode.js +0 -53
  220. data/app/components/marty/script_form/client/util/search.js +0 -118
  221. data/app/components/marty/script_form/client/util/searchcursor.js +0 -119
  222. data/app/components/marty/script_form/client/util/simple-hint.css +0 -16
  223. data/app/components/marty/script_form/client/util/simple-hint.js +0 -97
  224. data/app/components/marty/script_form/client/util/xml-hint.js +0 -137
  225. data/lib/marty/javascript/grid_view_in_form.js +0 -81
@@ -0,0 +1,399 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ function wordRegexp(words) {
15
+ return new RegExp("^((" + words.join(")|(") + "))\\b");
16
+ }
17
+
18
+ var wordOperators = wordRegexp(["and", "or", "not", "is"]);
19
+ var commonKeywords = ["as", "assert", "break", "class", "continue",
20
+ "def", "del", "elif", "else", "except", "finally",
21
+ "for", "from", "global", "if", "import",
22
+ "lambda", "pass", "raise", "return",
23
+ "try", "while", "with", "yield", "in"];
24
+ var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr",
25
+ "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
26
+ "enumerate", "eval", "filter", "float", "format", "frozenset",
27
+ "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
28
+ "input", "int", "isinstance", "issubclass", "iter", "len",
29
+ "list", "locals", "map", "max", "memoryview", "min", "next",
30
+ "object", "oct", "open", "ord", "pow", "property", "range",
31
+ "repr", "reversed", "round", "set", "setattr", "slice",
32
+ "sorted", "staticmethod", "str", "sum", "super", "tuple",
33
+ "type", "vars", "zip", "__import__", "NotImplemented",
34
+ "Ellipsis", "__debug__"];
35
+ CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins));
36
+
37
+ function top(state) {
38
+ return state.scopes[state.scopes.length - 1];
39
+ }
40
+
41
+ CodeMirror.defineMode("python", function(conf, parserConf) {
42
+ var ERRORCLASS = "error";
43
+
44
+ var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.\\]/;
45
+ // (Backwards-compatiblity with old, cumbersome config system)
46
+ var operators = [parserConf.singleOperators, parserConf.doubleOperators, parserConf.doubleDelimiters, parserConf.tripleDelimiters,
47
+ parserConf.operators || /^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@])/]
48
+ for (var i = 0; i < operators.length; i++) if (!operators[i]) operators.splice(i--, 1)
49
+
50
+ var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
51
+
52
+ var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
53
+ if (parserConf.extra_keywords != undefined)
54
+ myKeywords = myKeywords.concat(parserConf.extra_keywords);
55
+
56
+ if (parserConf.extra_builtins != undefined)
57
+ myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
58
+
59
+ var py3 = !(parserConf.version && Number(parserConf.version) < 3)
60
+ if (py3) {
61
+ // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
62
+ var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
63
+ myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
64
+ myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
65
+ var stringPrefixes = new RegExp("^(([rbuf]|(br)|(fr))?('{3}|\"{3}|['\"]))", "i");
66
+ } else {
67
+ var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
68
+ myKeywords = myKeywords.concat(["exec", "print"]);
69
+ myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
70
+ "file", "intern", "long", "raw_input", "reduce", "reload",
71
+ "unichr", "unicode", "xrange", "False", "True", "None"]);
72
+ var stringPrefixes = new RegExp("^(([rubf]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
73
+ }
74
+ var keywords = wordRegexp(myKeywords);
75
+ var builtins = wordRegexp(myBuiltins);
76
+
77
+ // tokenizers
78
+ function tokenBase(stream, state) {
79
+ var sol = stream.sol() && state.lastToken != "\\"
80
+ if (sol) state.indent = stream.indentation()
81
+ // Handle scope changes
82
+ if (sol && top(state).type == "py") {
83
+ var scopeOffset = top(state).offset;
84
+ if (stream.eatSpace()) {
85
+ var lineOffset = stream.indentation();
86
+ if (lineOffset > scopeOffset)
87
+ pushPyScope(state);
88
+ else if (lineOffset < scopeOffset && dedent(stream, state) && stream.peek() != "#")
89
+ state.errorToken = true;
90
+ return null;
91
+ } else {
92
+ var style = tokenBaseInner(stream, state);
93
+ if (scopeOffset > 0 && dedent(stream, state))
94
+ style += " " + ERRORCLASS;
95
+ return style;
96
+ }
97
+ }
98
+ return tokenBaseInner(stream, state);
99
+ }
100
+
101
+ function tokenBaseInner(stream, state) {
102
+ if (stream.eatSpace()) return null;
103
+
104
+ // Handle Comments
105
+ if (stream.match(/^#.*/)) return "comment";
106
+
107
+ // Handle Number Literals
108
+ if (stream.match(/^[0-9\.]/, false)) {
109
+ var floatLiteral = false;
110
+ // Floats
111
+ if (stream.match(/^[\d_]*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
112
+ if (stream.match(/^[\d_]+\.\d*/)) { floatLiteral = true; }
113
+ if (stream.match(/^\.\d+/)) { floatLiteral = true; }
114
+ if (floatLiteral) {
115
+ // Float literals may be "imaginary"
116
+ stream.eat(/J/i);
117
+ return "number";
118
+ }
119
+ // Integers
120
+ var intLiteral = false;
121
+ // Hex
122
+ if (stream.match(/^0x[0-9a-f_]+/i)) intLiteral = true;
123
+ // Binary
124
+ if (stream.match(/^0b[01_]+/i)) intLiteral = true;
125
+ // Octal
126
+ if (stream.match(/^0o[0-7_]+/i)) intLiteral = true;
127
+ // Decimal
128
+ if (stream.match(/^[1-9][\d_]*(e[\+\-]?[\d_]+)?/)) {
129
+ // Decimal literals may be "imaginary"
130
+ stream.eat(/J/i);
131
+ // TODO - Can you have imaginary longs?
132
+ intLiteral = true;
133
+ }
134
+ // Zero by itself with no other piece of number.
135
+ if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
136
+ if (intLiteral) {
137
+ // Integer literals may be "long"
138
+ stream.eat(/L/i);
139
+ return "number";
140
+ }
141
+ }
142
+
143
+ // Handle Strings
144
+ if (stream.match(stringPrefixes)) {
145
+ var isFmtString = stream.current().toLowerCase().indexOf('f') !== -1;
146
+ if (!isFmtString) {
147
+ state.tokenize = tokenStringFactory(stream.current(), state.tokenize);
148
+ return state.tokenize(stream, state);
149
+ } else {
150
+ state.tokenize = formatStringFactory(stream.current(), state.tokenize);
151
+ return state.tokenize(stream, state);
152
+ }
153
+ }
154
+
155
+ for (var i = 0; i < operators.length; i++)
156
+ if (stream.match(operators[i])) return "operator"
157
+
158
+ if (stream.match(delimiters)) return "punctuation";
159
+
160
+ if (state.lastToken == "." && stream.match(identifiers))
161
+ return "property";
162
+
163
+ if (stream.match(keywords) || stream.match(wordOperators))
164
+ return "keyword";
165
+
166
+ if (stream.match(builtins))
167
+ return "builtin";
168
+
169
+ if (stream.match(/^(self|cls)\b/))
170
+ return "variable-2";
171
+
172
+ if (stream.match(identifiers)) {
173
+ if (state.lastToken == "def" || state.lastToken == "class")
174
+ return "def";
175
+ return "variable";
176
+ }
177
+
178
+ // Handle non-detected items
179
+ stream.next();
180
+ return ERRORCLASS;
181
+ }
182
+
183
+ function formatStringFactory(delimiter, tokenOuter) {
184
+ while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
185
+ delimiter = delimiter.substr(1);
186
+
187
+ var singleline = delimiter.length == 1;
188
+ var OUTCLASS = "string";
189
+
190
+ function tokenNestedExpr(depth) {
191
+ return function(stream, state) {
192
+ var inner = tokenBaseInner(stream, state)
193
+ if (inner == "punctuation") {
194
+ if (stream.current() == "{") {
195
+ state.tokenize = tokenNestedExpr(depth + 1)
196
+ } else if (stream.current() == "}") {
197
+ if (depth > 1) state.tokenize = tokenNestedExpr(depth - 1)
198
+ else state.tokenize = tokenString
199
+ }
200
+ }
201
+ return inner
202
+ }
203
+ }
204
+
205
+ function tokenString(stream, state) {
206
+ while (!stream.eol()) {
207
+ stream.eatWhile(/[^'"\{\}\\]/);
208
+ if (stream.eat("\\")) {
209
+ stream.next();
210
+ if (singleline && stream.eol())
211
+ return OUTCLASS;
212
+ } else if (stream.match(delimiter)) {
213
+ state.tokenize = tokenOuter;
214
+ return OUTCLASS;
215
+ } else if (stream.match('{{')) {
216
+ // ignore {{ in f-str
217
+ return OUTCLASS;
218
+ } else if (stream.match('{', false)) {
219
+ // switch to nested mode
220
+ state.tokenize = tokenNestedExpr(0)
221
+ if (stream.current()) return OUTCLASS;
222
+ else return state.tokenize(stream, state)
223
+ } else if (stream.match('}}')) {
224
+ return OUTCLASS;
225
+ } else if (stream.match('}')) {
226
+ // single } in f-string is an error
227
+ return ERRORCLASS;
228
+ } else {
229
+ stream.eat(/['"]/);
230
+ }
231
+ }
232
+ if (singleline) {
233
+ if (parserConf.singleLineStringErrors)
234
+ return ERRORCLASS;
235
+ else
236
+ state.tokenize = tokenOuter;
237
+ }
238
+ return OUTCLASS;
239
+ }
240
+ tokenString.isString = true;
241
+ return tokenString;
242
+ }
243
+
244
+ function tokenStringFactory(delimiter, tokenOuter) {
245
+ while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
246
+ delimiter = delimiter.substr(1);
247
+
248
+ var singleline = delimiter.length == 1;
249
+ var OUTCLASS = "string";
250
+
251
+ function tokenString(stream, state) {
252
+ while (!stream.eol()) {
253
+ stream.eatWhile(/[^'"\\]/);
254
+ if (stream.eat("\\")) {
255
+ stream.next();
256
+ if (singleline && stream.eol())
257
+ return OUTCLASS;
258
+ } else if (stream.match(delimiter)) {
259
+ state.tokenize = tokenOuter;
260
+ return OUTCLASS;
261
+ } else {
262
+ stream.eat(/['"]/);
263
+ }
264
+ }
265
+ if (singleline) {
266
+ if (parserConf.singleLineStringErrors)
267
+ return ERRORCLASS;
268
+ else
269
+ state.tokenize = tokenOuter;
270
+ }
271
+ return OUTCLASS;
272
+ }
273
+ tokenString.isString = true;
274
+ return tokenString;
275
+ }
276
+
277
+ function pushPyScope(state) {
278
+ while (top(state).type != "py") state.scopes.pop()
279
+ state.scopes.push({offset: top(state).offset + conf.indentUnit,
280
+ type: "py",
281
+ align: null})
282
+ }
283
+
284
+ function pushBracketScope(stream, state, type) {
285
+ var align = stream.match(/^([\s\[\{\(]|#.*)*$/, false) ? null : stream.column() + 1
286
+ state.scopes.push({offset: state.indent + hangingIndent,
287
+ type: type,
288
+ align: align})
289
+ }
290
+
291
+ function dedent(stream, state) {
292
+ var indented = stream.indentation();
293
+ while (state.scopes.length > 1 && top(state).offset > indented) {
294
+ if (top(state).type != "py") return true;
295
+ state.scopes.pop();
296
+ }
297
+ return top(state).offset != indented;
298
+ }
299
+
300
+ function tokenLexer(stream, state) {
301
+ if (stream.sol()) state.beginningOfLine = true;
302
+
303
+ var style = state.tokenize(stream, state);
304
+ var current = stream.current();
305
+
306
+ // Handle decorators
307
+ if (state.beginningOfLine && current == "@")
308
+ return stream.match(identifiers, false) ? "meta" : py3 ? "operator" : ERRORCLASS;
309
+
310
+ if (/\S/.test(current)) state.beginningOfLine = false;
311
+
312
+ if ((style == "variable" || style == "builtin")
313
+ && state.lastToken == "meta")
314
+ style = "meta";
315
+
316
+ // Handle scope changes.
317
+ if (current == "pass" || current == "return")
318
+ state.dedent += 1;
319
+
320
+ if (current == "lambda") state.lambda = true;
321
+ if (current == ":" && !state.lambda && top(state).type == "py")
322
+ pushPyScope(state);
323
+
324
+ if (current.length == 1 && !/string|comment/.test(style)) {
325
+ var delimiter_index = "[({".indexOf(current);
326
+ if (delimiter_index != -1)
327
+ pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
328
+
329
+ delimiter_index = "])}".indexOf(current);
330
+ if (delimiter_index != -1) {
331
+ if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent
332
+ else return ERRORCLASS;
333
+ }
334
+ }
335
+ if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
336
+ if (state.scopes.length > 1) state.scopes.pop();
337
+ state.dedent -= 1;
338
+ }
339
+
340
+ return style;
341
+ }
342
+
343
+ var external = {
344
+ startState: function(basecolumn) {
345
+ return {
346
+ tokenize: tokenBase,
347
+ scopes: [{offset: basecolumn || 0, type: "py", align: null}],
348
+ indent: basecolumn || 0,
349
+ lastToken: null,
350
+ lambda: false,
351
+ dedent: 0
352
+ };
353
+ },
354
+
355
+ token: function(stream, state) {
356
+ var addErr = state.errorToken;
357
+ if (addErr) state.errorToken = false;
358
+ var style = tokenLexer(stream, state);
359
+
360
+ if (style && style != "comment")
361
+ state.lastToken = (style == "keyword" || style == "punctuation") ? stream.current() : style;
362
+ if (style == "punctuation") style = null;
363
+
364
+ if (stream.eol() && state.lambda)
365
+ state.lambda = false;
366
+ return addErr ? style + " " + ERRORCLASS : style;
367
+ },
368
+
369
+ indent: function(state, textAfter) {
370
+ if (state.tokenize != tokenBase)
371
+ return state.tokenize.isString ? CodeMirror.Pass : 0;
372
+
373
+ var scope = top(state), closing = scope.type == textAfter.charAt(0)
374
+ if (scope.align != null)
375
+ return scope.align - (closing ? 1 : 0)
376
+ else
377
+ return scope.offset - (closing ? hangingIndent : 0)
378
+ },
379
+
380
+ electricInput: /^\s*[\}\]\)]$/,
381
+ closeBrackets: {triples: "'\""},
382
+ lineComment: "#",
383
+ fold: "indent"
384
+ };
385
+ return external;
386
+ });
387
+
388
+ CodeMirror.defineMIME("text/x-python", "python");
389
+
390
+ var words = function(str) { return str.split(" "); };
391
+
392
+ CodeMirror.defineMIME("text/x-cython", {
393
+ name: "python",
394
+ extra_keywords: words("by cdef cimport cpdef ctypedef enum except "+
395
+ "extern gil include nogil property public "+
396
+ "readonly struct union DEF IF ELIF ELSE")
397
+ });
398
+
399
+ });
@@ -1,4 +1,17 @@
1
- CodeMirror.defineMode("ruby", function(config, parserConfig) {
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineMode("ruby", function(config) {
2
15
  function wordObj(words) {
3
16
  var o = {};
4
17
  for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
@@ -10,9 +23,9 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
10
23
  "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
11
24
  "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
12
25
  "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
13
- "require_relative", "extend", "autoload"
26
+ "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
14
27
  ]);
15
- var indentWords = wordObj(["def", "class", "case", "for", "while", "do", "module", "then",
28
+ var indentWords = wordObj(["def", "class", "case", "for", "while", "until", "module", "then",
16
29
  "catch", "loop", "proc", "begin"]);
17
30
  var dedentWords = wordObj(["end", "until"]);
18
31
  var matching = {"[": "]", "{": "}", "(": ")"};
@@ -24,22 +37,26 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
24
37
  }
25
38
 
26
39
  function tokenBase(stream, state) {
27
- curPunc = null;
28
40
  if (stream.sol() && stream.match("=begin") && stream.eol()) {
29
41
  state.tokenize.push(readBlockComment);
30
42
  return "comment";
31
43
  }
32
44
  if (stream.eatSpace()) return null;
33
45
  var ch = stream.next(), m;
34
- if (ch == "`" || ch == "'" || ch == '"' ||
35
- (ch == "/" && !stream.eol() && stream.peek() != " ")) {
46
+ if (ch == "`" || ch == "'" || ch == '"') {
36
47
  return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
48
+ } else if (ch == "/") {
49
+ if (regexpAhead(stream))
50
+ return chain(readQuoted(ch, "string-2", true), stream, state);
51
+ else
52
+ return "operator";
37
53
  } else if (ch == "%") {
38
- var style, embed = false;
54
+ var style = "string", embed = true;
39
55
  if (stream.eat("s")) style = "atom";
40
- else if (stream.eat(/[WQ]/)) { style = "string"; embed = true; }
41
- else if (stream.eat(/[wxqr]/)) style = "string";
42
- var delim = stream.eat(/[^\w\s]/);
56
+ else if (stream.eat(/[WQ]/)) style = "string";
57
+ else if (stream.eat(/[r]/)) style = "string-2";
58
+ else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
59
+ var delim = stream.eat(/[^\w\s=]/);
43
60
  if (!delim) return "operator";
44
61
  if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
45
62
  return chain(readQuoted(delim, style, embed, true), stream, state);
@@ -64,18 +81,42 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
64
81
  } else if (ch == ":") {
65
82
  if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
66
83
  if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
67
- stream.eatWhile(/[\w\?]/);
68
- return "atom";
69
- } else if (ch == "@") {
84
+
85
+ // :> :>> :< :<< are valid symbols
86
+ if (stream.eat(/[\<\>]/)) {
87
+ stream.eat(/[\<\>]/);
88
+ return "atom";
89
+ }
90
+
91
+ // :+ :- :/ :* :| :& :! are valid symbols
92
+ if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) {
93
+ return "atom";
94
+ }
95
+
96
+ // Symbols can't start by a digit
97
+ if (stream.eat(/[a-zA-Z$@_\xa1-\uffff]/)) {
98
+ stream.eatWhile(/[\w$\xa1-\uffff]/);
99
+ // Only one ? ! = is allowed and only as the last character
100
+ stream.eat(/[\?\!\=]/);
101
+ return "atom";
102
+ }
103
+ return "operator";
104
+ } else if (ch == "@" && stream.match(/^@?[a-zA-Z_\xa1-\uffff]/)) {
70
105
  stream.eat("@");
71
- stream.eatWhile(/[\w\?]/);
106
+ stream.eatWhile(/[\w\xa1-\uffff]/);
72
107
  return "variable-2";
73
108
  } else if (ch == "$") {
74
- stream.next();
75
- stream.eatWhile(/[\w\?]/);
109
+ if (stream.eat(/[a-zA-Z_]/)) {
110
+ stream.eatWhile(/[\w]/);
111
+ } else if (stream.eat(/\d/)) {
112
+ stream.eat(/\d/);
113
+ } else {
114
+ stream.next(); // Must be a special global like $: or $!
115
+ }
76
116
  return "variable-3";
77
- } else if (/\w/.test(ch)) {
78
- stream.eatWhile(/[\w\?]/);
117
+ } else if (/[a-zA-Z_\xa1-\uffff]/.test(ch)) {
118
+ stream.eatWhile(/[\w\xa1-\uffff]/);
119
+ stream.eat(/[\?\!]/);
79
120
  if (stream.eat(":")) return "atom";
80
121
  return "ident";
81
122
  } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
@@ -87,39 +128,88 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
87
128
  } else if (ch == "-" && stream.eat(">")) {
88
129
  return "arrow";
89
130
  } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
90
- stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
131
+ var more = stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
132
+ if (ch == "." && !more) curPunc = ".";
91
133
  return "operator";
92
134
  } else {
93
135
  return null;
94
136
  }
95
137
  }
96
138
 
97
- function tokenBaseUntilBrace() {
98
- var depth = 1;
139
+ function regexpAhead(stream) {
140
+ var start = stream.pos, depth = 0, next, found = false, escaped = false
141
+ while ((next = stream.next()) != null) {
142
+ if (!escaped) {
143
+ if ("[{(".indexOf(next) > -1) {
144
+ depth++
145
+ } else if ("]})".indexOf(next) > -1) {
146
+ depth--
147
+ if (depth < 0) break
148
+ } else if (next == "/" && depth == 0) {
149
+ found = true
150
+ break
151
+ }
152
+ escaped = next == "\\"
153
+ } else {
154
+ escaped = false
155
+ }
156
+ }
157
+ stream.backUp(stream.pos - start)
158
+ return found
159
+ }
160
+
161
+ function tokenBaseUntilBrace(depth) {
162
+ if (!depth) depth = 1;
99
163
  return function(stream, state) {
100
164
  if (stream.peek() == "}") {
101
- depth--;
102
- if (depth == 0) {
165
+ if (depth == 1) {
103
166
  state.tokenize.pop();
104
167
  return state.tokenize[state.tokenize.length-1](stream, state);
168
+ } else {
169
+ state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth - 1);
105
170
  }
106
171
  } else if (stream.peek() == "{") {
107
- depth++;
172
+ state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth + 1);
108
173
  }
109
174
  return tokenBase(stream, state);
110
175
  };
111
176
  }
177
+ function tokenBaseOnce() {
178
+ var alreadyCalled = false;
179
+ return function(stream, state) {
180
+ if (alreadyCalled) {
181
+ state.tokenize.pop();
182
+ return state.tokenize[state.tokenize.length-1](stream, state);
183
+ }
184
+ alreadyCalled = true;
185
+ return tokenBase(stream, state);
186
+ };
187
+ }
112
188
  function readQuoted(quote, style, embed, unescaped) {
113
189
  return function(stream, state) {
114
190
  var escaped = false, ch;
191
+
192
+ if (state.context.type === 'read-quoted-paused') {
193
+ state.context = state.context.prev;
194
+ stream.eat("}");
195
+ }
196
+
115
197
  while ((ch = stream.next()) != null) {
116
198
  if (ch == quote && (unescaped || !escaped)) {
117
199
  state.tokenize.pop();
118
200
  break;
119
201
  }
120
- if (embed && ch == "#" && !escaped && stream.eat("{")) {
121
- state.tokenize.push(tokenBaseUntilBrace(arguments.callee));
122
- break;
202
+ if (embed && ch == "#" && !escaped) {
203
+ if (stream.eat("{")) {
204
+ if (quote == "}") {
205
+ state.context = {prev: state.context, type: 'read-quoted-paused'};
206
+ }
207
+ state.tokenize.push(tokenBaseUntilBrace());
208
+ break;
209
+ } else if (/[@\$]/.test(stream.peek())) {
210
+ state.tokenize.push(tokenBaseOnce());
211
+ break;
212
+ }
123
213
  }
124
214
  escaped = !escaped && ch == "\\";
125
215
  }
@@ -151,20 +241,28 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
151
241
  },
152
242
 
153
243
  token: function(stream, state) {
244
+ curPunc = null;
154
245
  if (stream.sol()) state.indented = stream.indentation();
155
246
  var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
247
+ var thisTok = curPunc;
156
248
  if (style == "ident") {
157
249
  var word = stream.current();
158
- style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
250
+ style = state.lastTok == "." ? "property"
251
+ : keywords.propertyIsEnumerable(stream.current()) ? "keyword"
159
252
  : /^[A-Z]/.test(word) ? "tag"
160
253
  : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
161
254
  : "variable";
162
- if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
163
- else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
164
- else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
165
- kwtype = "indent";
255
+ if (style == "keyword") {
256
+ thisTok = word;
257
+ if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
258
+ else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
259
+ else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
260
+ kwtype = "indent";
261
+ else if (word == "do" && state.context.indented < state.indented)
262
+ kwtype = "indent";
263
+ }
166
264
  }
167
- if (curPunc || (style && style != "comment")) state.lastTok = word || curPunc || style;
265
+ if (curPunc || (style && style != "comment")) state.lastTok = thisTok;
168
266
  if (curPunc == "|") state.varList = !state.varList;
169
267
 
170
268
  if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
@@ -186,10 +284,13 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
186
284
  return ct.indented + (closing ? 0 : config.indentUnit) +
187
285
  (state.continuedLine ? config.indentUnit : 0);
188
286
  },
189
- electricChars: "}de" // enD and rescuE
190
287
 
288
+ electricInput: /^\s*(?:end|rescue|elsif|else|\})$/,
289
+ lineComment: "#",
290
+ fold: "indent"
191
291
  };
192
292
  });
193
293
 
194
294
  CodeMirror.defineMIME("text/x-ruby", "ruby");
195
295
 
296
+ });