ace-rails-ap 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +1 -1
  3. data/lib/ace/rails/version.rb +1 -1
  4. data/vendor/assets/javascripts/ace/ace.js +6911 -5290
  5. data/vendor/assets/javascripts/ace/ext-chromevox.js +537 -0
  6. data/vendor/assets/javascripts/ace/ext-elastic_tabstops_lite.js +301 -0
  7. data/vendor/assets/javascripts/ace/ext-emmet.js +1109 -0
  8. data/vendor/assets/javascripts/ace/ext-keybinding_menu.js +207 -0
  9. data/vendor/assets/javascripts/ace/ext-language_tools.js +1665 -0
  10. data/vendor/assets/javascripts/ace/ext-modelist.js +168 -0
  11. data/vendor/assets/javascripts/ace/ext-old_ie.js +500 -0
  12. data/vendor/assets/javascripts/ace/ext-options.js +252 -0
  13. data/vendor/assets/javascripts/ace/ext-searchbox.js +421 -0
  14. data/vendor/assets/javascripts/ace/ext-settings_menu.js +632 -0
  15. data/vendor/assets/javascripts/ace/ext-spellcheck.js +68 -0
  16. data/vendor/assets/javascripts/ace/ext-split.js +271 -0
  17. data/vendor/assets/javascripts/ace/ext-static_highlight.js +178 -0
  18. data/vendor/assets/javascripts/ace/ext-statusbar.js +47 -0
  19. data/vendor/assets/javascripts/ace/ext-textarea.js +478 -0
  20. data/vendor/assets/javascripts/ace/ext-themelist.js +86 -0
  21. data/vendor/assets/javascripts/ace/ext-whitespace.js +206 -0
  22. data/vendor/assets/javascripts/ace/keybinding-emacs.js +822 -131
  23. data/vendor/assets/javascripts/ace/keybinding-vim.js +382 -258
  24. data/vendor/assets/javascripts/ace/mode-abap.js +261 -0
  25. data/vendor/assets/javascripts/ace/mode-actionscript.js +257 -0
  26. data/vendor/assets/javascripts/ace/mode-ada.js +118 -0
  27. data/vendor/assets/javascripts/ace/mode-asciidoc.js +373 -0
  28. data/vendor/assets/javascripts/ace/mode-assembly_x86.js +217 -0
  29. data/vendor/assets/javascripts/ace/mode-autohotkey.js +225 -0
  30. data/vendor/assets/javascripts/ace/mode-batchfile.js +213 -0
  31. data/vendor/assets/javascripts/ace/mode-c9search.js +144 -124
  32. data/vendor/assets/javascripts/ace/mode-c_cpp.js +296 -254
  33. data/vendor/assets/javascripts/ace/mode-clojure.js +113 -177
  34. data/vendor/assets/javascripts/ace/mode-cobol.js +125 -0
  35. data/vendor/assets/javascripts/ace/mode-coffee.js +152 -235
  36. data/vendor/assets/javascripts/ace/mode-coldfusion.js +823 -835
  37. data/vendor/assets/javascripts/ace/mode-csharp.js +325 -187
  38. data/vendor/assets/javascripts/ace/mode-css.js +583 -297
  39. data/vendor/assets/javascripts/ace/mode-curly.js +2423 -0
  40. data/vendor/assets/javascripts/ace/mode-d.js +492 -0
  41. data/vendor/assets/javascripts/ace/mode-dart.js +993 -0
  42. data/vendor/assets/javascripts/ace/mode-diff.js +124 -204
  43. data/vendor/assets/javascripts/ace/mode-django.js +2448 -0
  44. data/vendor/assets/javascripts/ace/mode-dot.js +361 -0
  45. data/vendor/assets/javascripts/ace/mode-ejs.js +2817 -0
  46. data/vendor/assets/javascripts/ace/mode-erlang.js +987 -0
  47. data/vendor/assets/javascripts/ace/mode-forth.js +280 -0
  48. data/vendor/assets/javascripts/ace/mode-ftl.js +1061 -0
  49. data/vendor/assets/javascripts/ace/mode-glsl.js +313 -275
  50. data/vendor/assets/javascripts/ace/mode-golang.js +268 -275
  51. data/vendor/assets/javascripts/ace/mode-groovy.js +347 -492
  52. data/vendor/assets/javascripts/ace/mode-haml.js +498 -0
  53. data/vendor/assets/javascripts/ace/mode-handlebars.js +2433 -0
  54. data/vendor/assets/javascripts/ace/mode-haskell.js +362 -0
  55. data/vendor/assets/javascripts/ace/mode-haxe.js +226 -202
  56. data/vendor/assets/javascripts/ace/mode-html.js +1099 -802
  57. data/vendor/assets/javascripts/ace/mode-html_completions.js +309 -0
  58. data/vendor/assets/javascripts/ace/mode-html_ruby.js +2822 -0
  59. data/vendor/assets/javascripts/ace/mode-ini.js +185 -0
  60. data/vendor/assets/javascripts/ace/mode-jack.js +653 -0
  61. data/vendor/assets/javascripts/ace/mode-jade.js +2081 -0
  62. data/vendor/assets/javascripts/ace/mode-java.js +339 -488
  63. data/vendor/assets/javascripts/ace/mode-javascript.js +342 -478
  64. data/vendor/assets/javascripts/ace/mode-json.js +215 -178
  65. data/vendor/assets/javascripts/ace/mode-jsoniq.js +2761 -0
  66. data/vendor/assets/javascripts/ace/mode-jsp.js +1553 -0
  67. data/vendor/assets/javascripts/ace/mode-jsx.js +325 -289
  68. data/vendor/assets/javascripts/ace/mode-julia.js +286 -0
  69. data/vendor/assets/javascripts/ace/mode-latex.js +141 -46
  70. data/vendor/assets/javascripts/ace/mode-less.js +493 -151
  71. data/vendor/assets/javascripts/ace/mode-liquid.js +594 -656
  72. data/vendor/assets/javascripts/ace/mode-lisp.js +137 -0
  73. data/vendor/assets/javascripts/ace/mode-livescript.js +288 -0
  74. data/vendor/assets/javascripts/ace/mode-logiql.js +669 -0
  75. data/vendor/assets/javascripts/ace/mode-lsl.js +890 -0
  76. data/vendor/assets/javascripts/ace/mode-lua.js +274 -368
  77. data/vendor/assets/javascripts/ace/mode-luapage.js +1331 -1107
  78. data/vendor/assets/javascripts/ace/mode-lucene.js +64 -0
  79. data/vendor/assets/javascripts/ace/mode-makefile.js +332 -0
  80. data/vendor/assets/javascripts/ace/mode-markdown.js +1303 -948
  81. data/vendor/assets/javascripts/ace/mode-matlab.js +230 -0
  82. data/vendor/assets/javascripts/ace/mode-mushcode.js +705 -0
  83. data/vendor/assets/javascripts/ace/mode-mushcode_high_rules.js +569 -0
  84. data/vendor/assets/javascripts/ace/mode-mysql.js +185 -0
  85. data/vendor/assets/javascripts/ace/mode-nix.js +935 -0
  86. data/vendor/assets/javascripts/ace/mode-objectivec.js +699 -0
  87. data/vendor/assets/javascripts/ace/mode-ocaml.js +44 -63
  88. data/vendor/assets/javascripts/ace/mode-pascal.js +233 -0
  89. data/vendor/assets/javascripts/ace/mode-perl.js +116 -189
  90. data/vendor/assets/javascripts/ace/mode-pgsql.js +886 -500
  91. data/vendor/assets/javascripts/ace/mode-php.js +1158 -380
  92. data/vendor/assets/javascripts/ace/mode-plain_text.js +56 -0
  93. data/vendor/assets/javascripts/ace/mode-powershell.js +222 -167
  94. data/vendor/assets/javascripts/ace/mode-prolog.js +354 -0
  95. data/vendor/assets/javascripts/ace/mode-properties.js +100 -0
  96. data/vendor/assets/javascripts/ace/mode-protobuf.js +885 -0
  97. data/vendor/assets/javascripts/ace/mode-python.js +99 -201
  98. data/vendor/assets/javascripts/ace/mode-r.js +337 -0
  99. data/vendor/assets/javascripts/ace/mode-rdoc.js +210 -0
  100. data/vendor/assets/javascripts/ace/mode-rhtml.js +2663 -0
  101. data/vendor/assets/javascripts/ace/mode-ruby.js +262 -136
  102. data/vendor/assets/javascripts/ace/mode-rust.js +245 -0
  103. data/vendor/assets/javascripts/ace/mode-sass.js +443 -0
  104. data/vendor/assets/javascripts/ace/mode-scad.js +225 -240
  105. data/vendor/assets/javascripts/ace/mode-scala.js +340 -494
  106. data/vendor/assets/javascripts/ace/mode-scheme.js +143 -0
  107. data/vendor/assets/javascripts/ace/mode-scss.js +499 -157
  108. data/vendor/assets/javascripts/ace/mode-sh.js +180 -110
  109. data/vendor/assets/javascripts/ace/mode-sjs.js +1154 -0
  110. data/vendor/assets/javascripts/ace/mode-snippets.js +198 -0
  111. data/vendor/assets/javascripts/ace/mode-soy_template.js +2707 -0
  112. data/vendor/assets/javascripts/ace/mode-space.js +160 -0
  113. data/vendor/assets/javascripts/ace/mode-sql.js +48 -69
  114. data/vendor/assets/javascripts/ace/mode-stylus.js +447 -0
  115. data/vendor/assets/javascripts/ace/mode-svg.js +552 -605
  116. data/vendor/assets/javascripts/ace/mode-tcl.js +139 -98
  117. data/vendor/assets/javascripts/ace/mode-tex.js +187 -0
  118. data/vendor/assets/javascripts/ace/mode-textile.js +29 -40
  119. data/vendor/assets/javascripts/ace/mode-tmsnippet.js +200 -0
  120. data/vendor/assets/javascripts/ace/mode-toml.js +177 -0
  121. data/vendor/assets/javascripts/ace/mode-twig.js +2228 -0
  122. data/vendor/assets/javascripts/ace/mode-typescript.js +1018 -0
  123. data/vendor/assets/javascripts/ace/mode-vbscript.js +250 -0
  124. data/vendor/assets/javascripts/ace/mode-velocity.js +1621 -0
  125. data/vendor/assets/javascripts/ace/mode-verilog.js +127 -0
  126. data/vendor/assets/javascripts/ace/mode-vhdl.js +139 -0
  127. data/vendor/assets/javascripts/ace/mode-xml.js +350 -242
  128. data/vendor/assets/javascripts/ace/mode-xquery.js +2490 -300
  129. data/vendor/assets/javascripts/ace/mode-yaml.js +146 -45
  130. data/vendor/assets/javascripts/ace/theme-ambiance.js +202 -0
  131. data/vendor/assets/javascripts/ace/theme-chaos.js +179 -0
  132. data/vendor/assets/javascripts/ace/theme-chrome.js +97 -153
  133. data/vendor/assets/javascripts/ace/theme-clouds.js +78 -119
  134. data/vendor/assets/javascripts/ace/theme-clouds_midnight.js +79 -120
  135. data/vendor/assets/javascripts/ace/theme-cobalt.js +89 -140
  136. data/vendor/assets/javascripts/ace/theme-crimson_editor.js +93 -145
  137. data/vendor/assets/javascripts/ace/theme-dawn.js +84 -143
  138. data/vendor/assets/javascripts/ace/theme-dreamweaver.js +99 -162
  139. data/vendor/assets/javascripts/ace/theme-eclipse.js +78 -111
  140. data/vendor/assets/javascripts/ace/theme-github.js +70 -121
  141. data/vendor/assets/javascripts/ace/theme-idle_fingers.js +75 -134
  142. data/vendor/assets/javascripts/ace/theme-kr.js +135 -0
  143. data/vendor/assets/javascripts/ace/theme-merbivore.js +80 -143
  144. data/vendor/assets/javascripts/ace/theme-merbivore_soft.js +81 -149
  145. data/vendor/assets/javascripts/ace/theme-mono_industrial.js +87 -146
  146. data/vendor/assets/javascripts/ace/theme-monokai.js +88 -146
  147. data/vendor/assets/javascripts/ace/theme-pastel_on_dark.js +82 -142
  148. data/vendor/assets/javascripts/ace/theme-solarized_dark.js +83 -144
  149. data/vendor/assets/javascripts/ace/theme-solarized_light.js +76 -133
  150. data/vendor/assets/javascripts/ace/theme-terminal.js +145 -0
  151. data/vendor/assets/javascripts/ace/theme-textmate.js +101 -158
  152. data/vendor/assets/javascripts/ace/theme-tomorrow.js +89 -163
  153. data/vendor/assets/javascripts/ace/theme-tomorrow_night.js +89 -163
  154. data/vendor/assets/javascripts/ace/theme-tomorrow_night_blue.js +89 -165
  155. data/vendor/assets/javascripts/ace/theme-tomorrow_night_bright.js +101 -162
  156. data/vendor/assets/javascripts/ace/theme-tomorrow_night_eighties.js +90 -160
  157. data/vendor/assets/javascripts/ace/theme-twilight.js +87 -158
  158. data/vendor/assets/javascripts/ace/theme-vibrant_ink.js +75 -140
  159. data/vendor/assets/javascripts/ace/theme-xcode.js +120 -0
  160. data/vendor/assets/javascripts/ace/worker-coffee.js +3049 -2665
  161. data/vendor/assets/javascripts/ace/worker-css.js +1779 -4376
  162. data/vendor/assets/javascripts/ace/worker-javascript.js +8701 -9008
  163. data/vendor/assets/javascripts/ace/worker-json.js +709 -1340
  164. data/vendor/assets/javascripts/ace/worker-lua.js +3525 -0
  165. data/vendor/assets/javascripts/ace/worker-php.js +6893 -0
  166. data/vendor/assets/javascripts/ace/worker-xquery.js +19924 -64507
  167. metadata +100 -17
@@ -0,0 +1,301 @@
1
+ /* ***** BEGIN LICENSE BLOCK *****
2
+ * Distributed under the BSD license:
3
+ *
4
+ * Copyright (c) 2012, Ajax.org B.V.
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ * * Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of Ajax.org B.V. nor the
15
+ * names of its contributors may be used to endorse or promote products
16
+ * derived from this software without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
22
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ *
29
+ * ***** END LICENSE BLOCK ***** */
30
+
31
+ define('ace/ext/elastic_tabstops_lite', ['require', 'exports', 'module' , 'ace/editor', 'ace/config'], function(require, exports, module) {
32
+
33
+
34
+ var ElasticTabstopsLite = function(editor) {
35
+ this.$editor = editor;
36
+ var self = this;
37
+ var changedRows = [];
38
+ var recordChanges = false;
39
+ this.onAfterExec = function() {
40
+ recordChanges = false;
41
+ self.processRows(changedRows);
42
+ changedRows = [];
43
+ };
44
+ this.onExec = function() {
45
+ recordChanges = true;
46
+ };
47
+ this.onChange = function(e) {
48
+ var range = e.data.range
49
+ if (recordChanges) {
50
+ if (changedRows.indexOf(range.start.row) == -1)
51
+ changedRows.push(range.start.row);
52
+ if (range.end.row != range.start.row)
53
+ changedRows.push(range.end.row);
54
+ }
55
+ };
56
+ };
57
+
58
+ (function() {
59
+ this.processRows = function(rows) {
60
+ this.$inChange = true;
61
+ var checkedRows = [];
62
+
63
+ for (var r = 0, rowCount = rows.length; r < rowCount; r++) {
64
+ var row = rows[r];
65
+
66
+ if (checkedRows.indexOf(row) > -1)
67
+ continue;
68
+
69
+ var cellWidthObj = this.$findCellWidthsForBlock(row);
70
+ var cellWidths = this.$setBlockCellWidthsToMax(cellWidthObj.cellWidths);
71
+ var rowIndex = cellWidthObj.firstRow;
72
+
73
+ for (var w = 0, l = cellWidths.length; w < l; w++) {
74
+ var widths = cellWidths[w];
75
+ checkedRows.push(rowIndex);
76
+ this.$adjustRow(rowIndex, widths);
77
+ rowIndex++;
78
+ }
79
+ }
80
+ this.$inChange = false;
81
+ };
82
+
83
+ this.$findCellWidthsForBlock = function(row) {
84
+ var cellWidths = [], widths;
85
+ var rowIter = row;
86
+ while (rowIter >= 0) {
87
+ widths = this.$cellWidthsForRow(rowIter);
88
+ if (widths.length == 0)
89
+ break;
90
+
91
+ cellWidths.unshift(widths);
92
+ rowIter--;
93
+ }
94
+ var firstRow = rowIter + 1;
95
+ rowIter = row;
96
+ var numRows = this.$editor.session.getLength();
97
+
98
+ while (rowIter < numRows - 1) {
99
+ rowIter++;
100
+
101
+ widths = this.$cellWidthsForRow(rowIter);
102
+ if (widths.length == 0)
103
+ break;
104
+
105
+ cellWidths.push(widths);
106
+ }
107
+
108
+ return { cellWidths: cellWidths, firstRow: firstRow };
109
+ };
110
+
111
+ this.$cellWidthsForRow = function(row) {
112
+ var selectionColumns = this.$selectionColumnsForRow(row);
113
+
114
+ var tabs = [-1].concat(this.$tabsForRow(row));
115
+ var widths = tabs.map(function(el) { return 0; } ).slice(1);
116
+ var line = this.$editor.session.getLine(row);
117
+
118
+ for (var i = 0, len = tabs.length - 1; i < len; i++) {
119
+ var leftEdge = tabs[i]+1;
120
+ var rightEdge = tabs[i+1];
121
+
122
+ var rightmostSelection = this.$rightmostSelectionInCell(selectionColumns, rightEdge);
123
+ var cell = line.substring(leftEdge, rightEdge);
124
+ widths[i] = Math.max(cell.replace(/\s+$/g,'').length, rightmostSelection - leftEdge);
125
+ }
126
+
127
+ return widths;
128
+ };
129
+
130
+ this.$selectionColumnsForRow = function(row) {
131
+ var selections = [], cursor = this.$editor.getCursorPosition();
132
+ if (this.$editor.session.getSelection().isEmpty()) {
133
+ if (row == cursor.row)
134
+ selections.push(cursor.column);
135
+ }
136
+
137
+ return selections;
138
+ };
139
+
140
+ this.$setBlockCellWidthsToMax = function(cellWidths) {
141
+ var startingNewBlock = true, blockStartRow, blockEndRow, maxWidth;
142
+ var columnInfo = this.$izip_longest(cellWidths);
143
+
144
+ for (var c = 0, l = columnInfo.length; c < l; c++) {
145
+ var column = columnInfo[c];
146
+ if (!column.push) {
147
+ console.error(column);
148
+ continue;
149
+ }
150
+ column.push(NaN);
151
+
152
+ for (var r = 0, s = column.length; r < s; r++) {
153
+ var width = column[r];
154
+ if (startingNewBlock) {
155
+ blockStartRow = r;
156
+ maxWidth = 0;
157
+ startingNewBlock = false;
158
+ }
159
+ if (isNaN(width)) {
160
+ blockEndRow = r;
161
+
162
+ for (var j = blockStartRow; j < blockEndRow; j++) {
163
+ cellWidths[j][c] = maxWidth;
164
+ }
165
+ startingNewBlock = true;
166
+ }
167
+
168
+ maxWidth = Math.max(maxWidth, width);
169
+ }
170
+ }
171
+
172
+ return cellWidths;
173
+ };
174
+
175
+ this.$rightmostSelectionInCell = function(selectionColumns, cellRightEdge) {
176
+ var rightmost = 0;
177
+
178
+ if (selectionColumns.length) {
179
+ var lengths = [];
180
+ for (var s = 0, length = selectionColumns.length; s < length; s++) {
181
+ if (selectionColumns[s] <= cellRightEdge)
182
+ lengths.push(s);
183
+ else
184
+ lengths.push(0);
185
+ }
186
+ rightmost = Math.max.apply(Math, lengths);
187
+ }
188
+
189
+ return rightmost;
190
+ };
191
+
192
+ this.$tabsForRow = function(row) {
193
+ var rowTabs = [], line = this.$editor.session.getLine(row),
194
+ re = /\t/g, match;
195
+
196
+ while ((match = re.exec(line)) != null) {
197
+ rowTabs.push(match.index);
198
+ }
199
+
200
+ return rowTabs;
201
+ };
202
+
203
+ this.$adjustRow = function(row, widths) {
204
+ var rowTabs = this.$tabsForRow(row);
205
+
206
+ if (rowTabs.length == 0)
207
+ return;
208
+
209
+ var bias = 0, location = -1;
210
+ var expandedSet = this.$izip(widths, rowTabs);
211
+
212
+ for (var i = 0, l = expandedSet.length; i < l; i++) {
213
+ var w = expandedSet[i][0], it = expandedSet[i][1];
214
+ location += 1 + w;
215
+ it += bias;
216
+ var difference = location - it;
217
+
218
+ if (difference == 0)
219
+ continue;
220
+
221
+ var partialLine = this.$editor.session.getLine(row).substr(0, it );
222
+ var strippedPartialLine = partialLine.replace(/\s*$/g, "");
223
+ var ispaces = partialLine.length - strippedPartialLine.length;
224
+
225
+ if (difference > 0) {
226
+ this.$editor.session.getDocument().insertInLine({row: row, column: it + 1}, Array(difference + 1).join(" ") + "\t");
227
+ this.$editor.session.getDocument().removeInLine(row, it, it + 1);
228
+
229
+ bias += difference;
230
+ }
231
+
232
+ if (difference < 0 && ispaces >= -difference) {
233
+ this.$editor.session.getDocument().removeInLine(row, it + difference, it);
234
+ bias += difference;
235
+ }
236
+ }
237
+ };
238
+ this.$izip_longest = function(iterables) {
239
+ if (!iterables[0])
240
+ return [];
241
+ var longest = iterables[0].length;
242
+ var iterablesLength = iterables.length;
243
+
244
+ for (var i = 1; i < iterablesLength; i++) {
245
+ var iLength = iterables[i].length;
246
+ if (iLength > longest)
247
+ longest = iLength;
248
+ }
249
+
250
+ var expandedSet = [];
251
+
252
+ for (var l = 0; l < longest; l++) {
253
+ var set = [];
254
+ for (var i = 0; i < iterablesLength; i++) {
255
+ if (iterables[i][l] === "")
256
+ set.push(NaN);
257
+ else
258
+ set.push(iterables[i][l]);
259
+ }
260
+
261
+ expandedSet.push(set);
262
+ }
263
+
264
+
265
+ return expandedSet;
266
+ };
267
+ this.$izip = function(widths, tabs) {
268
+ var size = widths.length >= tabs.length ? tabs.length : widths.length;
269
+
270
+ var expandedSet = [];
271
+ for (var i = 0; i < size; i++) {
272
+ var set = [ widths[i], tabs[i] ];
273
+ expandedSet.push(set);
274
+ }
275
+ return expandedSet;
276
+ };
277
+
278
+ }).call(ElasticTabstopsLite.prototype);
279
+
280
+ exports.ElasticTabstopsLite = ElasticTabstopsLite;
281
+
282
+ var Editor = require("../editor").Editor;
283
+ require("../config").defineOptions(Editor.prototype, "editor", {
284
+ useElasticTabstops: {
285
+ set: function(val) {
286
+ if (val) {
287
+ if (!this.elasticTabstops)
288
+ this.elasticTabstops = new ElasticTabstopsLite(this);
289
+ this.commands.on("afterExec", this.elasticTabstops.onAfterExec);
290
+ this.commands.on("exec", this.elasticTabstops.onExec);
291
+ this.on("change", this.elasticTabstops.onChange);
292
+ } else if (this.elasticTabstops) {
293
+ this.commands.removeListener("afterExec", this.elasticTabstops.onAfterExec);
294
+ this.commands.removeListener("exec", this.elasticTabstops.onExec);
295
+ this.removeListener("change", this.elasticTabstops.onChange);
296
+ }
297
+ }
298
+ }
299
+ });
300
+
301
+ });
@@ -0,0 +1,1109 @@
1
+ /* ***** BEGIN LICENSE BLOCK *****
2
+ * Distributed under the BSD license:
3
+ *
4
+ * Copyright (c) 2010, Ajax.org B.V.
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ * * Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of Ajax.org B.V. nor the
15
+ * names of its contributors may be used to endorse or promote products
16
+ * derived from this software without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
22
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ *
29
+ * ***** END LICENSE BLOCK ***** */
30
+
31
+ define('ace/ext/emmet', ['require', 'exports', 'module' , 'ace/keyboard/hash_handler', 'ace/editor', 'ace/snippets', 'ace/range', 'ace/config'], function(require, exports, module) {
32
+
33
+ var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
34
+ var Editor = require("ace/editor").Editor;
35
+ var snippetManager = require("ace/snippets").snippetManager;
36
+ var Range = require("ace/range").Range;
37
+ var emmet;
38
+
39
+ Editor.prototype.indexToPosition = function(index) {
40
+ return this.session.doc.indexToPosition(index);
41
+ };
42
+
43
+ Editor.prototype.positionToIndex = function(pos) {
44
+ return this.session.doc.positionToIndex(pos);
45
+ };
46
+ function AceEmmetEditor() {}
47
+
48
+ AceEmmetEditor.prototype = {
49
+ setupContext: function(editor) {
50
+ this.ace = editor;
51
+ this.indentation = editor.session.getTabString();
52
+ if (!emmet)
53
+ emmet = window.emmet;
54
+ emmet.require("resources").setVariable("indentation", this.indentation);
55
+ this.$syntax = null;
56
+ this.$syntax = this.getSyntax();
57
+ },
58
+ getSelectionRange: function() {
59
+ var range = this.ace.getSelectionRange();
60
+ return {
61
+ start: this.ace.positionToIndex(range.start),
62
+ end: this.ace.positionToIndex(range.end)
63
+ };
64
+ },
65
+ createSelection: function(start, end) {
66
+ this.ace.selection.setRange({
67
+ start: this.ace.indexToPosition(start),
68
+ end: this.ace.indexToPosition(end)
69
+ });
70
+ },
71
+ getCurrentLineRange: function() {
72
+ var row = this.ace.getCursorPosition().row;
73
+ var lineLength = this.ace.session.getLine(row).length;
74
+ var index = this.ace.positionToIndex({row: row, column: 0});
75
+ return {
76
+ start: index,
77
+ end: index + lineLength
78
+ };
79
+ },
80
+ getCaretPos: function(){
81
+ var pos = this.ace.getCursorPosition();
82
+ return this.ace.positionToIndex(pos);
83
+ },
84
+ setCaretPos: function(index){
85
+ var pos = this.ace.indexToPosition(index);
86
+ this.ace.clearSelection();
87
+ this.ace.selection.moveCursorToPosition(pos);
88
+ },
89
+ getCurrentLine: function() {
90
+ var row = this.ace.getCursorPosition().row;
91
+ return this.ace.session.getLine(row);
92
+ },
93
+ replaceContent: function(value, start, end, noIndent) {
94
+ if (end == null)
95
+ end = start == null ? this.getContent().length : start;
96
+ if (start == null)
97
+ start = 0;
98
+
99
+ var editor = this.ace;
100
+ var range = Range.fromPoints(editor.indexToPosition(start), editor.indexToPosition(end));
101
+ editor.session.remove(range);
102
+
103
+ range.end = range.start;
104
+
105
+ value = this.$updateTabstops(value);
106
+ snippetManager.insertSnippet(editor, value)
107
+ },
108
+ getContent: function(){
109
+ return this.ace.getValue();
110
+ },
111
+ getSyntax: function() {
112
+ if (this.$syntax)
113
+ return this.$syntax;
114
+ var syntax = this.ace.session.$modeId.split("/").pop();
115
+ if (syntax == "html" || syntax == "php") {
116
+ var cursor = this.ace.getCursorPosition();
117
+ var state = this.ace.session.getState(cursor.row);
118
+ if (typeof state != "string")
119
+ state = state[0];
120
+ if (state) {
121
+ state = state.split("-");
122
+ if (state.length > 1)
123
+ syntax = state[0];
124
+ else if (syntax == "php")
125
+ syntax = "html";
126
+ }
127
+ }
128
+ return syntax;
129
+ },
130
+ getProfileName: function() {
131
+ switch(this.getSyntax()) {
132
+ case "css": return "css";
133
+ case "xml":
134
+ case "xsl":
135
+ return "xml";
136
+ case "html":
137
+ var profile = emmet.require("resources").getVariable("profile");
138
+ if (!profile)
139
+ profile = this.ace.session.getLines(0,2).join("").search(/<!DOCTYPE[^>]+XHTML/i) != -1 ? "xhtml": "html";
140
+ return profile;
141
+ }
142
+ return "xhtml";
143
+ },
144
+ prompt: function(title) {
145
+ return prompt(title);
146
+ },
147
+ getSelection: function() {
148
+ return this.ace.session.getTextRange();
149
+ },
150
+ getFilePath: function() {
151
+ return "";
152
+ },
153
+ $updateTabstops: function(value) {
154
+ var base = 1000;
155
+ var zeroBase = 0;
156
+ var lastZero = null;
157
+ var range = emmet.require('range');
158
+ var ts = emmet.require('tabStops');
159
+ var settings = emmet.require('resources').getVocabulary("user");
160
+ var tabstopOptions = {
161
+ tabstop: function(data) {
162
+ var group = parseInt(data.group, 10);
163
+ var isZero = group === 0;
164
+ if (isZero)
165
+ group = ++zeroBase;
166
+ else
167
+ group += base;
168
+
169
+ var placeholder = data.placeholder;
170
+ if (placeholder) {
171
+ placeholder = ts.processText(placeholder, tabstopOptions);
172
+ }
173
+
174
+ var result = '${' + group + (placeholder ? ':' + placeholder : '') + '}';
175
+
176
+ if (isZero) {
177
+ lastZero = range.create(data.start, result);
178
+ }
179
+
180
+ return result
181
+ },
182
+ escape: function(ch) {
183
+ if (ch == '$') return '\\$';
184
+ if (ch == '\\') return '\\\\';
185
+ return ch;
186
+ }
187
+ };
188
+
189
+ value = ts.processText(value, tabstopOptions);
190
+
191
+ if (settings.variables['insert_final_tabstop'] && !/\$\{0\}$/.test(value)) {
192
+ value += '${0}';
193
+ } else if (lastZero) {
194
+ value = emmet.require('utils').replaceSubstring(value, '${0}', lastZero);
195
+ }
196
+
197
+ return value;
198
+ }
199
+ };
200
+
201
+
202
+ var keymap = {
203
+ expand_abbreviation: {"mac": "ctrl+alt+e", "win": "alt+e"},
204
+ match_pair_outward: {"mac": "ctrl+d", "win": "ctrl+,"},
205
+ match_pair_inward: {"mac": "ctrl+j", "win": "ctrl+shift+0"},
206
+ matching_pair: {"mac": "ctrl+alt+j", "win": "alt+j"},
207
+ next_edit_point: "alt+right",
208
+ prev_edit_point: "alt+left",
209
+ toggle_comment: {"mac": "command+/", "win": "ctrl+/"},
210
+ split_join_tag: {"mac": "shift+command+'", "win": "shift+ctrl+`"},
211
+ remove_tag: {"mac": "command+'", "win": "shift+ctrl+;"},
212
+ evaluate_math_expression: {"mac": "shift+command+y", "win": "shift+ctrl+y"},
213
+ increment_number_by_1: "ctrl+up",
214
+ decrement_number_by_1: "ctrl+down",
215
+ increment_number_by_01: "alt+up",
216
+ decrement_number_by_01: "alt+down",
217
+ increment_number_by_10: {"mac": "alt+command+up", "win": "shift+alt+up"},
218
+ decrement_number_by_10: {"mac": "alt+command+down", "win": "shift+alt+down"},
219
+ select_next_item: {"mac": "shift+command+.", "win": "shift+ctrl+."},
220
+ select_previous_item: {"mac": "shift+command+,", "win": "shift+ctrl+,"},
221
+ reflect_css_value: {"mac": "shift+command+r", "win": "shift+ctrl+r"},
222
+
223
+ encode_decode_data_url: {"mac": "shift+ctrl+d", "win": "ctrl+'"},
224
+ expand_abbreviation_with_tab: "Tab",
225
+ wrap_with_abbreviation: {"mac": "shift+ctrl+a", "win": "shift+ctrl+a"}
226
+ };
227
+
228
+ var editorProxy = new AceEmmetEditor();
229
+ exports.commands = new HashHandler();
230
+ exports.runEmmetCommand = function(editor) {
231
+ editorProxy.setupContext(editor);
232
+ if (editorProxy.getSyntax() == "php")
233
+ return false;
234
+ var actions = emmet.require("actions");
235
+
236
+ if (this.action == "expand_abbreviation_with_tab") {
237
+ if (!editor.selection.isEmpty())
238
+ return false;
239
+ }
240
+
241
+ if (this.action == "wrap_with_abbreviation") {
242
+ return setTimeout(function() {
243
+ actions.run("wrap_with_abbreviation", editorProxy);
244
+ }, 0);
245
+ }
246
+
247
+ try {
248
+ var result = actions.run(this.action, editorProxy);
249
+ } catch(e) {
250
+ editor._signal("changeStatus", typeof e == "string" ? e : e.message);
251
+ console.log(e);
252
+ }
253
+ return result;
254
+ };
255
+
256
+ for (var command in keymap) {
257
+ exports.commands.addCommand({
258
+ name: "emmet:" + command,
259
+ action: command,
260
+ bindKey: keymap[command],
261
+ exec: exports.runEmmetCommand,
262
+ multiSelectAction: "forEach"
263
+ });
264
+ }
265
+
266
+ var onChangeMode = function(e, target) {
267
+ var editor = target;
268
+ if (!editor)
269
+ return;
270
+ var modeId = editor.session.$modeId;
271
+ var enabled = modeId && /css|less|scss|sass|stylus|html|php/.test(modeId);
272
+ if (e.enableEmmet === false)
273
+ enabled = false;
274
+ if (enabled)
275
+ editor.keyBinding.addKeyboardHandler(exports.commands);
276
+ else
277
+ editor.keyBinding.removeKeyboardHandler(exports.commands);
278
+ };
279
+
280
+
281
+ exports.AceEmmetEditor = AceEmmetEditor;
282
+ require("ace/config").defineOptions(Editor.prototype, "editor", {
283
+ enableEmmet: {
284
+ set: function(val) {
285
+ this[val ? "on" : "removeListener"]("changeMode", onChangeMode);
286
+ onChangeMode({enableEmmet: !!val}, this);
287
+ },
288
+ value: true
289
+ }
290
+ });
291
+
292
+
293
+ exports.setCore = function(e) {emmet = e;};
294
+ });
295
+
296
+ define('ace/snippets', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/range', 'ace/keyboard/hash_handler', 'ace/tokenizer', 'ace/lib/dom'], function(require, exports, module) {
297
+
298
+ var lang = require("./lib/lang")
299
+ var Range = require("./range").Range
300
+ var HashHandler = require("./keyboard/hash_handler").HashHandler;
301
+ var Tokenizer = require("./tokenizer").Tokenizer;
302
+ var comparePoints = Range.comparePoints;
303
+
304
+ var SnippetManager = function() {
305
+ this.snippetMap = {};
306
+ this.snippetNameMap = {};
307
+ };
308
+
309
+ (function() {
310
+ this.getTokenizer = function() {
311
+ function TabstopToken(str, _, stack) {
312
+ str = str.substr(1);
313
+ if (/^\d+$/.test(str) && !stack.inFormatString)
314
+ return [{tabstopId: parseInt(str, 10)}];
315
+ return [{text: str}]
316
+ }
317
+ function escape(ch) {
318
+ return "(?:[^\\\\" + ch + "]|\\\\.)";
319
+ }
320
+ SnippetManager.$tokenizer = new Tokenizer({
321
+ start: [
322
+ {regex: /:/, onMatch: function(val, state, stack) {
323
+ if (stack.length && stack[0].expectIf) {
324
+ stack[0].expectIf = false;
325
+ stack[0].elseBranch = stack[0];
326
+ return [stack[0]];
327
+ }
328
+ return ":";
329
+ }},
330
+ {regex: /\\./, onMatch: function(val, state, stack) {
331
+ var ch = val[1];
332
+ if (ch == "}" && stack.length) {
333
+ val = ch;
334
+ }else if ("`$\\".indexOf(ch) != -1) {
335
+ val = ch;
336
+ } else if (stack.inFormatString) {
337
+ if (ch == "n")
338
+ val = "\n";
339
+ else if (ch == "t")
340
+ val = "\n";
341
+ else if ("ulULE".indexOf(ch) != -1) {
342
+ val = {changeCase: ch, local: ch > "a"};
343
+ }
344
+ }
345
+
346
+ return [val];
347
+ }},
348
+ {regex: /}/, onMatch: function(val, state, stack) {
349
+ return [stack.length ? stack.shift() : val];
350
+ }},
351
+ {regex: /\$(?:\d+|\w+)/, onMatch: TabstopToken},
352
+ {regex: /\$\{[\dA-Z_a-z]+/, onMatch: function(str, state, stack) {
353
+ var t = TabstopToken(str.substr(1), state, stack);
354
+ stack.unshift(t[0]);
355
+ return t;
356
+ }, next: "snippetVar"},
357
+ {regex: /\n/, token: "newline", merge: false}
358
+ ],
359
+ snippetVar: [
360
+ {regex: "\\|" + escape("\\|") + "*\\|", onMatch: function(val, state, stack) {
361
+ stack[0].choices = val.slice(1, -1).split(",");
362
+ }, next: "start"},
363
+ {regex: "/(" + escape("/") + "+)/(?:(" + escape("/") + "*)/)(\\w*):?",
364
+ onMatch: function(val, state, stack) {
365
+ var ts = stack[0];
366
+ ts.fmtString = val;
367
+
368
+ val = this.splitRegex.exec(val);
369
+ ts.guard = val[1];
370
+ ts.fmt = val[2];
371
+ ts.flag = val[3];
372
+ return "";
373
+ }, next: "start"},
374
+ {regex: "`" + escape("`") + "*`", onMatch: function(val, state, stack) {
375
+ stack[0].code = val.splice(1, -1);
376
+ return "";
377
+ }, next: "start"},
378
+ {regex: "\\?", onMatch: function(val, state, stack) {
379
+ if (stack[0])
380
+ stack[0].expectIf = true;
381
+ }, next: "start"},
382
+ {regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "start"}
383
+ ],
384
+ formatString: [
385
+ {regex: "/(" + escape("/") + "+)/", token: "regex"},
386
+ {regex: "", onMatch: function(val, state, stack) {
387
+ stack.inFormatString = true;
388
+ }, next: "start"}
389
+ ]
390
+ });
391
+ SnippetManager.prototype.getTokenizer = function() {
392
+ return SnippetManager.$tokenizer;
393
+ }
394
+ return SnippetManager.$tokenizer;
395
+ };
396
+
397
+ this.tokenizeTmSnippet = function(str, startState) {
398
+ return this.getTokenizer().getLineTokens(str, startState).tokens.map(function(x) {
399
+ return x.value || x;
400
+ });
401
+ };
402
+
403
+ this.$getDefaultValue = function(editor, name) {
404
+ if (/^[A-Z]\d+$/.test(name)) {
405
+ var i = name.substr(1);
406
+ return (this.variables[name[0] + "__"] || {})[i];
407
+ }
408
+ if (/^\d+$/.test(name)) {
409
+ return (this.variables.__ || {})[name];
410
+ }
411
+ name = name.replace(/^TM_/, "");
412
+
413
+ if (!editor)
414
+ return;
415
+ var s = editor.session;
416
+ switch(name) {
417
+ case "CURRENT_WORD":
418
+ var r = s.getWordRange();
419
+ case "SELECTION":
420
+ case "SELECTED_TEXT":
421
+ return s.getTextRange(r);
422
+ case "CURRENT_LINE":
423
+ return s.getLine(editor.getCursorPosition().row);
424
+ case "PREV_LINE": // not possible in textmate
425
+ return s.getLine(editor.getCursorPosition().row - 1);
426
+ case "LINE_INDEX":
427
+ return editor.getCursorPosition().column;
428
+ case "LINE_NUMBER":
429
+ return editor.getCursorPosition().row + 1;
430
+ case "SOFT_TABS":
431
+ return s.getUseSoftTabs() ? "YES" : "NO";
432
+ case "TAB_SIZE":
433
+ return s.getTabSize();
434
+ case "FILENAME":
435
+ case "FILEPATH":
436
+ return "ace.ajax.org";
437
+ case "FULLNAME":
438
+ return "Ace";
439
+ }
440
+ };
441
+ this.variables = {};
442
+ this.getVariableValue = function(editor, varName) {
443
+ if (this.variables.hasOwnProperty(varName))
444
+ return this.variables[varName](editor, varName) || "";
445
+ return this.$getDefaultValue(editor, varName) || "";
446
+ };
447
+ this.tmStrFormat = function(str, ch, editor) {
448
+ var flag = ch.flag || "";
449
+ var re = ch.guard;
450
+ re = new RegExp(re, flag.replace(/[^gi]/, ""));
451
+ var fmtTokens = this.tokenizeTmSnippet(ch.fmt, "formatString");
452
+ var _self = this;
453
+ var formatted = str.replace(re, function() {
454
+ _self.variables.__ = arguments;
455
+ var fmtParts = _self.resolveVariables(fmtTokens, editor);
456
+ var gChangeCase = "E";
457
+ for (var i = 0; i < fmtParts.length; i++) {
458
+ var ch = fmtParts[i];
459
+ if (typeof ch == "object") {
460
+ fmtParts[i] = "";
461
+ if (ch.changeCase && ch.local) {
462
+ var next = fmtParts[i + 1];
463
+ if (next && typeof next == "string") {
464
+ if (ch.changeCase == "u")
465
+ fmtParts[i] = next[0].toUpperCase();
466
+ else
467
+ fmtParts[i] = next[0].toLowerCase();
468
+ fmtParts[i + 1] = next.substr(1);
469
+ }
470
+ } else if (ch.changeCase) {
471
+ gChangeCase = ch.changeCase;
472
+ }
473
+ } else if (gChangeCase == "U") {
474
+ fmtParts[i] = ch.toUpperCase();
475
+ } else if (gChangeCase == "L") {
476
+ fmtParts[i] = ch.toLowerCase();
477
+ }
478
+ }
479
+ return fmtParts.join("");
480
+ });
481
+ this.variables.__ = null;
482
+ return formatted;
483
+ };
484
+
485
+ this.resolveVariables = function(snippet, editor) {
486
+ var result = [];
487
+ for (var i = 0; i < snippet.length; i++) {
488
+ var ch = snippet[i];
489
+ if (typeof ch == "string") {
490
+ result.push(ch);
491
+ } else if (typeof ch != "object") {
492
+ continue;
493
+ } else if (ch.skip) {
494
+ gotoNext(ch);
495
+ } else if (ch.processed < i) {
496
+ continue;
497
+ } else if (ch.text) {
498
+ var value = this.getVariableValue(editor, ch.text);
499
+ if (value && ch.fmtString)
500
+ value = this.tmStrFormat(value, ch);
501
+ ch.processed = i;
502
+ if (ch.expectIf == null) {
503
+ if (value) {
504
+ result.push(value);
505
+ gotoNext(ch);
506
+ }
507
+ } else {
508
+ if (value) {
509
+ ch.skip = ch.elseBranch;
510
+ } else
511
+ gotoNext(ch);
512
+ }
513
+ } else if (ch.tabstopId != null) {
514
+ result.push(ch);
515
+ } else if (ch.changeCase != null) {
516
+ result.push(ch);
517
+ }
518
+ }
519
+ function gotoNext(ch) {
520
+ var i1 = snippet.indexOf(ch, i + 1);
521
+ if (i1 != -1)
522
+ i = i1;
523
+ }
524
+ return result;
525
+ };
526
+
527
+ this.insertSnippet = function(editor, snippetText) {
528
+ var cursor = editor.getCursorPosition();
529
+ var line = editor.session.getLine(cursor.row);
530
+ var indentString = line.match(/^\s*/)[0];
531
+ var tabString = editor.session.getTabString();
532
+
533
+ var tokens = this.tokenizeTmSnippet(snippetText);
534
+ tokens = this.resolveVariables(tokens, editor);
535
+ tokens = tokens.map(function(x) {
536
+ if (x == "\n")
537
+ return x + indentString;
538
+ if (typeof x == "string")
539
+ return x.replace(/\t/g, tabString);
540
+ return x;
541
+ });
542
+ var tabstops = [];
543
+ tokens.forEach(function(p, i) {
544
+ if (typeof p != "object")
545
+ return;
546
+ var id = p.tabstopId;
547
+ var ts = tabstops[id];
548
+ if (!ts) {
549
+ ts = tabstops[id] = [];
550
+ ts.index = id;
551
+ ts.value = "";
552
+ }
553
+ if (ts.indexOf(p) !== -1)
554
+ return;
555
+ ts.push(p);
556
+ var i1 = tokens.indexOf(p, i + 1);
557
+ if (i1 === -1)
558
+ return;
559
+
560
+ var value = tokens.slice(i + 1, i1);
561
+ var isNested = value.some(function(t) {return typeof t === "object"});
562
+ if (isNested && !ts.value) {
563
+ ts.value = value;
564
+ } else if (value.length && (!ts.value || typeof ts.value !== "string")) {
565
+ ts.value = value.join("");
566
+ }
567
+ });
568
+ tabstops.forEach(function(ts) {ts.length = 0});
569
+ var expanding = {};
570
+ function copyValue(val) {
571
+ var copy = []
572
+ for (var i = 0; i < val.length; i++) {
573
+ var p = val[i];
574
+ if (typeof p == "object") {
575
+ if (expanding[p.tabstopId])
576
+ continue;
577
+ var j = val.lastIndexOf(p, i - 1);
578
+ p = copy[j] || {tabstopId: p.tabstopId};
579
+ }
580
+ copy[i] = p;
581
+ }
582
+ return copy;
583
+ }
584
+ for (var i = 0; i < tokens.length; i++) {
585
+ var p = tokens[i];
586
+ if (typeof p != "object")
587
+ continue;
588
+ var id = p.tabstopId;
589
+ var i1 = tokens.indexOf(p, i + 1);
590
+ if (expanding[id] == p) {
591
+ expanding[id] = null;
592
+ continue;
593
+ }
594
+
595
+ var ts = tabstops[id];
596
+ var arg = typeof ts.value == "string" ? [ts.value] : copyValue(ts.value);
597
+ arg.unshift(i + 1, Math.max(0, i1 - i));
598
+ arg.push(p);
599
+ expanding[id] = p;
600
+ tokens.splice.apply(tokens, arg);
601
+
602
+ if (ts.indexOf(p) === -1)
603
+ ts.push(p);
604
+ };
605
+ var row = 0, column = 0;
606
+ var text = "";
607
+ tokens.forEach(function(t) {
608
+ if (typeof t === "string") {
609
+ if (t[0] === "\n"){
610
+ column = t.length - 1;
611
+ row ++;
612
+ } else
613
+ column += t.length;
614
+ text += t;
615
+ } else {
616
+ if (!t.start)
617
+ t.start = {row: row, column: column};
618
+ else
619
+ t.end = {row: row, column: column};
620
+ }
621
+ });
622
+ var range = editor.getSelectionRange();
623
+ var end = editor.session.replace(range, text);
624
+
625
+ var tabstopManager = new TabstopManager(editor);
626
+ tabstopManager.addTabstops(tabstops, range.start, end);
627
+ tabstopManager.tabNext();
628
+ };
629
+
630
+ this.$getScope = function(editor) {
631
+ var scope = editor.session.$mode.$id || "";
632
+ scope = scope.split("/").pop();
633
+ if (scope === "html" || scope === "php") {
634
+ if (scope === "php")
635
+ scope = "html";
636
+ var c = editor.getCursorPosition()
637
+ var state = editor.session.getState(c.row);
638
+ if (typeof state === "object") {
639
+ state = state[0];
640
+ }
641
+ if (state.substring) {
642
+ if (state.substring(0, 3) == "js-")
643
+ scope = "javascript";
644
+ else if (state.substring(0, 4) == "css-")
645
+ scope = "css";
646
+ else if (state.substring(0, 4) == "php-")
647
+ scope = "php";
648
+ }
649
+ }
650
+
651
+ return scope;
652
+ };
653
+
654
+ this.getActiveScopes = function(editor) {
655
+ var scope = this.$getScope(editor);
656
+ var scopes = [scope];
657
+ var snippetMap = this.snippetMap;
658
+ if (snippetMap[scope] && snippetMap[scope].includeScopes) {
659
+ scopes.push.apply(scopes, snippetMap[scope].includeScopes);
660
+ }
661
+ scopes.push("_");
662
+ return scopes;
663
+ };
664
+
665
+ this.expandWithTab = function(editor) {
666
+ var cursor = editor.getCursorPosition();
667
+ var line = editor.session.getLine(cursor.row);
668
+ var before = line.substring(0, cursor.column);
669
+ var after = line.substr(cursor.column);
670
+
671
+ var snippetMap = this.snippetMap;
672
+ var snippet;
673
+ this.getActiveScopes(editor).some(function(scope) {
674
+ var snippets = snippetMap[scope];
675
+ if (snippets)
676
+ snippet = this.findMatchingSnippet(snippets, before, after);
677
+ return !!snippet;
678
+ }, this);
679
+ if (!snippet)
680
+ return false;
681
+
682
+ editor.session.doc.removeInLine(cursor.row,
683
+ cursor.column - snippet.replaceBefore.length,
684
+ cursor.column + snippet.replaceAfter.length
685
+ );
686
+
687
+ this.variables.M__ = snippet.matchBefore;
688
+ this.variables.T__ = snippet.matchAfter;
689
+ this.insertSnippet(editor, snippet.content);
690
+
691
+ this.variables.M__ = this.variables.T__ = null;
692
+ return true;
693
+ };
694
+
695
+ this.findMatchingSnippet = function(snippetList, before, after) {
696
+ for (var i = snippetList.length; i--;) {
697
+ var s = snippetList[i];
698
+ if (s.startRe && !s.startRe.test(before))
699
+ continue;
700
+ if (s.endRe && !s.endRe.test(after))
701
+ continue;
702
+ if (!s.startRe && !s.endRe)
703
+ continue;
704
+
705
+ s.matchBefore = s.startRe ? s.startRe.exec(before) : [""];
706
+ s.matchAfter = s.endRe ? s.endRe.exec(after) : [""];
707
+ s.replaceBefore = s.triggerRe ? s.triggerRe.exec(before)[0] : "";
708
+ s.replaceAfter = s.endTriggerRe ? s.endTriggerRe.exec(after)[0] : "";
709
+ return s;
710
+ }
711
+ };
712
+
713
+ this.snippetMap = {};
714
+ this.snippetNameMap = {};
715
+ this.register = function(snippets, scope) {
716
+ var snippetMap = this.snippetMap;
717
+ var snippetNameMap = this.snippetNameMap;
718
+ var self = this;
719
+ function wrapRegexp(src) {
720
+ if (src && !/^\^?\(.*\)\$?$|^\\b$/.test(src))
721
+ src = "(?:" + src + ")"
722
+
723
+ return src || "";
724
+ }
725
+ function guardedRegexp(re, guard, opening) {
726
+ re = wrapRegexp(re);
727
+ guard = wrapRegexp(guard);
728
+ if (opening) {
729
+ re = guard + re;
730
+ if (re && re[re.length - 1] != "$")
731
+ re = re + "$";
732
+ } else {
733
+ re = re + guard;
734
+ if (re && re[0] != "^")
735
+ re = "^" + re;
736
+ }
737
+ return new RegExp(re);
738
+ }
739
+
740
+ function addSnippet(s) {
741
+ if (!s.scope)
742
+ s.scope = scope || "_";
743
+ scope = s.scope
744
+ if (!snippetMap[scope]) {
745
+ snippetMap[scope] = [];
746
+ snippetNameMap[scope] = {};
747
+ }
748
+
749
+ var map = snippetNameMap[scope];
750
+ if (s.name) {
751
+ var old = map[s.name];
752
+ if (old)
753
+ self.unregister(old);
754
+ map[s.name] = s;
755
+ }
756
+ snippetMap[scope].push(s);
757
+
758
+ if (s.tabTrigger && !s.trigger) {
759
+ if (!s.guard && /^\w/.test(s.tabTrigger))
760
+ s.guard = "\\b";
761
+ s.trigger = lang.escapeRegExp(s.tabTrigger);
762
+ }
763
+
764
+ s.startRe = guardedRegexp(s.trigger, s.guard, true);
765
+ s.triggerRe = new RegExp(s.trigger, "", true);
766
+
767
+ s.endRe = guardedRegexp(s.endTrigger, s.endGuard, true);
768
+ s.endTriggerRe = new RegExp(s.endTrigger, "", true);
769
+ };
770
+
771
+ if (snippets.content)
772
+ addSnippet(snippets);
773
+ else if (Array.isArray(snippets))
774
+ snippets.forEach(addSnippet);
775
+ };
776
+ this.unregister = function(snippets, scope) {
777
+ var snippetMap = this.snippetMap;
778
+ var snippetNameMap = this.snippetNameMap;
779
+
780
+ function removeSnippet(s) {
781
+ var nameMap = snippetNameMap[s.scope||scope];
782
+ if (nameMap && nameMap[s.name]) {
783
+ delete nameMap[s.name];
784
+ var map = snippetMap[s.scope||scope];
785
+ var i = map && map.indexOf(s);
786
+ if (i >= 0)
787
+ map.splice(i, 1);
788
+ }
789
+ }
790
+ if (snippets.content)
791
+ removeSnippet(snippets);
792
+ else if (Array.isArray(snippets))
793
+ snippets.forEach(removeSnippet);
794
+ };
795
+ this.parseSnippetFile = function(str) {
796
+ str = str.replace(/\r/g, "");
797
+ var list = [], snippet = {};
798
+ var re = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm;
799
+ var m;
800
+ while (m = re.exec(str)) {
801
+ if (m[1]) {
802
+ try {
803
+ snippet = JSON.parse(m[1])
804
+ list.push(snippet);
805
+ } catch (e) {}
806
+ } if (m[4]) {
807
+ snippet.content = m[4].replace(/^\t/gm, "");
808
+ list.push(snippet);
809
+ snippet = {};
810
+ } else {
811
+ var key = m[2], val = m[3];
812
+ if (key == "regex") {
813
+ var guardRe = /\/((?:[^\/\\]|\\.)*)|$/g;
814
+ snippet.guard = guardRe.exec(val)[1];
815
+ snippet.trigger = guardRe.exec(val)[1];
816
+ snippet.endTrigger = guardRe.exec(val)[1];
817
+ snippet.endGuard = guardRe.exec(val)[1];
818
+ } else if (key == "snippet") {
819
+ snippet.tabTrigger = val.match(/^\S*/)[0];
820
+ if (!snippet.name)
821
+ snippet.name = val;
822
+ } else {
823
+ snippet[key] = val;
824
+ }
825
+ }
826
+ }
827
+ return list;
828
+ };
829
+ this.getSnippetByName = function(name, editor) {
830
+ var snippetMap = this.snippetNameMap;
831
+ var snippet;
832
+ this.getActiveScopes(editor).some(function(scope) {
833
+ var snippets = snippetMap[scope];
834
+ if (snippets)
835
+ snippet = snippets[name];
836
+ return !!snippet;
837
+ }, this);
838
+ return snippet;
839
+ };
840
+
841
+ }).call(SnippetManager.prototype);
842
+
843
+
844
+ var TabstopManager = function(editor) {
845
+ if (editor.tabstopManager)
846
+ return editor.tabstopManager;
847
+ editor.tabstopManager = this;
848
+ this.$onChange = this.onChange.bind(this);
849
+ this.$onChangeSelection = lang.delayedCall(this.onChangeSelection.bind(this)).schedule;
850
+ this.$onChangeSession = this.onChangeSession.bind(this);
851
+ this.$onAfterExec = this.onAfterExec.bind(this);
852
+ this.attach(editor);
853
+ };
854
+ (function() {
855
+ this.attach = function(editor) {
856
+ this.index = -1;
857
+ this.ranges = [];
858
+ this.tabstops = [];
859
+ this.selectedTabstop = null;
860
+
861
+ this.editor = editor;
862
+ this.editor.on("change", this.$onChange);
863
+ this.editor.on("changeSelection", this.$onChangeSelection);
864
+ this.editor.on("changeSession", this.$onChangeSession);
865
+ this.editor.commands.on("afterExec", this.$onAfterExec);
866
+ this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
867
+ };
868
+ this.detach = function() {
869
+ this.tabstops.forEach(this.removeTabstopMarkers, this);
870
+ this.ranges = null;
871
+ this.tabstops = null;
872
+ this.selectedTabstop = null;
873
+ this.editor.removeListener("change", this.$onChange);
874
+ this.editor.removeListener("changeSelection", this.$onChangeSelection);
875
+ this.editor.removeListener("changeSession", this.$onChangeSession);
876
+ this.editor.commands.removeListener("afterExec", this.$onAfterExec);
877
+ this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
878
+ this.editor.tabstopManager = null;
879
+ this.editor = null;
880
+ };
881
+
882
+ this.onChange = function(e) {
883
+ var changeRange = e.data.range;
884
+ var isRemove = e.data.action[0] == "r";
885
+ var start = changeRange.start;
886
+ var end = changeRange.end;
887
+ var startRow = start.row;
888
+ var endRow = end.row;
889
+ var lineDif = endRow - startRow;
890
+ var colDiff = end.column - start.column;
891
+
892
+ if (isRemove) {
893
+ lineDif = -lineDif;
894
+ colDiff = -colDiff;
895
+ }
896
+ if (!this.$inChange && isRemove) {
897
+ var ts = this.selectedTabstop;
898
+ var changedOutside = !ts.some(function(r) {
899
+ return comparePoints(r.start, start) <= 0 && comparePoints(r.end, end) >= 0;
900
+ });
901
+ if (changedOutside)
902
+ return this.detach();
903
+ }
904
+ var ranges = this.ranges;
905
+ for (var i = 0; i < ranges.length; i++) {
906
+ var r = ranges[i];
907
+ if (r.end.row < start.row)
908
+ continue;
909
+
910
+ if (comparePoints(start, r.start) < 0 && comparePoints(end, r.end) > 0) {
911
+ this.removeRange(r);
912
+ i--;
913
+ continue;
914
+ }
915
+
916
+ if (r.start.row == startRow && r.start.column > start.column)
917
+ r.start.column += colDiff;
918
+ if (r.end.row == startRow && r.end.column >= start.column)
919
+ r.end.column += colDiff;
920
+ if (r.start.row >= startRow)
921
+ r.start.row += lineDif;
922
+ if (r.end.row >= startRow)
923
+ r.end.row += lineDif;
924
+
925
+ if (comparePoints(r.start, r.end) > 0)
926
+ this.removeRange(r);
927
+ }
928
+ if (!ranges.length)
929
+ this.detach();
930
+ };
931
+ this.updateLinkedFields = function() {
932
+ var ts = this.selectedTabstop;
933
+ if (!ts.hasLinkedRanges)
934
+ return;
935
+ this.$inChange = true;
936
+ var session = this.editor.session;
937
+ var text = session.getTextRange(ts.firstNonLinked);
938
+ for (var i = ts.length; i--;) {
939
+ var range = ts[i];
940
+ if (!range.linked)
941
+ continue;
942
+ var fmt = exports.snippetManager.tmStrFormat(text, range.original)
943
+ session.replace(range, fmt);
944
+ }
945
+ this.$inChange = false;
946
+ };
947
+ this.onAfterExec = function(e) {
948
+ if (e.command && !e.command.readOnly)
949
+ this.updateLinkedFields();
950
+ };
951
+ this.onChangeSelection = function() {
952
+ if (!this.editor)
953
+ return
954
+ var lead = this.editor.selection.lead;
955
+ var anchor = this.editor.selection.anchor;
956
+ var isEmpty = this.editor.selection.isEmpty();
957
+ for (var i = this.ranges.length; i--;) {
958
+ if (this.ranges[i].linked)
959
+ continue;
960
+ var containsLead = this.ranges[i].contains(lead.row, lead.column);
961
+ var containsAnchor = isEmpty || this.ranges[i].contains(anchor.row, anchor.column);
962
+ if (containsLead && containsAnchor)
963
+ return;
964
+ }
965
+ this.detach();
966
+ };
967
+ this.onChangeSession = function() {
968
+ this.detach();
969
+ };
970
+ this.tabNext = function(dir) {
971
+ var max = this.tabstops.length - 1;
972
+ var index = this.index + (dir || 1);
973
+ index = Math.min(Math.max(index, 0), max);
974
+ this.selectTabstop(index);
975
+ if (index == max)
976
+ this.detach();
977
+ };
978
+ this.selectTabstop = function(index) {
979
+ var ts = this.tabstops[this.index];
980
+ if (ts)
981
+ this.addTabstopMarkers(ts);
982
+ this.index = index;
983
+ ts = this.tabstops[this.index];
984
+ if (!ts || !ts.length)
985
+ return;
986
+
987
+ this.selectedTabstop = ts;
988
+ if (!this.editor.inVirtualSelectionMode) {
989
+ var sel = this.editor.multiSelect;
990
+ sel.toSingleRange(ts.firstNonLinked.clone());
991
+ for (var i = ts.length; i--;) {
992
+ if (ts.hasLinkedRanges && ts[i].linked)
993
+ continue;
994
+ sel.addRange(ts[i].clone(), true);
995
+ }
996
+ } else {
997
+ this.editor.selection.setRange(ts.firstNonLinked);
998
+ }
999
+
1000
+ this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
1001
+ };
1002
+ this.addTabstops = function(tabstops, start, end) {
1003
+ if (!tabstops[0]) {
1004
+ var p = Range.fromPoints(end, end);
1005
+ moveRelative(p.start, start);
1006
+ moveRelative(p.end, start);
1007
+ tabstops[0] = [p];
1008
+ tabstops[0].index = 0;
1009
+ }
1010
+
1011
+ var i = this.index;
1012
+ var arg = [i, 0];
1013
+ var ranges = this.ranges;
1014
+ var editor = this.editor;
1015
+ tabstops.forEach(function(ts) {
1016
+ for (var i = ts.length; i--;) {
1017
+ var p = ts[i];
1018
+ var range = Range.fromPoints(p.start, p.end || p.start);
1019
+ movePoint(range.start, start);
1020
+ movePoint(range.end, start);
1021
+ range.original = p;
1022
+ range.tabstop = ts;
1023
+ ranges.push(range);
1024
+ ts[i] = range;
1025
+ if (p.fmtString) {
1026
+ range.linked = true;
1027
+ ts.hasLinkedRanges = true;
1028
+ } else if (!ts.firstNonLinked)
1029
+ ts.firstNonLinked = range;
1030
+ }
1031
+ if (!ts.firstNonLinked)
1032
+ ts.hasLinkedRanges = false;
1033
+ arg.push(ts);
1034
+ this.addTabstopMarkers(ts);
1035
+ }, this);
1036
+ arg.push(arg.splice(2, 1)[0]);
1037
+ this.tabstops.splice.apply(this.tabstops, arg);
1038
+ };
1039
+
1040
+ this.addTabstopMarkers = function(ts) {
1041
+ var session = this.editor.session;
1042
+ ts.forEach(function(range) {
1043
+ if (!range.markerId)
1044
+ range.markerId = session.addMarker(range, "ace_snippet-marker", "text");
1045
+ });
1046
+ };
1047
+ this.removeTabstopMarkers = function(ts) {
1048
+ var session = this.editor.session;
1049
+ ts.forEach(function(range) {
1050
+ session.removeMarker(range.markerId);
1051
+ range.markerId = null;
1052
+ });
1053
+ };
1054
+ this.removeRange = function(range) {
1055
+ var i = range.tabstop.indexOf(range);
1056
+ range.tabstop.splice(i, 1);
1057
+ i = this.ranges.indexOf(range);
1058
+ this.ranges.splice(i, 1);
1059
+ this.editor.session.removeMarker(range.markerId);
1060
+ };
1061
+
1062
+ this.keyboardHandler = new HashHandler();
1063
+ this.keyboardHandler.bindKeys({
1064
+ "Tab": function(ed) {
1065
+ if (exports.snippetManager && exports.snippetManager.expandWithTab(ed)) {
1066
+ return;
1067
+ }
1068
+
1069
+ ed.tabstopManager.tabNext(1);
1070
+ },
1071
+ "Shift-Tab": function(ed) {
1072
+ ed.tabstopManager.tabNext(-1);
1073
+ },
1074
+ "Esc": function(ed) {
1075
+ ed.tabstopManager.detach();
1076
+ },
1077
+ "Return": function(ed) {
1078
+ return false;
1079
+ }
1080
+ });
1081
+ }).call(TabstopManager.prototype);
1082
+
1083
+
1084
+ var movePoint = function(point, diff) {
1085
+ if (point.row == 0)
1086
+ point.column += diff.column;
1087
+ point.row += diff.row;
1088
+ };
1089
+
1090
+ var moveRelative = function(point, start) {
1091
+ if (point.row == start.row)
1092
+ point.column -= start.column;
1093
+ point.row -= start.row;
1094
+ };
1095
+
1096
+
1097
+ require("./lib/dom").importCssString("\
1098
+ .ace_snippet-marker {\
1099
+ -moz-box-sizing: border-box;\
1100
+ box-sizing: border-box;\
1101
+ background: rgba(194, 193, 208, 0.09);\
1102
+ border: 1px dotted rgba(211, 208, 235, 0.62);\
1103
+ position: absolute;\
1104
+ }");
1105
+
1106
+ exports.snippetManager = new SnippetManager();
1107
+
1108
+
1109
+ });