From b77c3b348ebcb2b6e952262f4c2605a58a6d5287 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 14 Apr 2012 18:20:27 +0400 Subject: [PATCH] fix bug with ghost selections --- lib/ace/layer/cursor.js | 2 +- lib/ace/mouse/multi_select_handler.js | 14 ++++++--- lib/ace/multi_select.js | 22 ++++++++------ lib/ace/multi_select_test.js | 41 +++++++++++++++++++++------ lib/ace/range.js | 2 +- 5 files changed, 58 insertions(+), 23 deletions(-) diff --git a/lib/ace/layer/cursor.js b/lib/ace/layer/cursor.js index 36a085f3..38b4adbc 100644 --- a/lib/ace/layer/cursor.js +++ b/lib/ace/layer/cursor.js @@ -141,7 +141,7 @@ var Cursor = function(parentEl) { this.update = function(config) { this.config = config; - if (this.session.selectionMarkerCount > 1) { + if (this.session.selectionMarkerCount > 0) { var selections = this.session.$selectionMarkers; var i = 0, sel, cursorIndex = 0; diff --git a/lib/ace/mouse/multi_select_handler.js b/lib/ace/mouse/multi_select_handler.js index fa5def23..34db2cda 100644 --- a/lib/ace/mouse/multi_select_handler.js +++ b/lib/ace/mouse/multi_select_handler.js @@ -111,9 +111,10 @@ function onMouseDown(e) { if (!isMultiSelect && inSelection) return; // dragging - if (!isMultiSelect) - selection.addRange(selection.toOrientedRange()); - + if (!isMultiSelect) { + var range = selection.toOrientedRange(); + editor.addSelectionMarker(range); + } var oldRange = selection.rangeList.rangeAtPoint(pos); @@ -122,8 +123,13 @@ function onMouseDown(e) { if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor)) selection.substractPoint(tmpSel.cursor); - else + else { + if (range) { + editor.removeSelectionMarkers([range]); + selection.addRange(range); + } selection.addRange(tmpSel); + } }); } else if (!shift && alt && button == 0) { diff --git a/lib/ace/multi_select.js b/lib/ace/multi_select.js index b1104775..0586a722 100644 --- a/lib/ace/multi_select.js +++ b/lib/ace/multi_select.js @@ -77,17 +77,21 @@ var EditSession = require("./edit_session").EditSession; * adds a range to selection entering multiselect mode if necessary **/ this.addRange = function(range) { - if (!this.inMultiSelectMode && this.rangeCount == 0) { - var oldRange = this.toOrientedRange(); - if (!range || !range.isEqual(oldRange)) { - this.rangeList.add(oldRange); - this.$onAddRange(oldRange); - } - } - if (!range) return; + if (!this.inMultiSelectMode && this.rangeCount == 0) { + var oldRange = this.toOrientedRange(); + if (range.intersects(oldRange)) { + this.fromOrientedRange(range); + return; + } + + this.rangeList.add(oldRange); + this.$onAddRange(oldRange); + } + + if (!range.cursor) range.cursor = range.end; @@ -98,7 +102,7 @@ var EditSession = require("./edit_session").EditSession; if (removed.length) this.$onRemoveRange(removed); - if (this.rangeCount > 0 && !this.inMultiSelectMode) { + if (this.rangeCount > 1 && !this.inMultiSelectMode) { this._emit("multiSelect"); this.inMultiSelectMode = true; this.session.$undoSelect = false; diff --git a/lib/ace/multi_select_test.js b/lib/ace/multi_select_test.js index 571202f0..8e0a4013 100644 --- a/lib/ace/multi_select_test.js +++ b/lib/ace/multi_select_test.js @@ -57,7 +57,7 @@ var exec = function(name, times, args) { } while(times --> 1) }; var testRanges = function(str) { - assert.equal(editor.selection.getAllRanges()+"", str); + assert.equal(editor.selection.getAllRanges() + "", str + ""); } module.exports = { @@ -78,8 +78,8 @@ module.exports = { assert.ok(editor.inMultiSelectMode); assert.equal(editor.selection.getAllRanges().length, 4); - var newLine = editor.session.getDocument().getNewLineCharacter(); - var copyText = "wwww".split("").join(newLine); + var newLine = editor.session.getDocument().getNewLineCharacter(); + var copyText = "wwww".split("").join(newLine); assert.equal(editor.getCopyText(), copyText); exec("insertstring", 1, "a"); exec("backspace", 2); @@ -120,14 +120,11 @@ module.exports = { " wtt.w", " wtt.w" ]); - var editor = new Editor(new MockRenderer(), doc); + editor = new Editor(new MockRenderer(), doc); MultiSelect(editor); editor.selectMoreLines(1) - assert.equal( - editor.selection.getAllRanges()+"", - "Range: [0/0] -> [0/0],Range: [1/0] -> [1/0]" - ); + testRanges("Range: [0/0] -> [0/0],Range: [1/0] -> [1/0]"); assert.ok(editor.inMultiSelectMode); var doc2 = new EditSession(["w1"]); @@ -136,6 +133,34 @@ module.exports = { editor.setSession(doc); assert.ok(editor.inMultiSelectMode); + }, + + "test: multiselect addRange": function() { + var doc = new EditSession([ + "w1.w2", + " wtt.w", + " wtt.w" + ]); + editor = new Editor(new MockRenderer(), doc); + MultiSelect(editor); + var selection = editor.selection; + + var range1 = new Range(0, 2, 0, 4); + editor.selection.fromOrientedRange(range1); + + var range2 = new Range(0, 3, 0, 4); + selection.addRange(range2); + assert.ok(!editor.inMultiSelectMode); + assert.ok(range2.isEqual(editor.selection.getRange())); + + var range3 = new Range(0, 1, 0, 1); + selection.addRange(range3); + assert.ok(editor.inMultiSelectMode); + testRanges([range3, range2]); + + var range4 = new Range(0, 0, 4, 0); + selection.addRange(range4); + assert.ok(!editor.inMultiSelectMode); } }; diff --git a/lib/ace/range.js b/lib/ace/range.js index 163979fe..0947d9f4 100644 --- a/lib/ace/range.js +++ b/lib/ace/range.js @@ -117,7 +117,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) { return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0; } - this.intersectsRange = function(range) { + this.intersects = function(range) { var cmp = this.compareRange(range); return (cmp == -1 || cmp == 0 || cmp == 1); }