Skip to content

Commit 6f7a33e

Browse files
committed
allow multiple selections with shared edges
1 parent 7eeb988 commit 6f7a33e

4 files changed

Lines changed: 46 additions & 18 deletions

File tree

lib/ace/mouse/default_handlers.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@ function DefaultHandlers(mouseHandler) {
8484
// selection
8585
if (inSelection && !editor.isFocused()) {
8686
editor.focus();
87-
if (this.$focusTimout && !this.$clickSelection) {
87+
if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {
8888
this.setState("focusWait");
8989
this.captureMouse(ev);
9090
return ev.preventDefault();
9191
}
9292
}
9393

94-
if (!inSelection || this.$clickSelection || ev.getShiftKey()) {
94+
if (!inSelection || this.$clickSelection || ev.getShiftKey() || editor.inMultiSelectMode) {
9595
// Directly pick STATE_SELECT, since the user is not clicking inside
9696
// a selection.
9797
this.startSelect(pos);

lib/ace/multi_select.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,13 @@ var EditSession = require("./edit_session").EditSession;
7878

7979
if (!this.inMultiSelectMode && this.rangeCount == 0) {
8080
var oldRange = this.toOrientedRange();
81-
if (range.intersects(oldRange))
81+
this.rangeList.add(oldRange);
82+
this.rangeList.add(range);
83+
if (this.rangeList.ranges.length != 2) {
84+
this.rangeList.removeAll();
8285
return $blockChangeEvents || this.fromOrientedRange(range);
83-
86+
}
87+
this.rangeList.removeAll();
8488
this.rangeList.add(oldRange);
8589
this.$onAddRange(oldRange);
8690
}

lib/ace/range_list.js

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,18 @@ var RangeList = function() {
4040
(function() {
4141
this.comparePoints = comparePoints;
4242

43-
this.pointIndex = function(pos, startIndex) {
43+
this.pointIndex = function(pos, excludeEdges, startIndex) {
4444
var list = this.ranges;
4545

4646
for (var i = startIndex || 0; i < list.length; i++) {
4747
var range = list[i];
48-
var cmp = comparePoints(pos, range.end);
49-
50-
if (cmp > 0)
48+
var cmpEnd = comparePoints(pos, range.end);
49+
if (cmpEnd > 0)
5150
continue;
52-
if (cmp == 0)
53-
return i;
54-
cmp = comparePoints(pos, range.start);
55-
if (cmp >= 0)
51+
var cmpStart = comparePoints(pos, range.start);
52+
if (cmpEnd === 0)
53+
return excludeEdges && cmpStart !== 0 ? -i-2 : i;
54+
if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))
5655
return i;
5756

5857
return -i-1;
@@ -61,17 +60,17 @@ var RangeList = function() {
6160
};
6261

6362
this.add = function(range) {
64-
var startIndex = this.pointIndex(range.start);
63+
var excludeEdges = !range.isEmpty();
64+
var startIndex = this.pointIndex(range.start, excludeEdges);
6565
if (startIndex < 0)
6666
startIndex = -startIndex - 1;
6767

68-
var endIndex = this.pointIndex(range.end, startIndex);
68+
var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);
6969

7070
if (endIndex < 0)
7171
endIndex = -endIndex - 1;
7272
else
7373
endIndex++;
74-
7574
return this.ranges.splice(startIndex, endIndex - startIndex, range);
7675
};
7776

@@ -102,7 +101,7 @@ var RangeList = function() {
102101
if (cmp < 0)
103102
continue;
104103

105-
if (cmp == 0 && !(range.isEmpty() || next.isEmpty()))
104+
if (cmp == 0 && !range.isEmpty() && !next.isEmpty())
106105
continue;
107106

108107
if (comparePoints(range.end, next.end) < 0) {
@@ -198,10 +197,16 @@ var RangeList = function() {
198197
break;
199198

200199
if (r.start.row == startRow && r.start.column >= start.column ) {
200+
201201
r.start.column += colDiff;
202202
r.start.row += lineDif;
203203
}
204-
if (r.end.row == startRow && r.end.column >= start.column) {
204+
if (r.end.row == startRow && r.end.column >= start.column) {
205+
// special handling for the case when two ranges share an edge
206+
if (r.end.column == start.column && colDiff > 0 && i < n - 1) {
207+
if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)
208+
r.end.column -= colDiff;
209+
}
205210
r.end.column += colDiff;
206211
r.end.row += lineDif;
207212
}

lib/ace/range_list_test.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,26 @@ module.exports = {
7272
assert.equal(rangeList.pointIndex({row: 8, column: 9}), 2);
7373
assert.equal(rangeList.pointIndex({row: 18, column: 9}), -4);
7474
},
75+
76+
"test: rangeList pointIndex excludeEdges": function() {
77+
var rangeList = new RangeList();
78+
rangeList.ranges = [
79+
new Range(1,2,3,4),
80+
new Range(4,2,5,4),
81+
new Range(8,8,9,9),
82+
new Range(10,10,10,10)
83+
];
84+
85+
assert.equal(rangeList.pointIndex({row: 0, column: 1}, true), -1);
86+
assert.equal(rangeList.pointIndex({row: 1, column: 2}, true), -1);
87+
assert.equal(rangeList.pointIndex({row: 1, column: 3}, true), 0);
88+
assert.equal(rangeList.pointIndex({row: 3, column: 4}, true), -2);
89+
assert.equal(rangeList.pointIndex({row: 4, column: 1}, true), -2);
90+
assert.equal(rangeList.pointIndex({row: 5, column: 1}, true), 1);
91+
assert.equal(rangeList.pointIndex({row: 8, column: 9}, true), 2);
92+
assert.equal(rangeList.pointIndex({row: 10, column: 10}, true), 3);
93+
assert.equal(rangeList.pointIndex({row: 18, column: 9}, true), -5);
94+
},
7595

7696
"test: rangeList add": function() {
7797
var rangeList = new RangeList();
@@ -153,7 +173,6 @@ module.exports = {
153173
rangeList.substractPoint({row: 6, column: 7});
154174
assert.equal(rangeList.ranges.length, 2);
155175
}
156-
157176
};
158177

159178
});

0 commit comments

Comments
 (0)