ace-rails-ap 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ace/rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/ace/ace.js +210 -161
  4. data/vendor/assets/javascripts/ace/ext-beautify.js +0 -1
  5. data/vendor/assets/javascripts/ace/ext-chromevox.js +0 -1
  6. data/vendor/assets/javascripts/ace/ext-elastic_tabstops_lite.js +0 -1
  7. data/vendor/assets/javascripts/ace/ext-emmet.js +66 -48
  8. data/vendor/assets/javascripts/ace/ext-keybinding_menu.js +9 -19
  9. data/vendor/assets/javascripts/ace/ext-language_tools.js +108 -10
  10. data/vendor/assets/javascripts/ace/ext-linking.js +0 -1
  11. data/vendor/assets/javascripts/ace/ext-modelist.js +4 -1
  12. data/vendor/assets/javascripts/ace/ext-old_ie.js +23 -2
  13. data/vendor/assets/javascripts/ace/ext-searchbox.js +23 -2
  14. data/vendor/assets/javascripts/ace/ext-settings_menu.js +10 -1
  15. data/vendor/assets/javascripts/ace/ext-spellcheck.js +0 -1
  16. data/vendor/assets/javascripts/ace/ext-split.js +0 -1
  17. data/vendor/assets/javascripts/ace/ext-static_highlight.js +0 -1
  18. data/vendor/assets/javascripts/ace/ext-statusbar.js +2 -4
  19. data/vendor/assets/javascripts/ace/ext-textarea.js +0 -1
  20. data/vendor/assets/javascripts/ace/ext-themelist.js +0 -1
  21. data/vendor/assets/javascripts/ace/ext-whitespace.js +0 -1
  22. data/vendor/assets/javascripts/ace/keybinding-emacs.js +159 -50
  23. data/vendor/assets/javascripts/ace/mode-autohotkey.js +1 -1
  24. data/vendor/assets/javascripts/ace/mode-c_cpp.js +32 -14
  25. data/vendor/assets/javascripts/ace/mode-coffee.js +1 -1
  26. data/vendor/assets/javascripts/ace/mode-coldfusion.js +62 -24
  27. data/vendor/assets/javascripts/ace/mode-csharp.js +14 -8
  28. data/vendor/assets/javascripts/ace/mode-css.js +2 -2
  29. data/vendor/assets/javascripts/ace/mode-curly.js +62 -24
  30. data/vendor/assets/javascripts/ace/mode-d.js +13 -7
  31. data/vendor/assets/javascripts/ace/mode-dart.js +32 -14
  32. data/vendor/assets/javascripts/ace/mode-django.js +62 -24
  33. data/vendor/assets/javascripts/ace/mode-dockerfile.js +3 -3
  34. data/vendor/assets/javascripts/ace/mode-dot.js +12 -6
  35. data/vendor/assets/javascripts/ace/mode-ejs.js +126 -27
  36. data/vendor/assets/javascripts/ace/mode-elixir.js +493 -0
  37. data/vendor/assets/javascripts/ace/mode-elm.js +248 -0
  38. data/vendor/assets/javascripts/ace/mode-forth.js +1 -1
  39. data/vendor/assets/javascripts/ace/mode-ftl.js +20 -10
  40. data/vendor/assets/javascripts/ace/mode-gitignore.js +1 -0
  41. data/vendor/assets/javascripts/ace/mode-glsl.js +32 -14
  42. data/vendor/assets/javascripts/ace/mode-golang.js +14 -8
  43. data/vendor/assets/javascripts/ace/mode-groovy.js +22 -12
  44. data/vendor/assets/javascripts/ace/mode-haml.js +64 -3
  45. data/vendor/assets/javascripts/ace/mode-handlebars.js +72 -34
  46. data/vendor/assets/javascripts/ace/mode-haxe.js +14 -8
  47. data/vendor/assets/javascripts/ace/mode-html.js +62 -24
  48. data/vendor/assets/javascripts/ace/mode-html_ruby.js +126 -27
  49. data/vendor/assets/javascripts/ace/mode-jack.js +2 -2
  50. data/vendor/assets/javascripts/ace/mode-jade.js +21 -11
  51. data/vendor/assets/javascripts/ace/mode-java.js +22 -12
  52. data/vendor/assets/javascripts/ace/mode-javascript.js +22 -12
  53. data/vendor/assets/javascripts/ace/mode-json.js +2 -2
  54. data/vendor/assets/javascripts/ace/mode-jsoniq.js +47 -1835
  55. data/vendor/assets/javascripts/ace/mode-jsp.js +22 -12
  56. data/vendor/assets/javascripts/ace/mode-jsx.js +14 -8
  57. data/vendor/assets/javascripts/ace/mode-less.js +2 -2
  58. data/vendor/assets/javascripts/ace/mode-liquid.js +20 -10
  59. data/vendor/assets/javascripts/ace/mode-logiql.js +2 -2
  60. data/vendor/assets/javascripts/ace/mode-lsl.js +2 -2
  61. data/vendor/assets/javascripts/ace/mode-luapage.js +62 -24
  62. data/vendor/assets/javascripts/ace/mode-markdown.js +62 -24
  63. data/vendor/assets/javascripts/ace/mode-mel.js +2 -2
  64. data/vendor/assets/javascripts/ace/mode-mysql.js +12 -6
  65. data/vendor/assets/javascripts/ace/mode-nix.js +32 -14
  66. data/vendor/assets/javascripts/ace/mode-objectivec.js +30 -12
  67. data/vendor/assets/javascripts/ace/mode-pgsql.js +20 -10
  68. data/vendor/assets/javascripts/ace/mode-php.js +1126 -40
  69. data/vendor/assets/javascripts/ace/mode-powershell.js +2 -2
  70. data/vendor/assets/javascripts/ace/mode-protobuf.js +32 -14
  71. data/vendor/assets/javascripts/ace/mode-rhtml.js +62 -24
  72. data/vendor/assets/javascripts/ace/mode-ruby.js +66 -5
  73. data/vendor/assets/javascripts/ace/mode-rust.js +36 -3
  74. data/vendor/assets/javascripts/ace/mode-scad.js +14 -8
  75. data/vendor/assets/javascripts/ace/mode-scala.js +22 -12
  76. data/vendor/assets/javascripts/ace/mode-scss.js +2 -2
  77. data/vendor/assets/javascripts/ace/mode-sh.js +2 -2
  78. data/vendor/assets/javascripts/ace/mode-sjs.js +22 -12
  79. data/vendor/assets/javascripts/ace/mode-smarty.js +62 -24
  80. data/vendor/assets/javascripts/ace/mode-soy_template.js +63 -25
  81. data/vendor/assets/javascripts/ace/mode-stylus.js +4 -1
  82. data/vendor/assets/javascripts/ace/mode-svg.js +62 -24
  83. data/vendor/assets/javascripts/ace/mode-textile.js +1 -0
  84. data/vendor/assets/javascripts/ace/mode-twig.js +62 -24
  85. data/vendor/assets/javascripts/ace/mode-typescript.js +22 -12
  86. data/vendor/assets/javascripts/ace/mode-vala.js +2 -2
  87. data/vendor/assets/javascripts/ace/mode-velocity.js +62 -24
  88. data/vendor/assets/javascripts/ace/mode-xml.js +40 -12
  89. data/vendor/assets/javascripts/ace/mode-xquery.js +47 -1835
  90. data/vendor/assets/javascripts/ace/theme-cobalt.js +1 -1
  91. data/vendor/assets/javascripts/ace/theme-idle_fingers.js +1 -1
  92. data/vendor/assets/javascripts/ace/theme-tomorrow_night_bright.js +2 -2
  93. data/vendor/assets/javascripts/ace/worker-coffee.js +15 -5
  94. data/vendor/assets/javascripts/ace/worker-css.js +15 -5
  95. data/vendor/assets/javascripts/ace/worker-html.js +15 -5
  96. data/vendor/assets/javascripts/ace/worker-javascript.js +15 -5
  97. data/vendor/assets/javascripts/ace/worker-json.js +17 -6
  98. data/vendor/assets/javascripts/ace/worker-lua.js +15 -5
  99. data/vendor/assets/javascripts/ace/worker-php.js +15 -5
  100. data/vendor/assets/javascripts/ace/worker-xquery.js +15 -5
  101. metadata +4 -2
@@ -46,7 +46,6 @@ function onClick(e) {
46
46
  }
47
47
 
48
48
  });
49
- ;
50
49
  (function() {
51
50
  window.require(["ace/ext/linking"], function() {});
52
51
  })();
@@ -57,8 +57,12 @@ var supportedModes = {
57
57
  Diff: ["diff|patch"],
58
58
  Dockerfile: ["^Dockerfile"],
59
59
  Dot: ["dot"],
60
+ Dummy: ["dummy"],
61
+ DummySyntax: ["dummy"],
60
62
  Eiffel: ["e"],
61
63
  EJS: ["ejs"],
64
+ Elixir: ["ex|exs"],
65
+ Elm: ["elm"],
62
66
  Erlang: ["erl|hrl"],
63
67
  Forth: ["frt|fs|ldr"],
64
68
  FTL: ["ftl"],
@@ -176,7 +180,6 @@ module.exports = {
176
180
  };
177
181
 
178
182
  });
179
- ;
180
183
  (function() {
181
184
  window.require(["ace/ext/modelist"], function() {});
182
185
  })();
@@ -9,7 +9,7 @@ var searchboxCss = "\
9
9
  background-color: #ddd;\
10
10
  border: 1px solid #cbcbcb;\
11
11
  border-top: 0 none;\
12
- max-width: 297px;\
12
+ max-width: 325px;\
13
13
  overflow: hidden;\
14
14
  margin: 0;\
15
15
  padding: 4px;\
@@ -158,6 +158,7 @@ var html = '<div class="ace_search right">\
158
158
  <input class="ace_search_field" placeholder="Search for" spellcheck="false"></input>\
159
159
  <button type="button" action="findNext" class="ace_searchbtn next"></button>\
160
160
  <button type="button" action="findPrev" class="ace_searchbtn prev"></button>\
161
+ <button type="button" action="findAll" class="ace_searchbtn" title="Alt-Enter">All</button>\
161
162
  </div>\
162
163
  <div class="ace_replace_form">\
163
164
  <input class="ace_search_field" placeholder="Replace with" spellcheck="false"></input>\
@@ -278,6 +279,11 @@ var SearchBox = function(editor, range, showReplaceForm) {
278
279
  sb.replace();
279
280
  sb.findPrev();
280
281
  },
282
+ "Alt-Return": function(sb) {
283
+ if (sb.activeInput == sb.replaceInput)
284
+ sb.replaceAll();
285
+ sb.findAll();
286
+ },
281
287
  "Tab": function(sb) {
282
288
  (sb.activeInput == sb.replaceInput ? sb.searchInput : sb.replaceInput).focus();
283
289
  }
@@ -337,6 +343,18 @@ var SearchBox = function(editor, range, showReplaceForm) {
337
343
  this.findPrev = function() {
338
344
  this.find(true, true);
339
345
  };
346
+ this.findAll = function(){
347
+ var range = this.editor.findAll(this.searchInput.value, {
348
+ regExp: this.regExpOption.checked,
349
+ caseSensitive: this.caseSensitiveOption.checked,
350
+ wholeWord: this.wholeWordOption.checked
351
+ });
352
+ var noMatch = !range && this.searchInput.value;
353
+ dom.setCssClass(this.searchBox, "ace_nomatch", noMatch);
354
+ this.editor._emit("findSearchBox", { match: !noMatch });
355
+ this.highlight();
356
+ this.hide();
357
+ };
340
358
  this.replace = function() {
341
359
  if (!this.editor.getReadOnly())
342
360
  this.editor.replace(this.replaceInput.value);
@@ -371,6 +389,10 @@ var SearchBox = function(editor, range, showReplaceForm) {
371
389
  this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb);
372
390
  };
373
391
 
392
+ this.isFocused = function() {
393
+ var el = document.activeElement;
394
+ return el == this.searchInput || el == this.replaceInput;
395
+ }
374
396
  }).call(SearchBox.prototype);
375
397
 
376
398
  exports.SearchBox = SearchBox;
@@ -466,7 +488,6 @@ patch(
466
488
  useragent.isOldIE = true;
467
489
 
468
490
  });
469
- ;
470
491
  (function() {
471
492
  window.require(["ace/ext/old_ie"], function() {});
472
493
  })();
@@ -9,7 +9,7 @@ var searchboxCss = "\
9
9
  background-color: #ddd;\
10
10
  border: 1px solid #cbcbcb;\
11
11
  border-top: 0 none;\
12
- max-width: 297px;\
12
+ max-width: 325px;\
13
13
  overflow: hidden;\
14
14
  margin: 0;\
15
15
  padding: 4px;\
@@ -158,6 +158,7 @@ var html = '<div class="ace_search right">\
158
158
  <input class="ace_search_field" placeholder="Search for" spellcheck="false"></input>\
159
159
  <button type="button" action="findNext" class="ace_searchbtn next"></button>\
160
160
  <button type="button" action="findPrev" class="ace_searchbtn prev"></button>\
161
+ <button type="button" action="findAll" class="ace_searchbtn" title="Alt-Enter">All</button>\
161
162
  </div>\
162
163
  <div class="ace_replace_form">\
163
164
  <input class="ace_search_field" placeholder="Replace with" spellcheck="false"></input>\
@@ -278,6 +279,11 @@ var SearchBox = function(editor, range, showReplaceForm) {
278
279
  sb.replace();
279
280
  sb.findPrev();
280
281
  },
282
+ "Alt-Return": function(sb) {
283
+ if (sb.activeInput == sb.replaceInput)
284
+ sb.replaceAll();
285
+ sb.findAll();
286
+ },
281
287
  "Tab": function(sb) {
282
288
  (sb.activeInput == sb.replaceInput ? sb.searchInput : sb.replaceInput).focus();
283
289
  }
@@ -337,6 +343,18 @@ var SearchBox = function(editor, range, showReplaceForm) {
337
343
  this.findPrev = function() {
338
344
  this.find(true, true);
339
345
  };
346
+ this.findAll = function(){
347
+ var range = this.editor.findAll(this.searchInput.value, {
348
+ regExp: this.regExpOption.checked,
349
+ caseSensitive: this.caseSensitiveOption.checked,
350
+ wholeWord: this.wholeWordOption.checked
351
+ });
352
+ var noMatch = !range && this.searchInput.value;
353
+ dom.setCssClass(this.searchBox, "ace_nomatch", noMatch);
354
+ this.editor._emit("findSearchBox", { match: !noMatch });
355
+ this.highlight();
356
+ this.hide();
357
+ };
340
358
  this.replace = function() {
341
359
  if (!this.editor.getReadOnly())
342
360
  this.editor.replace(this.replaceInput.value);
@@ -371,6 +389,10 @@ var SearchBox = function(editor, range, showReplaceForm) {
371
389
  this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb);
372
390
  };
373
391
 
392
+ this.isFocused = function() {
393
+ var el = document.activeElement;
394
+ return el == this.searchInput || el == this.replaceInput;
395
+ }
374
396
  }).call(SearchBox.prototype);
375
397
 
376
398
  exports.SearchBox = SearchBox;
@@ -381,7 +403,6 @@ exports.Search = function(editor, isReplace) {
381
403
  };
382
404
 
383
405
  });
384
- ;
385
406
  (function() {
386
407
  window.require(["ace/ext/searchbox"], function() {});
387
408
  })();
@@ -113,8 +113,12 @@ var supportedModes = {
113
113
  Diff: ["diff|patch"],
114
114
  Dockerfile: ["^Dockerfile"],
115
115
  Dot: ["dot"],
116
+ Dummy: ["dummy"],
117
+ DummySyntax: ["dummy"],
116
118
  Eiffel: ["e"],
117
119
  EJS: ["ejs"],
120
+ Elixir: ["ex|exs"],
121
+ Elm: ["elm"],
118
122
  Erlang: ["erl|hrl"],
119
123
  Forth: ["frt|fs|ldr"],
120
124
  FTL: ["ftl"],
@@ -404,6 +408,12 @@ module.exports.generateSettingsMenu = function generateSettingsMenu (editor) {
404
408
  elements.forEach(function(element) {
405
409
  topmenu.appendChild(element);
406
410
  });
411
+
412
+ var el = topmenu.appendChild(document.createElement('div'));
413
+ var version = "1.1.7";
414
+ el.style.padding = "1em";
415
+ el.textContent = "Ace version " + version;
416
+
407
417
  return topmenu;
408
418
  }
409
419
  function createNewEntry(obj, clss, item, val) {
@@ -620,7 +630,6 @@ module.exports.init = function(editor) {
620
630
  };
621
631
  };
622
632
  });
623
- ;
624
633
  (function() {
625
634
  window.require(["ace/ext/settings_menu"], function() {});
626
635
  })();
@@ -65,7 +65,6 @@ require("../config").defineOptions(Editor.prototype, "editor", {
65
65
  });
66
66
 
67
67
  });
68
- ;
69
68
  (function() {
70
69
  window.require(["ace/ext/spellcheck"], function() {});
71
70
  })();
@@ -240,7 +240,6 @@ define("ace/ext/split",["require","exports","module","ace/split"], function(requ
240
240
  module.exports = require("../split");
241
241
 
242
242
  });
243
- ;
244
243
  (function() {
245
244
  window.require(["ace/ext/split"], function() {});
246
245
  })();
@@ -148,7 +148,6 @@ highlight.renderSync = function(input, mode, theme, lineStart, disableGutter) {
148
148
  module.exports = highlight;
149
149
  module.exports.highlight =highlight;
150
150
  });
151
- ;
152
151
  (function() {
153
152
  window.require(["ace/ext/static_highlight"], function() {});
154
153
  })();
@@ -27,9 +27,8 @@ var StatusBar = function(editor, parentNode) {
27
27
  str && status.push(str, separator || "|");
28
28
  }
29
29
 
30
- if (editor.$vimModeHandler)
31
- add(editor.$vimModeHandler.getStatusText());
32
- else if (editor.commands.recording)
30
+ add(editor.keyBinding.getStatusText(editor));
31
+ if (editor.commands.recording)
33
32
  add("REC");
34
33
 
35
34
  var c = editor.selection.lead;
@@ -46,7 +45,6 @@ var StatusBar = function(editor, parentNode) {
46
45
  exports.StatusBar = StatusBar;
47
46
 
48
47
  });
49
- ;
50
48
  (function() {
51
49
  window.require(["ace/ext/statusbar"], function() {});
52
50
  })();
@@ -626,7 +626,6 @@ exports.defaultOptions = {
626
626
  };
627
627
 
628
628
  });
629
- ;
630
629
  (function() {
631
630
  window.require(["ace/ext/textarea"], function() {});
632
631
  })();
@@ -52,7 +52,6 @@ exports.themes = themeData.map(function(data) {
52
52
  });
53
53
 
54
54
  });
55
- ;
56
55
  (function() {
57
56
  window.require(["ace/ext/themelist"], function() {});
58
57
  })();
@@ -175,7 +175,6 @@ exports.commands = [{
175
175
  }];
176
176
 
177
177
  });
178
- ;
179
178
  (function() {
180
179
  window.require(["ace/ext/whitespace"], function() {});
181
180
  })();
@@ -315,6 +315,28 @@ exports.iSearchCommands = [{
315
315
  exec: function(iSearch) { iSearch.$editor.execCommand('recenterTopBottom'); },
316
316
  readOnly: true,
317
317
  isIncrementalSearchCommand: true
318
+ }, {
319
+ name: 'selectAllMatches',
320
+ bindKey: 'Ctrl-space',
321
+ exec: function(iSearch) {
322
+ var ed = iSearch.$editor,
323
+ hl = ed.session.$isearchHighlight,
324
+ ranges = hl && hl.cache ? hl.cache
325
+ .reduce(function(ranges, ea) {
326
+ return ranges.concat(ea ? ea : []); }, []) : [];
327
+ iSearch.deactivate(false);
328
+ ranges.forEach(ed.selection.addRange.bind(ed.selection));
329
+ },
330
+ readOnly: true,
331
+ isIncrementalSearchCommand: true
332
+ }, {
333
+ name: 'searchAsRegExp',
334
+ bindKey: 'Alt-r',
335
+ exec: function(iSearch) {
336
+ iSearch.convertNeedleToRegExp();
337
+ },
338
+ readOnly: true,
339
+ isIncrementalSearchCommand: true
318
340
  }];
319
341
 
320
342
  function IncrementalSearchKeyboardHandler(iSearch) {
@@ -378,6 +400,30 @@ function IncrementalSearch() {
378
400
 
379
401
  oop.inherits(IncrementalSearch, Search);
380
402
 
403
+ function isRegExp(obj) {
404
+ return obj instanceof RegExp;
405
+ }
406
+
407
+ function regExpToObject(re) {
408
+ var string = String(re),
409
+ start = string.indexOf('/'),
410
+ flagStart = string.lastIndexOf('/');
411
+ return {
412
+ expression: string.slice(start+1, flagStart),
413
+ flags: string.slice(flagStart+1)
414
+ }
415
+ }
416
+
417
+ function stringToRegExp(string, flags) {
418
+ try {
419
+ return new RegExp(string, flags);
420
+ } catch (e) { return string; }
421
+ }
422
+
423
+ function objectToRegExp(obj) {
424
+ return stringToRegExp(obj.expression, obj.flags);
425
+ }
426
+
381
427
  ;(function() {
382
428
 
383
429
  this.activate = function(ed, backwards) {
@@ -444,10 +490,12 @@ oop.inherits(IncrementalSearch, Search);
444
490
  };
445
491
  options.start = this.$currentPos;
446
492
  var session = this.$editor.session,
447
- found = this.find(session);
493
+ found = this.find(session),
494
+ shouldSelect = this.$editor.emacsMark ?
495
+ !!this.$editor.emacsMark() : !this.$editor.selection.isEmpty();
448
496
  if (found) {
449
497
  if (options.backwards) found = Range.fromPoints(found.end, found.start);
450
- this.$editor.moveCursorToPosition(found.end);
498
+ this.$editor.selection.setRange(Range.fromPoints(shouldSelect ? this.$startPos : found.end, found.end));
451
499
  if (moveToNext) this.$currentPos = found.end;
452
500
  this.highlight(options.re)
453
501
  }
@@ -459,13 +507,21 @@ oop.inherits(IncrementalSearch, Search);
459
507
 
460
508
  this.addString = function(s) {
461
509
  return this.highlightAndFindWithNeedle(false, function(needle) {
462
- return needle + s;
510
+ if (!isRegExp(needle))
511
+ return needle + s;
512
+ var reObj = regExpToObject(needle);
513
+ reObj.expression += s;
514
+ return objectToRegExp(reObj);
463
515
  });
464
516
  }
465
517
 
466
518
  this.removeChar = function(c) {
467
519
  return this.highlightAndFindWithNeedle(false, function(needle) {
468
- return needle.length > 0 ? needle.substring(0, needle.length-1) : needle;
520
+ if (!isRegExp(needle))
521
+ return needle.substring(0, needle.length-1);
522
+ var reObj = regExpToObject(needle);
523
+ reObj.expression = reObj.expression.substring(0, reObj.expression.length-1);
524
+ return objectToRegExp(reObj);
469
525
  });
470
526
  }
471
527
 
@@ -488,6 +544,18 @@ oop.inherits(IncrementalSearch, Search);
488
544
  this.addString(text);
489
545
  }
490
546
 
547
+ this.convertNeedleToRegExp = function() {
548
+ return this.highlightAndFindWithNeedle(false, function(needle) {
549
+ return isRegExp(needle) ? needle : stringToRegExp(needle, 'ig');
550
+ });
551
+ }
552
+
553
+ this.convertNeedleToString = function() {
554
+ return this.highlightAndFindWithNeedle(false, function(needle) {
555
+ return isRegExp(needle) ? regExpToObject(needle).expression : needle;
556
+ });
557
+ }
558
+
491
559
  this.statusMessage = function(found) {
492
560
  var options = this.$options, msg = '';
493
561
  msg += options.backwards ? 'reverse-' : '';
@@ -590,7 +658,7 @@ exports.handler.attach = function(editor) {
590
658
  initialized = true;
591
659
  dom.importCssString('\
592
660
  .emacs-mode .ace_cursor{\
593
- border: 2px rgba(50,250,50,0.8) solid!important;\
661
+ border: 1px rgba(50,250,50,0.8) solid!important;\
594
662
  -moz-box-sizing: border-box!important;\
595
663
  -webkit-box-sizing: border-box!important;\
596
664
  box-sizing: border-box!important;\
@@ -648,6 +716,22 @@ exports.handler.attach = function(editor) {
648
716
  return this.session.$emacsMark || this.session.$emacsMarkRing.slice(-1)[0];
649
717
  };
650
718
 
719
+ editor.emacsMarkForSelection = function(replacement) {
720
+ var sel = this.selection,
721
+ multiRangeLength = this.multiSelect ?
722
+ this.multiSelect.getAllRanges().length : 1,
723
+ selIndex = sel.index || 0,
724
+ markRing = this.session.$emacsMarkRing,
725
+ markIndex = markRing.length - (multiRangeLength - selIndex),
726
+ lastMark = markRing[markIndex] || sel.anchor;
727
+ if (replacement) {
728
+ markRing.splice(markIndex, 1,
729
+ "row" in replacement && "column" in replacement ?
730
+ replacement : undefined);
731
+ }
732
+ return lastMark;
733
+ }
734
+
651
735
  editor.on("click", $resetMarkMode);
652
736
  editor.on("changeSession", $kbSessionChange);
653
737
  editor.renderer.screenToTextCoordinates = screenToTextBlockCoordinates;
@@ -669,6 +753,7 @@ exports.handler.detach = function(editor) {
669
753
  editor.commands.removeCommands(commands);
670
754
  editor.removeEventListener('copy', this.onCopy);
671
755
  editor.removeEventListener('paste', this.onPaste);
756
+ editor.$emacsModeHandler = null;
672
757
  };
673
758
 
674
759
  var $kbSessionChange = function(e) {
@@ -710,7 +795,7 @@ exports.handler.onCopy = function(e, editor) {
710
795
  if (editor.$handlesEmacsOnCopy) return;
711
796
  editor.$handlesEmacsOnCopy = true;
712
797
  exports.handler.commands.killRingSave.exec(editor);
713
- delete editor.$handlesEmacsOnCopy;
798
+ editor.$handlesEmacsOnCopy = false;
714
799
  };
715
800
 
716
801
  exports.handler.onPaste = function(e, editor) {
@@ -718,6 +803,8 @@ exports.handler.onPaste = function(e, editor) {
718
803
  };
719
804
 
720
805
  exports.handler.bindKey = function(key, command) {
806
+ if (typeof key == "object")
807
+ key = key[this.platform];
721
808
  if (!key)
722
809
  return;
723
810
 
@@ -735,10 +822,20 @@ exports.handler.bindKey = function(key, command) {
735
822
  }, this);
736
823
  };
737
824
 
825
+ exports.handler.getStatusText = function(editor, data) {
826
+ var str = "";
827
+ if (data.count)
828
+ str += data.count;
829
+ if (data.keyChain)
830
+ str += " " + data.keyChain
831
+ return str;
832
+ };
833
+
738
834
  exports.handler.handleKeyboard = function(data, hashId, key, keyCode) {
739
835
  if (keyCode === -1) return undefined;
740
836
 
741
837
  var editor = data.editor;
838
+ editor._signal("changeStatus");
742
839
  if (hashId == -1) {
743
840
  editor.pushEmacsMark();
744
841
  if (data.count) {
@@ -748,20 +845,15 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) {
748
845
  }
749
846
  }
750
847
 
751
- if (key == "\x00") return undefined;
752
-
753
848
  var modifier = eMods[hashId];
754
- if (modifier == "c-" || data.universalArgument) {
755
- var prevCount = String(data.count || 0);
849
+ if (modifier == "c-" || data.count) {
756
850
  var count = parseInt(key[key.length - 1]);
757
851
  if (typeof count === 'number' && !isNaN(count)) {
758
- data.count = parseInt(prevCount + count);
852
+ data.count = Math.max(data.count, 0) || 0;
853
+ data.count = 10 * data.count + count;
759
854
  return {command: "null"};
760
- } else if (data.universalArgument) {
761
- data.count = 4;
762
855
  }
763
856
  }
764
- data.universalArgument = false;
765
857
  if (modifier) key = modifier + key;
766
858
  if (data.keyChain) key = data.keyChain += " " + key;
767
859
  var command = this.commandKeyBinding[key];
@@ -770,7 +862,7 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) {
770
862
  if (command === "null") return {command: "null"};
771
863
 
772
864
  if (command === "universalArgument") {
773
- data.universalArgument = true;
865
+ data.count = -4;
774
866
  return {command: "null"};
775
867
  }
776
868
  var args;
@@ -809,7 +901,8 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) {
809
901
  exec: function(editor, args) {
810
902
  for (var i = 0; i < count; i++)
811
903
  command.exec(editor, args);
812
- }
904
+ },
905
+ multiSelectAction: command.multiSelectAction
813
906
  }
814
907
  };
815
908
  } else {
@@ -915,53 +1008,56 @@ exports.handler.addCommands({
915
1008
  },
916
1009
  setMark: {
917
1010
  exec: function(editor, args) {
1011
+
918
1012
  if (args && args.count) {
919
- var mark = editor.popEmacsMark();
920
- mark && editor.selection.moveCursorToPosition(mark);
1013
+ if (editor.inMultiSelectMode) editor.forEachSelection(moveToMark);
1014
+ else moveToMark();
1015
+ moveToMark();
921
1016
  return;
922
1017
  }
923
1018
 
924
1019
  var mark = editor.emacsMark(),
925
- transientMarkModeActive = true;
926
- if (transientMarkModeActive && (mark || !editor.selection.isEmpty())) {
927
- editor.pushEmacsMark();
928
- editor.clearSelection();
1020
+ ranges = editor.selection.getAllRanges(),
1021
+ rangePositions = ranges.map(function(r) { return {row: r.start.row, column: r.start.column}; }),
1022
+ transientMarkModeActive = true,
1023
+ hasNoSelection = ranges.every(function(range) { return range.isEmpty(); });
1024
+ if (transientMarkModeActive && (mark || !hasNoSelection)) {
1025
+ if (editor.inMultiSelectMode) editor.forEachSelection({exec: editor.clearSelection.bind(editor)})
1026
+ else editor.clearSelection();
1027
+ if (mark) editor.pushEmacsMark(null);
929
1028
  return;
930
1029
  }
931
1030
 
932
- if (mark) {
933
- var cp = editor.getCursorPosition();
934
- if (editor.selection.isEmpty() &&
935
- mark.row == cp.row && mark.column == cp.column) {
936
- editor.pushEmacsMark();
937
- return;
938
- }
1031
+ if (!mark) {
1032
+ rangePositions.forEach(function(pos) { editor.pushEmacsMark(pos); });
1033
+ editor.setEmacsMark(rangePositions[rangePositions.length-1]);
1034
+ return;
1035
+ }
1036
+
1037
+ function moveToMark() {
1038
+ var mark = editor.popEmacsMark();
1039
+ mark && editor.moveCursorToPosition(mark);
939
1040
  }
940
- mark = editor.getCursorPosition();
941
- editor.setEmacsMark(mark);
942
- editor.selection.setSelectionAnchor(mark.row, mark.column);
1041
+
943
1042
  },
944
1043
  readOnly: true,
945
- handlesCount: true,
946
- multiSelectAction: "forEach"
1044
+ handlesCount: true
947
1045
  },
948
1046
  exchangePointAndMark: {
949
- exec: function(editor, args) {
1047
+ exec: function exchangePointAndMark$exec(editor, args) {
950
1048
  var sel = editor.selection;
951
- if (args.count) {
952
- var pos = editor.getCursorPosition();
953
- sel.clearSelection();
954
- sel.moveCursorToPosition(editor.popEmacsMark());
955
- editor.pushEmacsMark(pos);
1049
+ if (!args.count && !sel.isEmpty()) { // just invert selection
1050
+ sel.setSelectionRange(sel.getRange(), !sel.isBackwards());
956
1051
  return;
957
1052
  }
958
- var lastMark = editor.getLastEmacsMark();
959
- var range = sel.getRange();
960
- if (range.isEmpty()) {
961
- sel.selectToPosition(lastMark);
962
- return;
1053
+
1054
+ if (args.count) { // replace mark and point
1055
+ var pos = {row: sel.lead.row, column: sel.lead.column};
1056
+ sel.clearSelection();
1057
+ sel.moveCursorToPosition(editor.emacsMarkForSelection(pos));
1058
+ } else { // create selection to last mark
1059
+ sel.selectToPosition(editor.emacsMarkForSelection());
963
1060
  }
964
- sel.setSelectionRange(range, !sel.isBackwards());
965
1061
  },
966
1062
  readOnly: true,
967
1063
  handlesCount: true,
@@ -1009,6 +1105,7 @@ exports.handler.addCommands({
1009
1105
  if (editor.keyBinding.$data.lastCommand != "yank")
1010
1106
  return;
1011
1107
  editor.undo();
1108
+ editor.session.$emacsMarkRing.pop(); // also undo recording mark
1012
1109
  editor.onPaste(exports.killRing.rotate());
1013
1110
  editor.keyBinding.$data.lastCommand = "yank";
1014
1111
  },
@@ -1022,12 +1119,23 @@ exports.handler.addCommands({
1022
1119
  },
1023
1120
  killRingSave: {
1024
1121
  exec: function(editor) {
1122
+
1123
+ editor.$handlesEmacsOnCopy = true;
1124
+ var marks = editor.session.$emacsMarkRing.slice(),
1125
+ deselectedMarks = [];
1025
1126
  exports.killRing.add(editor.getCopyText());
1127
+
1026
1128
  setTimeout(function() {
1027
- var sel = editor.selection,
1028
- range = sel.getRange();
1029
- editor.pushEmacsMark(sel.isBackwards() ? range.end : range.start);
1030
- sel.clearSelection();
1129
+ function deselect() {
1130
+ var sel = editor.selection, range = sel.getRange(),
1131
+ pos = sel.isBackwards() ? range.end : range.start;
1132
+ deselectedMarks.push({row: pos.row, column: pos.column});
1133
+ sel.clearSelection();
1134
+ }
1135
+ editor.$handlesEmacsOnCopy = false;
1136
+ if (editor.inMultiSelectMode) editor.forEachSelection({exec: deselect});
1137
+ else deselect();
1138
+ editor.session.$emacsMarkRing = marks.concat(deselectedMarks.reverse());
1031
1139
  }, 0);
1032
1140
  },
1033
1141
  readOnly: true
@@ -1035,6 +1143,7 @@ exports.handler.addCommands({
1035
1143
  keyboardQuit: function(editor) {
1036
1144
  editor.selection.clearSelection();
1037
1145
  editor.setEmacsMark(null);
1146
+ editor.keyBinding.$data.count = null;
1038
1147
  },
1039
1148
  focusCommandLine: function(editor, arg) {
1040
1149
  if (editor.showCommandLine)