mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-14 04:29:04 +03:00
Overlapping selections are merged
This commit is contained in:
parent
22eb9c5860
commit
8422c7ad12
@ -757,7 +757,7 @@ describe "Editor", ->
|
||||
expect(range.end).toEqual({row: 5, column: 27})
|
||||
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
|
||||
|
||||
fdescribe "multiple cursor placement", ->
|
||||
fdescribe "multiple cursors", ->
|
||||
it "places multiple cursor with meta-click", ->
|
||||
editor.attachToDom()
|
||||
editor.lines.trigger mousedownEvent(editor: editor, point: [3, 0])
|
||||
@ -919,6 +919,22 @@ describe "Editor", ->
|
||||
expect(selection1.getScreenRange()).toEqual [[4, 10], [5, 27]]
|
||||
expect(selection2.getScreenRange()).toEqual [[6, 10], [8, 27]]
|
||||
|
||||
describe "when multiple selctions intersect", ->
|
||||
it "merges a selection that is completely contained within another", ->
|
||||
editor.attachToDom()
|
||||
editor.lines.trigger mousedownEvent(editor: editor, point: [4, 10])
|
||||
editor.lines.trigger mousemoveEvent(editor: editor, point: [5, 27])
|
||||
editor.lines.trigger 'mouseup'
|
||||
|
||||
editor.lines.trigger mousedownEvent(editor: editor, point: [3, 10], metaKey: true)
|
||||
editor.lines.trigger mousemoveEvent(editor: editor, point: [6, 27], metaKey: true)
|
||||
editor.lines.trigger 'mouseup'
|
||||
|
||||
selections = editor.compositeSelection.getSelections()
|
||||
expect(selections.length).toBe 1
|
||||
[selection1] = selections
|
||||
expect(selection1.getScreenRange()).toEqual [[3, 10], [6, 27]]
|
||||
|
||||
describe "cursor merging", ->
|
||||
it "merges cursors when they overlap due to a buffer change", ->
|
||||
editor.setCursorScreenPosition([0, 0])
|
||||
|
@ -15,3 +15,18 @@ describe "Range", ->
|
||||
expect(new Range(new Point(1, 1), new Point(1, 1)).isEmpty()).toBeTruthy()
|
||||
expect(new Range(new Point(1, 1), new Point(1, 2)).isEmpty()).toBeFalsy()
|
||||
|
||||
describe ".intersectsWith(otherRange)", ->
|
||||
it "returns true if the ranges intersect", ->
|
||||
expect(new Range([1, 1], [2, 10]).intersectsWith(new Range([2, 1], [3, 10]))).toBeTruthy()
|
||||
expect(new Range([2, 1], [3, 10]).intersectsWith(new Range([1, 1], [2, 10]))).toBeTruthy()
|
||||
expect(new Range([2, 1], [3, 10]).intersectsWith(new Range([2, 5], [3, 1]))).toBeTruthy()
|
||||
expect(new Range([2, 5], [3, 1]).intersectsWith(new Range([2, 1], [3, 10]))).toBeTruthy()
|
||||
expect(new Range([2, 5], [3, 1]).intersectsWith(new Range([3, 2], [3, 10]))).toBeFalsy()
|
||||
expect(new Range([3, 2], [3, 10]).intersectsWith(new Range([2, 5], [3, 1]))).toBeFalsy()
|
||||
|
||||
describe ".union(otherRange)", ->
|
||||
it "returns the union of the two ranges", ->
|
||||
expect(new Range([1, 1], [2, 10]).union(new Range([2, 1], [3, 10]))).toEqual [[1, 1], [3, 10]]
|
||||
expect(new Range([2, 1], [3, 10]).union(new Range([1, 1], [2, 10]))).toEqual [[1, 1], [3, 10]]
|
||||
expect(new Range([2, 1], [3, 10]).union(new Range([2, 5], [3, 1]))).toEqual [[2, 1], [3, 10]]
|
||||
expect(new Range([2, 5], [3, 1]).union(new Range([2, 1], [3, 10]))).toEqual [[2, 1], [3, 10]]
|
||||
|
42
spec/atom/range-spec.js
Normal file
42
spec/atom/range-spec.js
Normal file
@ -0,0 +1,42 @@
|
||||
(function() {
|
||||
var Point, Range;
|
||||
|
||||
Range = require('range');
|
||||
|
||||
Point = require('point');
|
||||
|
||||
describe("Range", function() {
|
||||
describe("constructor", function() {
|
||||
return it("ensures that @start <= @end", function() {
|
||||
var range1, range2;
|
||||
range1 = new Range(new Point(0, 1), new Point(0, 4));
|
||||
expect(range1.start).toEqual({
|
||||
row: 0,
|
||||
column: 1
|
||||
});
|
||||
range2 = new Range(new Point(1, 4), new Point(0, 1));
|
||||
return expect(range2.start).toEqual({
|
||||
row: 0,
|
||||
column: 1
|
||||
});
|
||||
});
|
||||
});
|
||||
describe(".isEmpty()", function() {
|
||||
return it("returns true if @start equals @end", function() {
|
||||
expect(new Range(new Point(1, 1), new Point(1, 1)).isEmpty()).toBeTruthy();
|
||||
return expect(new Range(new Point(1, 1), new Point(1, 2)).isEmpty()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
return describe(".intersectsWith(otherRange)", function() {
|
||||
return fit("returns the intersection of the two ranges", function() {
|
||||
var range1, range2;
|
||||
range1 = new Range([1, 1], [2, 10]);
|
||||
range2 = new Range([2, 1], [3, 10]);
|
||||
expect(range1.intersectsWith(range2)).toBeTruth;
|
||||
range2 = range1 = new Range([2, 1], [3, 10]);
|
||||
return expect(range1.intersectsWith(range2)).toBeTruth;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
@ -27,4 +27,14 @@ class CompositeSeleciton
|
||||
selection.backspace()
|
||||
|
||||
selectToScreenPosition: (position) ->
|
||||
_.last(@selections).selectToScreenPosition(position)
|
||||
_.last(@selections).selectToScreenPosition(position)
|
||||
|
||||
mergeIntersectingSelections: ->
|
||||
for selection in @getSelections()
|
||||
otherSelections = @getSelections()
|
||||
_.remove(otherSelections, selection)
|
||||
for otherSelection in otherSelections
|
||||
if selection.intersectsWith(otherSelection)
|
||||
selection.merge(otherSelection)
|
||||
@mergeIntersectingSelections()
|
||||
return
|
||||
|
@ -166,7 +166,9 @@ class Editor extends View
|
||||
selectOnMousemoveUntilMouseup: ->
|
||||
moveHandler = (e) => @selectToScreenPosition(@screenPositionFromMouseEvent(e))
|
||||
@on 'mousemove', moveHandler
|
||||
$(document).one 'mouseup', => @off 'mousemove', moveHandler
|
||||
$(document).one 'mouseup', =>
|
||||
@off 'mousemove', moveHandler
|
||||
@compositeSelection.mergeIntersectingSelections()
|
||||
|
||||
renderLines: ->
|
||||
@lineCache = []
|
||||
|
@ -40,6 +40,17 @@ class Range
|
||||
inspect: ->
|
||||
"[#{@start.inspect()} - #{@end.inspect()}]"
|
||||
|
||||
intersectsWith: (otherRange) ->
|
||||
if @start.isLessThanOrEqual(otherRange.start)
|
||||
@end.isGreaterThan(otherRange.start)
|
||||
else
|
||||
otherRange.intersectsWith(this)
|
||||
|
||||
union: (otherRange) ->
|
||||
start = if @start.isLessThan(otherRange.start) then @start else otherRange.start
|
||||
end = if @end.isGreaterThan(otherRange.end) then @end else otherRange.end
|
||||
new Range(start, end)
|
||||
|
||||
isEmpty: ->
|
||||
@start.isEqual(@end)
|
||||
|
||||
|
@ -92,6 +92,17 @@ class Selection extends View
|
||||
isEmpty: ->
|
||||
@getBufferRange().isEmpty()
|
||||
|
||||
intersectsWith: (otherSelection) ->
|
||||
@getScreenRange().intersectsWith(otherSelection.getScreenRange())
|
||||
|
||||
merge: (otherSelection) ->
|
||||
@setScreenRange(@getScreenRange().union(otherSelection.getScreenRange()))
|
||||
otherSelection.remove()
|
||||
|
||||
remove: ->
|
||||
@cursor?.remove()
|
||||
super
|
||||
|
||||
modifySelection: (fn) ->
|
||||
@placeAnchor()
|
||||
@modifyingSelection = true
|
||||
|
Loading…
Reference in New Issue
Block a user