diff --git a/lib/ace/multi_cursor.js b/lib/ace/multi_cursor.js index d5e930ee..db286363 100644 --- a/lib/ace/multi_cursor.js +++ b/lib/ace/multi_cursor.js @@ -52,8 +52,25 @@ function VirtualSelection(selection) { this.selectionLead = this.doc.createAnchor(0, 0); this.selectionAnchor = this.doc.createAnchor(0, 0); - this.selectionLead.detach() - this.selectionAnchor.detach() + /*var _self = this; + this.selectionLead.on("change", function(e) { + _self._emit("changeCursor"); + if (!_self.$isEmpty) + _self._emit("changeSelection"); + if (!_self.$preventUpdateDesiredColumnOnChange && e.old.column != e.value.column) + _self.$updateDesiredColumn(); + }); + + this.selectionAnchor.on("change", function() { + if (!_self.$isEmpty) + _self._emit("changeSelection"); + }); */ + + this.detach = function() { + this.selectionLead.detach(); + this.selectionAnchor.detach(); + this.session = this.doc = null; + } this.fromRange = function(r) { this.setSelectionRange(r, r.cursor == r.start) @@ -80,6 +97,9 @@ function forEachSelection(editor, cmd, args) { var selection = editor.selection var rangeList = selection.rangeList + var reg = selection._eventRegistry; + selection._eventRegistry = {}; + var sh = new VirtualSelection(selection) editor.session.multiSelection.inVirtualMode = true for (var i = rangeList.ranges.length; i--;) { @@ -89,10 +109,12 @@ function forEachSelection(editor, cmd, args) { sh.toRange(rangeList.ranges[i]) } + sh.detach(); rangeList.merge() - editor.selection = session.selection = selection - editor.session.multiSelection.inVirtualMode = false + editor.selection = session.selection = selection; + editor.session.multiSelection.inVirtualMode = false; + selection._eventRegistry = reg; selection.setSelectionRange(selection.rangeList.all[0]) editor.renderer.updateCursor(); @@ -128,6 +150,7 @@ function enterMultiSelectMode(editor) { editor.commands.__exec = editor.commands.exec editor.commands.exec = exec + editor.session.$undoSelect = false editor.selection.rangeList.attach(editor.session); } function exitMultiSelectMode(editor) { @@ -143,7 +166,9 @@ function exitMultiSelectMode(editor) { editor.renderer.updateCursor(); editor.renderer.updateBackMarkers(); - editor.selection.rangeList.dettach(editor.session); + editor.session.$undoSelect = true + + editor.selection.rangeList.detach(editor.session); } function initSession(session) { @@ -347,7 +372,7 @@ function onMouseDown(e) { selection.clearSelection(); if (!isMultiSelect) { enterMultiSelectMode(editor) - selection.rangeCount = 5 + selection.rangeCount = Infinity } @@ -371,6 +396,13 @@ function onMouseDown(e) { selection.secondarySelections = []; for (var i = rectSel.length; i--; ) addSelectionRange(editor, rectSel[i]) + + if (selection.rangeCount == Infinity) { + selection.rangeCount = selection.rangeList.all.length + selection.secondarySelections.length; + + if (selection.rangeCount <= 1) + exitMultiSelectMode(editor) + } }; var anchor = selection.getCursor(); diff --git a/lib/ace/range_list.js b/lib/ace/range_list.js index fcf9b250..9777b5ab 100644 --- a/lib/ace/range_list.js +++ b/lib/ace/range_list.js @@ -170,7 +170,7 @@ var RangeList = function(startRow, startColumn, endRow, endColumn) { this.attach = function(session) { if (this.session) - this.dettach(); + this.detach(); this.session = session; this.onChange = this.$onChange.bind(this); @@ -178,7 +178,7 @@ var RangeList = function(startRow, startColumn, endRow, endColumn) { this.session.on('change', this.onChange); }; - this.dettach = function() { + this.detach = function() { if (!this.session) return; this.session.removeListener('change', this.onChange) @@ -186,7 +186,46 @@ var RangeList = function(startRow, startColumn, endRow, endColumn) { }; this.$onChange = function(e) { - // todo + var changeRange = e.data.range; + if (e.data.action[0] == "i"){ + var start = changeRange.start; + var end = changeRange.end; + } else { + var end = changeRange.start; + var start = changeRange.end; + } + var startRow = start.row; + var endRow = end.row; + var lineDif = endRow - startRow; + + var colDiff = -start.column + end.column; + + var ranges = this.ranges; + + for (var i=0, n = ranges.length; i < n; i++) { + var r = ranges[i]; + if (r.end.row < startRow) + continue; + if (r.start.row > startRow) + break; + + if (r.start.row == startRow && r.start.column >= start.column ) { + r.start.column += colDiff; + r.start.row += lineDif; + } + if (r.end.row == startRow && r.end.column >= start.column) { + r.end.column += colDiff; + r.end.row += lineDif; + } + } + + if (lineDif != 0 && i < n) { + for (; i < n; i++) { + var r = ranges[i]; + r.start.row += lineDif; + r.end.row += lineDif; + } + } }; }).call(RangeList.prototype); diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 0e6b9f7c..66717d9d 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -736,6 +736,19 @@ var VirtualRenderer = function(container, theme) { // todo: handle horizontal scrolling }; + this.pixelToScreenCoordinates = function(pageX, pageY) { + var canvasPos = this.scroller.getBoundingClientRect(); + + var col = Math.round( + (pageX + this.scrollLeft - canvasPos.left - this.$padding - dom.getPageScrollLeft()) / this.characterWidth + ); + var row = Math.floor( + (pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop()) / this.lineHeight + ); + + return {row: row, column: col}; + }; + this.screenToTextCoordinates = function(pageX, pageY) { var canvasPos = this.scroller.getBoundingClientRect();