overuse of events is bad:(
This commit is contained in:
parent
299cdc1b19
commit
346ae096b3
5 changed files with 581 additions and 503 deletions
|
|
@ -40,23 +40,23 @@ define(function(require, exports, module) {
|
||||||
|
|
||||||
// add multiSelectAction annotations to default commands
|
// add multiSelectAction annotations to default commands
|
||||||
require("./default_commands").commands.forEach(function(command) {
|
require("./default_commands").commands.forEach(function(command) {
|
||||||
var single = RegExp(["selectall"].join("|"), "");
|
var single = RegExp(["selectall"].join("|"), "");
|
||||||
var mapOver = RegExp(["backspace", "del",
|
var mapOver = RegExp(["backspace", "del",
|
||||||
"golinedown", "golineup", "gotoend", "gotoleft", "gotolineend", "gotolinestart",
|
"golinedown", "golineup", "gotoend", "gotoleft", "gotolineend", "gotolinestart",
|
||||||
"gotoright", "gotostart", "gotowordleft", "gotowordright",
|
"gotoright", "gotostart", "gotowordleft", "gotowordright",
|
||||||
"indent", "insertstring", "inserttext", "jumptomatching", "outdent",
|
"indent", "insertstring", "inserttext", "jumptomatching", "outdent",
|
||||||
"removetolineend", "removetolinestart", "removewordleft", "removewordright",
|
"removetolineend", "removetolinestart", "removewordleft", "removewordright",
|
||||||
"selectdown", "selectleft", "selectlineend", "selectlinestart", "selectright",
|
"selectdown", "selectleft", "selectlineend", "selectlinestart", "selectright",
|
||||||
"selecttoend", "selecttolineend", "selecttolinestart", "selecttostart",
|
"selecttoend", "selecttolineend", "selecttolinestart", "selecttostart",
|
||||||
"selectup", "selectwordleft", "selectwordright",
|
"selectup", "selectwordleft", "selectwordright",
|
||||||
"splitline", "tolowercase", "touppercase"].join("|"), "");
|
"splitline", "tolowercase", "touppercase"].join("|"), "");
|
||||||
|
|
||||||
if (single.test(command.name))
|
if (single.test(command.name))
|
||||||
command.multiSelectAction = "single";
|
command.multiSelectAction = "single";
|
||||||
else if (mapOver.test(command.name))
|
else if (mapOver.test(command.name))
|
||||||
command.multiSelectAction = "forEach";
|
command.multiSelectAction = "forEach";
|
||||||
else if (command.name == "transposeletters")
|
else if (command.name == "transposeletters")
|
||||||
command.multiSelectAction = function(editor) {editor.transposeSelections(1); }
|
command.multiSelectAction = function(editor) {editor.transposeSelections(1); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// commands to enter multiselect mode
|
// commands to enter multiselect mode
|
||||||
|
|
@ -64,37 +64,47 @@ exports.defaultCommands = [{
|
||||||
name: "addCursorAbove",
|
name: "addCursorAbove",
|
||||||
exec: function(editor) { editor.selectMoreLines(-1); },
|
exec: function(editor) { editor.selectMoreLines(-1); },
|
||||||
bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
|
bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
|
||||||
readonly: true
|
readonly: true
|
||||||
}, {
|
}, {
|
||||||
name: "addCursorBelow",
|
name: "addCursorBelow",
|
||||||
exec: function(editor) { editor.selectMoreLines(1); },
|
exec: function(editor) { editor.selectMoreLines(1); },
|
||||||
bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
|
bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
|
||||||
readonly: true
|
readonly: true
|
||||||
|
}, {
|
||||||
|
name: "addCursorAboveSkipCurrent",
|
||||||
|
exec: function(editor) { editor.selectMoreLines(-1, true); },
|
||||||
|
bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"},
|
||||||
|
readonly: true
|
||||||
|
}, {
|
||||||
|
name: "addCursorBelowSkipCurrent",
|
||||||
|
exec: function(editor) { editor.selectMoreLines(1, true); },
|
||||||
|
bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"},
|
||||||
|
readonly: true
|
||||||
}, {
|
}, {
|
||||||
name: "selectMoreBefore",
|
name: "selectMoreBefore",
|
||||||
exec: function(editor) { editor.selectMore(-1); },
|
exec: function(editor) { editor.selectMore(-1); },
|
||||||
bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"},
|
bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"},
|
||||||
readonly: true
|
readonly: true
|
||||||
}, {
|
}, {
|
||||||
name: "selectMoreAfter",
|
name: "selectMoreAfter",
|
||||||
exec: function(editor) { editor.selectMore(1); },
|
exec: function(editor) { editor.selectMore(1); },
|
||||||
bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"},
|
bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"},
|
||||||
readonly: true
|
readonly: true
|
||||||
}, {
|
}, {
|
||||||
name: "selectNextBefore",
|
name: "selectNextBefore",
|
||||||
exec: function(editor) { editor.selectMore(-1, true); },
|
exec: function(editor) { editor.selectMore(-1, true); },
|
||||||
bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"},
|
bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"},
|
||||||
readonly: true
|
readonly: true
|
||||||
}, {
|
}, {
|
||||||
name: "selectNextAfter",
|
name: "selectNextAfter",
|
||||||
exec: function(editor) { editor.selectMore(1, true); },
|
exec: function(editor) { editor.selectMore(1, true); },
|
||||||
bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"},
|
bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"},
|
||||||
readonly: true
|
readonly: true
|
||||||
}, {
|
}, {
|
||||||
name: "splitIntoLines",
|
name: "splitIntoLines",
|
||||||
exec: function(editor) { editor.multiSelect.splitIntoLines(); },
|
exec: function(editor) { editor.multiSelect.splitIntoLines(); },
|
||||||
bindKey: {win: "Ctrl-Shift-L", mac: "Ctrl-Shift-L"},
|
bindKey: {win: "Ctrl-Shift-L", mac: "Ctrl-Shift-L"},
|
||||||
readonly: true
|
readonly: true
|
||||||
}, ];
|
}, ];
|
||||||
|
|
||||||
// commands active in multiselect mode
|
// commands active in multiselect mode
|
||||||
|
|
@ -102,7 +112,7 @@ exports.multiEditCommands = [{
|
||||||
name: "singleSelection",
|
name: "singleSelection",
|
||||||
bindKey: "esc",
|
bindKey: "esc",
|
||||||
exec: function(editor) { editor.exitMultiSelectMode(); },
|
exec: function(editor) { editor.exitMultiSelectMode(); },
|
||||||
readonly: true
|
readonly: true
|
||||||
}];
|
}];
|
||||||
|
|
||||||
var HashHandler = require("../keyboard/hash_handler").HashHandler;
|
var HashHandler = require("../keyboard/hash_handler").HashHandler;
|
||||||
|
|
|
||||||
|
|
@ -50,11 +50,11 @@ function onMouseDown(e) {
|
||||||
var ev = e.domEvent;
|
var ev = e.domEvent;
|
||||||
var alt = ev.altKey;
|
var alt = ev.altKey;
|
||||||
var shift = ev.shiftKey;
|
var shift = ev.shiftKey;
|
||||||
var ctrl = ev.ctrlKey;
|
var ctrl = e.getAccelKey();
|
||||||
var button = e.getButton();
|
var button = e.getButton();
|
||||||
|
|
||||||
if (!ctrl && !alt) {
|
if (!ctrl && !alt) {
|
||||||
if (e.editor.selection.rangeCount > 1) {
|
if (e.editor.inMultiSelectMode) {
|
||||||
if (button == 0) {
|
if (button == 0) {
|
||||||
e.editor.exitMultiSelectMode();
|
e.editor.exitMultiSelectMode();
|
||||||
} else if (button == 2) {
|
} else if (button == 2) {
|
||||||
|
|
@ -70,12 +70,71 @@ function onMouseDown(e) {
|
||||||
|
|
||||||
var editor = e.editor;
|
var editor = e.editor;
|
||||||
var selection = editor.selection;
|
var selection = editor.selection;
|
||||||
var isMultiSelect = selection.rangeCount > 1
|
var isMultiSelect = editor.inMultiSelectMode;
|
||||||
var pos = e.getDocumentPosition();
|
var pos = e.getDocumentPosition();
|
||||||
var rangeList = selection.rangeList;
|
|
||||||
var cursor = selection.getCursor()
|
var cursor = selection.getCursor()
|
||||||
var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
|
var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
|
||||||
|
|
||||||
|
|
||||||
|
var mouseX = e.pageX, mouseY = e.pageY;
|
||||||
|
var clickX = mouseX, clickY = mouseY;
|
||||||
|
var onMouseSelection = function(e) {
|
||||||
|
mouseX = event.getDocumentX(e);
|
||||||
|
mouseY = event.getDocumentY(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
var blockSelect = function() {
|
||||||
|
var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
|
||||||
|
var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column);
|
||||||
|
|
||||||
|
if (isSamePoint(screenCursor, newCursor)
|
||||||
|
&& isSamePoint(cursor, selection.selectionLead))
|
||||||
|
return;
|
||||||
|
screenCursor = newCursor;
|
||||||
|
|
||||||
|
editor.selection.moveCursorToPosition(cursor);
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
editor.renderer.scrollCursorIntoView();
|
||||||
|
|
||||||
|
editor.removeSelectionMarkers(rectSel);
|
||||||
|
rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
|
||||||
|
rectSel.forEach(editor.addSelectionMarker, editor);
|
||||||
|
editor.updateSelectionMarkers()
|
||||||
|
};
|
||||||
|
|
||||||
|
var normalSelect = function() {
|
||||||
|
var clickSelection
|
||||||
|
if (_self.$clickSelection) {
|
||||||
|
if (_self.$clickSelection.contains(cursor.row, cursor.column)) {
|
||||||
|
editor.selection.setSelectionRange(_self.$clickSelection);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (_self.$clickSelection.compare(cursor.row, cursor.column) == -1) {
|
||||||
|
anchor = _self.$clickSelection.end;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
anchor = _self.$clickSelection.start;
|
||||||
|
}
|
||||||
|
editor.selection.setSelectionAnchor(anchor.row, anchor.column);
|
||||||
|
editor.selection.selectToPosition(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
editor.selection.selectToPosition(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.renderer.scrollCursorIntoView();
|
||||||
|
};
|
||||||
|
|
||||||
|
var session = editor.session;
|
||||||
|
var anchor = selection.getCursor();
|
||||||
|
var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
|
||||||
|
var clippedAnchor = session.documentToScreenPosition(anchor);
|
||||||
|
var screenCursor = screenAnchor;
|
||||||
|
|
||||||
|
|
||||||
|
onSelectionInterval = blockSelect;
|
||||||
|
|
||||||
if (ctrl && !shift && !alt && button == 0) {
|
if (ctrl && !shift && !alt && button == 0) {
|
||||||
if (!isMultiSelect && inSelection)
|
if (!isMultiSelect && inSelection)
|
||||||
return // dragging
|
return // dragging
|
||||||
|
|
@ -86,23 +145,23 @@ function onMouseDown(e) {
|
||||||
if (inSelection)
|
if (inSelection)
|
||||||
selection.clearSelection();
|
selection.clearSelection();
|
||||||
|
|
||||||
var helper = selection.toOrientedRange();
|
var helper = selection.toOrientedRange();
|
||||||
editor.addSelectionMarker(helper);
|
editor.addSelectionMarker(helper);
|
||||||
|
|
||||||
var oldRange = rangeList.rangeAtPoint(pos);
|
var oldRange = selection.rangeList.rangeAtPoint(pos);
|
||||||
|
|
||||||
event.capture(editor.container, function(){}, function() {
|
event.capture(editor.container, function(){}, function() {
|
||||||
editor.removeSelectionMarkers([helper]);
|
editor.removeSelectionMarkers([helper]);
|
||||||
var tmpSel = selection.toOrientedRange();
|
var tmpSel = selection.toOrientedRange();
|
||||||
|
|
||||||
if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor)) {
|
if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor)) {
|
||||||
if (selection.rangeCount > 1) {
|
if (selection.rangeCount > 1) {
|
||||||
range = editor.selection.rangeList.substractPoint(tmpSel.cursor);
|
editor.selection.substractPoint(tmpSel.cursor);
|
||||||
var range = editor.selection.rangeList.all[0];
|
var range = editor.selection.ranges[0];
|
||||||
if (range)
|
if (range)
|
||||||
editor.selection.addRange(range);
|
editor.selection.addRange(range);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selection.addRange(tmpSel);
|
selection.addRange(tmpSel);
|
||||||
|
|
@ -111,20 +170,18 @@ function onMouseDown(e) {
|
||||||
//e.stop()
|
//e.stop()
|
||||||
} else if (!shift && alt && button == 0) {
|
} else if (!shift && alt && button == 0) {
|
||||||
e.stop()
|
e.stop()
|
||||||
var mouseX = e.pageX, mouseY = e.pageY;
|
|
||||||
var onMouseSelection = function(e) {
|
|
||||||
mouseX = event.getDocumentX(e);
|
|
||||||
mouseY = event.getDocumentY(e);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isMultiSelect && !ctrl) {
|
|
||||||
selection.single();
|
if (isMultiSelect && !ctrl) {
|
||||||
|
selection.toSingleRange();
|
||||||
|
} else if (!isMultiSelect && ctrl) {
|
||||||
|
selection.addRange();
|
||||||
}
|
}
|
||||||
selection.moveCursorToPosition(pos);
|
|
||||||
selection.clearSelection();
|
selection.moveCursorToPosition(pos);
|
||||||
|
selection.clearSelection();
|
||||||
|
|
||||||
var rectSel = [];
|
var rectSel = [];
|
||||||
var session = editor.session;
|
|
||||||
|
|
||||||
var onMouseSelectionEnd = function(e) {
|
var onMouseSelectionEnd = function(e) {
|
||||||
clearInterval(timerId);
|
clearInterval(timerId);
|
||||||
|
|
@ -133,34 +190,12 @@ function onMouseDown(e) {
|
||||||
selection.addRange(rectSel[i])
|
selection.addRange(rectSel[i])
|
||||||
};
|
};
|
||||||
|
|
||||||
var anchor = selection.getCursor();
|
|
||||||
var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
|
|
||||||
var clippedAnchor = session.documentToScreenPosition(anchor);
|
|
||||||
var screenCursor = screenAnchor;
|
|
||||||
|
|
||||||
var onSelectionInterval = function() {
|
|
||||||
var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
|
|
||||||
var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column);
|
|
||||||
|
|
||||||
if (isSamePoint(screenCursor, newCursor)
|
|
||||||
&& isSamePoint(cursor, selection.selectionLead))
|
|
||||||
return;
|
|
||||||
screenCursor = newCursor;
|
|
||||||
|
|
||||||
editor.selection.moveCursorToPosition(cursor);
|
|
||||||
editor.selection.clearSelection();
|
|
||||||
editor.renderer.scrollCursorIntoView();
|
|
||||||
|
|
||||||
editor.removeSelectionMarkers(rectSel);
|
|
||||||
rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
|
|
||||||
rectSel.forEach(editor.addSelectionMarker, editor);
|
|
||||||
|
|
||||||
editor.renderer.updateCursor();
|
|
||||||
editor.renderer.updateBackMarkers();
|
|
||||||
};
|
|
||||||
|
|
||||||
event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
|
event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
|
||||||
var timerId = setInterval(onSelectionInterval, 20);
|
var timerId = setInterval(function() {onSelectionInterval()}, 20);
|
||||||
|
|
||||||
return e.preventDefault();
|
return e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ define(function(require, exports, module) {
|
||||||
var RangeList = require("./range_list").RangeList;
|
var RangeList = require("./range_list").RangeList;
|
||||||
var Range = require("./range").Range;
|
var Range = require("./range").Range;
|
||||||
var Selection = require("./selection").Selection;
|
var Selection = require("./selection").Selection;
|
||||||
var onMouseDown = require("./mouse/multi_select_mouse_handler").onMouseDown;
|
var onMouseDown = require("./mouse/multi_select_handler").onMouseDown;
|
||||||
exports.commands = require("./commands/multi_select_commands");
|
exports.commands = require("./commands/multi_select_commands");
|
||||||
|
|
||||||
// Todo
|
// Todo
|
||||||
|
|
@ -49,292 +49,330 @@ var Search = require("ace/search").Search
|
||||||
var search = new Search
|
var search = new Search
|
||||||
|
|
||||||
function find(session, needle, dir) {
|
function find(session, needle, dir) {
|
||||||
search.$options.wrap = true;
|
search.$options.wrap = true;
|
||||||
search.$options.needle = needle;
|
search.$options.needle = needle;
|
||||||
search.$options.backwards = dir == -1;
|
search.$options.backwards = dir == -1;
|
||||||
return search.find(session)
|
return search.find(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
// extend EditSession
|
// extend EditSession
|
||||||
var EditSession = require("./edit_session").EditSession;
|
var EditSession = require("./edit_session").EditSession;
|
||||||
;(function() {
|
;(function() {
|
||||||
this.getSelectionMarkers = function() {
|
this.getSelectionMarkers = function() {
|
||||||
return this.$selectionMarkers;
|
return this.$selectionMarkers;
|
||||||
};
|
};
|
||||||
}).call(EditSession.prototype);
|
}).call(EditSession.prototype);
|
||||||
|
|
||||||
// extend Selection
|
// extend Selection
|
||||||
;(function() {
|
;(function() {
|
||||||
this.addRange = function(range) {
|
// list of ranges in reverse addition order
|
||||||
if (!range.cursor)
|
this.ranges = null;
|
||||||
range.cursor = range.end;
|
// automatically sorted list of ranges
|
||||||
|
this.rangeList = null;
|
||||||
if (this.rangeCount == 0) {
|
|
||||||
var oldRange = this.toOrientedRange();
|
|
||||||
this.rangeList.add(oldRange);
|
|
||||||
this._emit("addRange", {range: oldRange});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.rangeList.add(range);
|
/**
|
||||||
this.rangeCount = this.rangeList.ranges.length;
|
* add a range to selection entering multiselect mode if necessary
|
||||||
|
*/
|
||||||
if (this.rangeCount > 1 && !this.inMultiSelectMode) {
|
this.addRange = function(range) {
|
||||||
this._emit("multiSelect");
|
if (!this.inMultiSelectMode && this.rangeCount == 0) {
|
||||||
this.inMultiSelectMode = true;
|
var oldRange = this.toOrientedRange();
|
||||||
this.$undoSelect = false;
|
if (!range || !range.isEqual(oldRange)) {
|
||||||
this.rangeList.attach(this.session);
|
this.rangeList.add(oldRange);
|
||||||
}
|
this.$onAddRange(oldRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.fromOrientedRange(range);
|
if (!range)
|
||||||
if (this.rangeCount >= 1)
|
return;
|
||||||
this._emit("addRange", {range: range});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.single = function(range) {
|
if (!range.cursor)
|
||||||
range = range || this.rangeList.all[0];
|
range.cursor = range.end;
|
||||||
this.rangeList.removeAll();
|
|
||||||
range && this.fromOrientedRange(range);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$onRemoveRange = function(e) {
|
var removed = this.rangeList.add(range);
|
||||||
this.rangeCount = this.rangeList.ranges.length;
|
|
||||||
this._emit("removeRange", e);
|
|
||||||
|
|
||||||
if (this.rangeCount <= 1 && this.inMultiSelectMode) {
|
this.fromOrientedRange(range);
|
||||||
this.inMultiSelectMode = false;
|
this.$onAddRange(range);
|
||||||
this._emit("singleSelect");
|
|
||||||
this.$undoSelect = true;
|
|
||||||
this.rangeList.detach(this.session);
|
|
||||||
|
|
||||||
if (this.rangeCount == 1)
|
if (removed.length)
|
||||||
this.single();
|
this.$onRemoveRange(removed);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// adds multicursor support to selection
|
if (this.rangeCount > 0 && !this.inMultiSelectMode) {
|
||||||
this.$initRangeList = function() {
|
this._emit("multiSelect");
|
||||||
if (this.rangeList)
|
this.inMultiSelectMode = true;
|
||||||
return;
|
this.session.$undoSelect = false;
|
||||||
|
this.rangeList.attach(this.session);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var rangeList = new RangeList;
|
this.toSingleRange = function(range) {
|
||||||
// list of ranges in reverse addition order
|
range = range || this.ranges[0];
|
||||||
// rangeList.all[0] is the same as selection.getRange
|
var removed = this.rangeList.removeAll();
|
||||||
rangeList.all = [];
|
if (removed.length)
|
||||||
rangeList.on("add", function(e) {
|
this.$onRemoveRange(removed);
|
||||||
rangeList.all.unshift(e.range)
|
|
||||||
})
|
|
||||||
rangeList.on("remove", function(e) {
|
|
||||||
var ranges = e.ranges
|
|
||||||
for (var i = ranges.length; i--; ) {
|
|
||||||
var index = rangeList.all.indexOf(ranges[i]);
|
|
||||||
rangeList.all.splice(index, 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.rangeList = rangeList;
|
range && this.fromOrientedRange(range);
|
||||||
this.cursor = this.selectionLead;
|
};
|
||||||
|
|
||||||
this.rangeCount = 1;
|
this.substractPoint = function(pos) {
|
||||||
this.rangeList.on("remove", this.$onRemoveRange.bind(this));
|
var removed = this.rangeList.substractPoint(pos);
|
||||||
};
|
if (removed) {
|
||||||
this.getAllRanges = function() {
|
this.$onRemoveRange(removed);
|
||||||
return this.rangeList.ranges.concat()
|
return removed[0]
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.splitIntoLines = function () {
|
this.mergeOverlappingRanges = function() {
|
||||||
if (this.rangeCount > 1) {
|
var removed = this.rangeList.merge();
|
||||||
var ranges = this.rangeList.ranges;
|
var lastRange = this.ranges[0];
|
||||||
var lastRange = ranges[ranges.length - 1]
|
if (removed.length)
|
||||||
var range = Range.fromPoints(ranges[0].start, lastRange.end)
|
this.$onRemoveRange(removed);
|
||||||
|
|
||||||
this.single()
|
if (lastRange)
|
||||||
this.setSelectionRange(range, lastRange.cursor == lastRange.start)
|
this.fromOrientedRange(lastRange);
|
||||||
} else {
|
};
|
||||||
var cursor = this.session.documentToScreenPosition(this.selectionLead);
|
|
||||||
var anchor = this.session.documentToScreenPosition(this.selectionAnchor);
|
|
||||||
|
|
||||||
var rectSel = this.rectangularRangeBlock(cursor, anchor);
|
|
||||||
rectSel.forEach(this.addRange, this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {
|
|
||||||
var rectSel = [];
|
|
||||||
|
|
||||||
var xBackwards = screenCursor.column < screenAnchor.column;
|
this.$onAddRange = function(range) {
|
||||||
if (xBackwards) {
|
this.rangeCount = this.rangeList.ranges.length;
|
||||||
var startColumn = screenCursor.column;
|
this.ranges.unshift(range);
|
||||||
var endColumn = screenAnchor.column;
|
this._emit("addRange", {range: range});
|
||||||
} else {
|
};
|
||||||
var startColumn = screenAnchor.column;
|
|
||||||
var endColumn = screenCursor.column;
|
|
||||||
}
|
|
||||||
|
|
||||||
var yBackwards = screenCursor.row < screenAnchor.row;
|
|
||||||
if (yBackwards) {
|
|
||||||
var startRow = screenCursor.row;
|
|
||||||
var endRow = screenAnchor.row;
|
|
||||||
} else {
|
|
||||||
var startRow = screenAnchor.row;
|
|
||||||
var endRow = screenCursor.row;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startColumn < 0)
|
|
||||||
startColumn = 0;
|
|
||||||
if (startRow < 0)
|
|
||||||
startRow = 0;
|
|
||||||
|
|
||||||
if (startRow == endRow)
|
this.$onRemoveRange = function(removed) {
|
||||||
includeEmptyLines = true;
|
this.rangeCount = this.rangeList.ranges.length;
|
||||||
|
if (this.rangeCount == 1 && this.inMultiSelectMode) {
|
||||||
for (var row = startRow; row <= endRow; row++) {
|
removed.push(this.rangeList.ranges.pop());
|
||||||
var range = Range.fromPoints(
|
this.rangeCount = 0;
|
||||||
this.session.screenToDocumentPosition(row, startColumn),
|
}
|
||||||
this.session.screenToDocumentPosition(row, endColumn)
|
|
||||||
);
|
for (var i = removed.length; i--; ) {
|
||||||
if (range.isEmpty()) {
|
var index = this.ranges.indexOf(removed[i]);
|
||||||
if (docEnd && isSamePoint(range.end, docEnd))
|
this.ranges.splice(index, 1);
|
||||||
break;
|
}
|
||||||
var docEnd = range.end;
|
|
||||||
}
|
console.log(this.ranges+'')
|
||||||
range.cursor = xBackwards ? range.start : range.end;
|
this._emit("removeRange", {ranges: removed});
|
||||||
rectSel.push(range);
|
|
||||||
}
|
if (this.rangeCount == 0 && this.inMultiSelectMode) {
|
||||||
if (yBackwards)
|
this.inMultiSelectMode = false;
|
||||||
rectSel.reverse();
|
this._emit("singleSelect");
|
||||||
|
this.session.$undoSelect = true;
|
||||||
if (!includeEmptyLines) {
|
this.rangeList.detach(this.session);
|
||||||
var end = rectSel.length - 1;
|
}
|
||||||
while (rectSel[end].isEmpty() && end > 0)
|
};
|
||||||
end--;
|
|
||||||
if (end > 0) {
|
// adds multicursor support to selection
|
||||||
var start = 0;
|
this.$initRangeList = function() {
|
||||||
while (rectSel[start].isEmpty())
|
if (this.rangeList)
|
||||||
start++;
|
return;
|
||||||
}
|
|
||||||
for (var i = end; i >= start; i--) {
|
this.rangeList = new RangeList;
|
||||||
if (rectSel[i].isEmpty())
|
this.ranges = [];
|
||||||
rectSel.splice(i, 1);
|
this.rangeCount = 0;
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
this.getAllRanges = function() {
|
||||||
return rectSel;
|
return this.rangeList.ranges.concat()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.splitIntoLines = function () {
|
||||||
|
if (this.rangeCount > 1) {
|
||||||
|
var ranges = this.rangeList.ranges;
|
||||||
|
var lastRange = ranges[ranges.length - 1]
|
||||||
|
var range = Range.fromPoints(ranges[0].start, lastRange.end)
|
||||||
|
|
||||||
|
this.toSingleRange()
|
||||||
|
this.setSelectionRange(range, lastRange.cursor == lastRange.start)
|
||||||
|
} else {
|
||||||
|
var cursor = this.session.documentToScreenPosition(this.selectionLead);
|
||||||
|
var anchor = this.session.documentToScreenPosition(this.selectionAnchor);
|
||||||
|
|
||||||
|
var rectSel = this.rectangularRangeBlock(cursor, anchor);
|
||||||
|
rectSel.forEach(this.addRange, this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets list of ranges composing rectangular block on the screen
|
||||||
|
* @includeEmptyLines if true includes ranges inside the block which
|
||||||
|
* are empty becuase of the clipping
|
||||||
|
*/
|
||||||
|
this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {
|
||||||
|
var rectSel = [];
|
||||||
|
|
||||||
|
var xBackwards = screenCursor.column < screenAnchor.column;
|
||||||
|
if (xBackwards) {
|
||||||
|
var startColumn = screenCursor.column;
|
||||||
|
var endColumn = screenAnchor.column;
|
||||||
|
} else {
|
||||||
|
var startColumn = screenAnchor.column;
|
||||||
|
var endColumn = screenCursor.column;
|
||||||
|
}
|
||||||
|
|
||||||
|
var yBackwards = screenCursor.row < screenAnchor.row;
|
||||||
|
if (yBackwards) {
|
||||||
|
var startRow = screenCursor.row;
|
||||||
|
var endRow = screenAnchor.row;
|
||||||
|
} else {
|
||||||
|
var startRow = screenAnchor.row;
|
||||||
|
var endRow = screenCursor.row;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startColumn < 0)
|
||||||
|
startColumn = 0;
|
||||||
|
if (startRow < 0)
|
||||||
|
startRow = 0;
|
||||||
|
|
||||||
|
if (startRow == endRow)
|
||||||
|
includeEmptyLines = true;
|
||||||
|
|
||||||
|
for (var row = startRow; row <= endRow; row++) {
|
||||||
|
var range = Range.fromPoints(
|
||||||
|
this.session.screenToDocumentPosition(row, startColumn),
|
||||||
|
this.session.screenToDocumentPosition(row, endColumn)
|
||||||
|
);
|
||||||
|
if (range.isEmpty()) {
|
||||||
|
if (docEnd && isSamePoint(range.end, docEnd))
|
||||||
|
break;
|
||||||
|
var docEnd = range.end;
|
||||||
|
}
|
||||||
|
range.cursor = xBackwards ? range.start : range.end;
|
||||||
|
rectSel.push(range);
|
||||||
|
}
|
||||||
|
if (yBackwards)
|
||||||
|
rectSel.reverse();
|
||||||
|
|
||||||
|
if (!includeEmptyLines) {
|
||||||
|
var end = rectSel.length - 1;
|
||||||
|
while (rectSel[end].isEmpty() && end > 0)
|
||||||
|
end--;
|
||||||
|
if (end > 0) {
|
||||||
|
var start = 0;
|
||||||
|
while (rectSel[start].isEmpty())
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
for (var i = end; i >= start; i--) {
|
||||||
|
if (rectSel[i].isEmpty())
|
||||||
|
rectSel.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rectSel;
|
||||||
|
};
|
||||||
}).call(Selection.prototype);
|
}).call(Selection.prototype);
|
||||||
|
|
||||||
// extend Editor
|
// extend Editor
|
||||||
var Editor = require("./editor").Editor;
|
var Editor = require("./editor").Editor;
|
||||||
;(function() {
|
;(function() {
|
||||||
this.addSelectionMarker = function(orientedRange) {
|
this.updateSelectionMarkers = function(orientedRange) {
|
||||||
if (!orientedRange.cursor)
|
this.renderer.updateCursor();
|
||||||
orientedRange.cursor = orientedRange.end;
|
this.renderer.updateBackMarkers();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addSelectionMarker = function(orientedRange) {
|
||||||
|
if (!orientedRange.cursor)
|
||||||
|
orientedRange.cursor = orientedRange.end;
|
||||||
|
|
||||||
var style = this.getSelectionStyle();
|
var style = this.getSelectionStyle();
|
||||||
orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style);
|
orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style);
|
||||||
|
|
||||||
this.session.$selectionMarkers.push(orientedRange);
|
this.session.$selectionMarkers.push(orientedRange);
|
||||||
this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
|
this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
|
||||||
return orientedRange
|
return orientedRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.removeSelectionMarkers = function(ranges) {
|
this.removeSelectionMarkers = function(ranges) {
|
||||||
for (var i = ranges.length; i--; ) {
|
for (var i = ranges.length; i--; ) {
|
||||||
var range = ranges[i];
|
var range = ranges[i];
|
||||||
if (!range.marker)
|
if (!range.marker)
|
||||||
continue;
|
continue;
|
||||||
this.session.removeMarker(range.marker);
|
this.session.removeMarker(range.marker);
|
||||||
var index = this.session.$selectionMarkers.indexOf(range);
|
var index = this.session.$selectionMarkers.indexOf(range);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
this.session.$selectionMarkers.splice(index, 1)
|
this.session.$selectionMarkers.splice(index, 1)
|
||||||
}
|
}
|
||||||
this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
|
this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$onAddRange = function(e) {
|
this.$onAddRange = function(e) {
|
||||||
this.addSelectionMarker(e.range);
|
this.addSelectionMarker(e.range);
|
||||||
this.renderer.updateCursor();
|
this.renderer.updateCursor();
|
||||||
this.renderer.updateBackMarkers();
|
this.renderer.updateBackMarkers();
|
||||||
};
|
};
|
||||||
this.$onRemoveRange = function(e) {
|
this.$onRemoveRange = function(e) {
|
||||||
this.removeSelectionMarkers(e.ranges);
|
this.removeSelectionMarkers(e.ranges);
|
||||||
this.renderer.updateCursor();
|
this.renderer.updateCursor();
|
||||||
this.renderer.updateBackMarkers();
|
this.renderer.updateBackMarkers();
|
||||||
};
|
};
|
||||||
this.$onMultiSelect = function(e) {
|
this.$onMultiSelect = function(e) {
|
||||||
if (this.inMultiSelectMode)
|
if (this.inMultiSelectMode)
|
||||||
return;
|
return;
|
||||||
this.inMultiSelectMode = true;
|
this.inMultiSelectMode = true;
|
||||||
|
|
||||||
this.setStyle("multiselect");
|
this.setStyle("multiselect");
|
||||||
this.keyBinding.addKeyboardHandler(exports.commands.keyboardHandler);
|
this.keyBinding.addKeyboardHandler(exports.commands.keyboardHandler);
|
||||||
// FixMe
|
// FixMe
|
||||||
this.commands.__SingleSelectionExec = this.commands.exec;
|
this.commands.__SingleSelectionExec = this.commands.exec;
|
||||||
this.commands.exec = exports.exec;
|
this.commands.exec = exports.exec;
|
||||||
this.renderer.updateCursor();
|
this.renderer.updateCursor();
|
||||||
this.renderer.updateBackMarkers();
|
this.renderer.updateBackMarkers();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$onSingleSelect = function(e) {
|
this.$onSingleSelect = function(e) {
|
||||||
if (this.session.multiSelect.inVirtualMode)
|
if (this.session.multiSelect.inVirtualMode)
|
||||||
return;
|
return;
|
||||||
this.inMultiSelectMode = false;
|
this.inMultiSelectMode = false;
|
||||||
|
|
||||||
this.unsetStyle("multiselect");
|
this.unsetStyle("multiselect");
|
||||||
this.keyBinding.removeKeyboardHandler(exports.commands.keyboardHandler);
|
this.keyBinding.removeKeyboardHandler(exports.commands.keyboardHandler);
|
||||||
|
|
||||||
this.commands.exec = this.commands.__SingleSelectionExec;
|
this.commands.exec = this.commands.__SingleSelectionExec;
|
||||||
this.renderer.updateCursor();
|
this.renderer.updateCursor();
|
||||||
this.renderer.updateBackMarkers();
|
this.renderer.updateBackMarkers();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.forEachSelection = function(cmd, args) {
|
this.forEachSelection = function(cmd, args) {
|
||||||
if (this.inVirtualSelectionMode)
|
if (this.inVirtualSelectionMode)
|
||||||
return;
|
return;
|
||||||
var session = this.session
|
var session = this.session
|
||||||
var selection = this.selection
|
var selection = this.selection
|
||||||
var rangeList = selection.rangeList
|
var rangeList = selection.rangeList
|
||||||
|
|
||||||
var reg = selection._eventRegistry;
|
var reg = selection._eventRegistry;
|
||||||
selection._eventRegistry = {};
|
selection._eventRegistry = {};
|
||||||
|
|
||||||
var tmpSel = new Selection(session);
|
var tmpSel = new Selection(session);
|
||||||
this.inVirtualSelectionMode = true;
|
this.inVirtualSelectionMode = true;
|
||||||
for (var i = rangeList.ranges.length; i--;) {
|
for (var i = rangeList.ranges.length; i--;) {
|
||||||
tmpSel.fromOrientedRange(rangeList.ranges[i]);
|
tmpSel.fromOrientedRange(rangeList.ranges[i]);
|
||||||
this.selection = session.selection = tmpSel;
|
this.selection = session.selection = tmpSel;
|
||||||
cmd.exec(this, args || {});
|
cmd.exec(this, args || {});
|
||||||
tmpSel.toOrientedRange(rangeList.ranges[i]);
|
tmpSel.toOrientedRange(rangeList.ranges[i]);
|
||||||
}
|
}
|
||||||
tmpSel.detach();
|
tmpSel.detach();
|
||||||
|
|
||||||
this.selection = session.selection = selection;
|
this.selection = session.selection = selection;
|
||||||
this.inVirtualSelectionMode = false;
|
this.inVirtualSelectionMode = false;
|
||||||
selection._eventRegistry = reg;
|
selection._eventRegistry = reg;
|
||||||
rangeList.merge();
|
selection.mergeOverlappingRanges();
|
||||||
|
|
||||||
var lastRange = selection.rangeList.all[0]
|
this.onCursorChange();
|
||||||
lastRange && selection.fromOrientedRange(lastRange);
|
this.onSelectionChange();
|
||||||
|
};
|
||||||
|
|
||||||
selection._emit("changeSelection")
|
this.exitMultiSelectMode = function() {
|
||||||
selection._emit("changeCursor")
|
if (this.inVirtualSelectionMode)
|
||||||
this.renderer.updateCursor();
|
return;
|
||||||
this.renderer.updateBackMarkers();
|
this.multiSelect.toSingleRange();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.exitMultiSelectMode = function() {
|
// todo route copy/cut/paste through commandmanager
|
||||||
if (this.inVirtualSelectionMode)
|
this.getCopyText = function() {
|
||||||
return;
|
|
||||||
this.multiSelect.single();
|
|
||||||
};
|
|
||||||
|
|
||||||
// todo route copy/cut/paste through commandmanager
|
|
||||||
this.getCopyText = function() {
|
|
||||||
var text = "";
|
var text = "";
|
||||||
if (this.inMultiSelectMode) {
|
if (this.inMultiSelectMode) {
|
||||||
var ranges = this.multiSelect.rangeList.ranges;
|
var ranges = this.multiSelect.rangeList.ranges;
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
text += this.session.getTextRange(ranges[i]);
|
text += this.session.getTextRange(ranges[i]);
|
||||||
}
|
}
|
||||||
} else if (!this.selection.isEmpty())
|
} else if (!this.selection.isEmpty())
|
||||||
text = this.session.getTextRange(this.getSelectionRange());
|
text = this.session.getTextRange(this.getSelectionRange());
|
||||||
|
|
||||||
|
|
@ -342,120 +380,121 @@ var Editor = require("./editor").Editor;
|
||||||
return text;
|
return text;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onCut = function() {
|
this.onCut = function() {
|
||||||
var cmd = {
|
var cmd = {
|
||||||
name: "cut",
|
name: "cut",
|
||||||
exec: function(editor) {
|
exec: function(editor) {
|
||||||
var range = editor.getSelectionRange();
|
var range = editor.getSelectionRange();
|
||||||
editor._emit("cut", range);
|
editor._emit("cut", range);
|
||||||
|
|
||||||
if (!editor.selection.isEmpty()) {
|
if (!editor.selection.isEmpty()) {
|
||||||
editor.session.remove(range);
|
editor.session.remove(range);
|
||||||
editor.clearSelection();
|
editor.clearSelection();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
readonly: true,
|
readonly: true,
|
||||||
multiSelectAction: "forEach"
|
multiSelectAction: "forEach"
|
||||||
}
|
}
|
||||||
this.commands.exec(cmd, this)
|
this.commands.exec(cmd, this)
|
||||||
};
|
};
|
||||||
|
|
||||||
// commands
|
// commands
|
||||||
|
|
||||||
this.selectMoreLines = function(dir, skip) {
|
this.selectMoreLines = function(dir, skip) {
|
||||||
var range = this.selection.toOrientedRange();
|
var range = this.selection.toOrientedRange();
|
||||||
var isBackwards = range.cursor == range.end;
|
var isBackwards = range.cursor == range.end;
|
||||||
|
|
||||||
var screenLead = this.session.documentToScreenPosition(range.cursor);
|
var screenLead = this.session.documentToScreenPosition(range.cursor);
|
||||||
if (this.selection.$desiredColumn)
|
if (this.selection.$desiredColumn)
|
||||||
screenLead.column = this.selection.$desiredColumn;
|
screenLead.column = this.selection.$desiredColumn;
|
||||||
|
|
||||||
var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);
|
var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);
|
||||||
|
|
||||||
if (!range.isEmpty()) {
|
if (!range.isEmpty()) {
|
||||||
var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);
|
var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);
|
||||||
var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);
|
var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);
|
||||||
} else {
|
} else {
|
||||||
var anchor = lead;
|
var anchor = lead;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBackwards) {
|
if (isBackwards) {
|
||||||
var newRange = Range.fromPoints(lead, anchor);
|
var newRange = Range.fromPoints(lead, anchor);
|
||||||
newRange.cursor = newRange.start;
|
newRange.cursor = newRange.start;
|
||||||
} else {
|
} else {
|
||||||
var newRange = Range.fromPoints(anchor, lead);
|
var newRange = Range.fromPoints(anchor, lead);
|
||||||
newRange.cursor = newRange.end;
|
newRange.cursor = newRange.end;
|
||||||
}
|
}
|
||||||
|
|
||||||
newRange.desiredColumn = screenLead.column;
|
newRange.desiredColumn = screenLead.column;
|
||||||
if (!this.selection.inMultiSelectMode) {
|
if (!this.selection.inMultiSelectMode) {
|
||||||
this.selection.addRange(range);
|
this.selection.addRange(range);
|
||||||
} else {
|
} else {
|
||||||
var allRanges = this.selection.rangeList.ranges;
|
var allRanges = this.selection.rangeList.ranges;
|
||||||
// remove range if at end
|
// remove range if at end
|
||||||
if (skip || range.isEequal(allRanges[dir == 1 ? 0 : allRanges.length - 1]))
|
// var atEdge = range.isEqual(allRanges[dir == 1 ? 0 : allRanges.length - 1]);
|
||||||
var toRemove = range.cursor;
|
if (skip)
|
||||||
}
|
var toRemove = range.cursor;
|
||||||
|
}
|
||||||
|
|
||||||
this.selection.addRange(newRange);
|
this.selection.addRange(newRange);
|
||||||
if (toRemove)
|
if (toRemove)
|
||||||
this.selection.rangeList.substractPoint(toRemove);
|
this.selection.substractPoint(toRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.transposeSelections = function(dir) {
|
this.transposeSelections = function(dir) {
|
||||||
var session = this.session;
|
var session = this.session;
|
||||||
var sel = session.multiSelect;
|
var sel = session.multiSelect;
|
||||||
var all = sel.rangeList.all;
|
var all = sel.ranges;
|
||||||
|
|
||||||
var words = [];
|
var words = [];
|
||||||
for (var i = all.length; i--; ) {
|
for (var i = all.length; i--; ) {
|
||||||
var range = all[i]
|
var range = all[i]
|
||||||
if (range.isEmpty()) {
|
if (range.isEmpty()) {
|
||||||
var tmp = session.getWordRange(range.start.row, range.start.column)
|
var tmp = session.getWordRange(range.start.row, range.start.column)
|
||||||
range.start.row = tmp.start.row;
|
range.start.row = tmp.start.row;
|
||||||
range.start.column = tmp.start.column;
|
range.start.column = tmp.start.column;
|
||||||
range.end.row = tmp.end.row;
|
range.end.row = tmp.end.row;
|
||||||
range.end.column = tmp.end.column;
|
range.end.column = tmp.end.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
words.unshift(this.session.getTextRange(range));
|
words.unshift(this.session.getTextRange(range));
|
||||||
}
|
}
|
||||||
if (dir < 0)
|
if (dir < 0)
|
||||||
words.unshift(words.pop());
|
words.unshift(words.pop());
|
||||||
else
|
else
|
||||||
words.push(words.shift());
|
words.push(words.shift());
|
||||||
|
|
||||||
for (var i = all.length; i--; ) {
|
for (var i = all.length; i--; ) {
|
||||||
var range = all[i];
|
var range = all[i];
|
||||||
var tmp = range.clone();
|
var tmp = range.clone();
|
||||||
session.replace(range, words[i]);
|
session.replace(range, words[i]);
|
||||||
range.start.row = tmp.start.row;
|
range.start.row = tmp.start.row;
|
||||||
range.start.column = tmp.start.column;
|
range.start.column = tmp.start.column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selectMore = function (dir, skip) {
|
this.selectMore = function (dir, skip) {
|
||||||
var session = this.session;
|
var session = this.session;
|
||||||
var sel = session.multiSelect;
|
var sel = session.multiSelect;
|
||||||
var all = sel.rangeList.all;
|
var all = sel.ranges;
|
||||||
|
|
||||||
var range = sel.toOrientedRange();
|
var range = sel.toOrientedRange();
|
||||||
if (range.isEmpty()) {
|
if (range.isEmpty()) {
|
||||||
var range = session.getWordRange(range.start.row, range.start.column)
|
var range = session.getWordRange(range.start.row, range.start.column)
|
||||||
range.cursor = range.end;
|
range.cursor = range.end;
|
||||||
this.multiSelect.addRange(range);
|
this.multiSelect.addRange(range);
|
||||||
}
|
}
|
||||||
var needle = session.getTextRange(range);
|
var needle = session.getTextRange(range);
|
||||||
|
|
||||||
|
|
||||||
var newRange = find(session, needle, dir);
|
var newRange = find(session, needle, dir);
|
||||||
if (newRange) {
|
if (newRange) {
|
||||||
newRange.cursor = dir == -1 ? newRange.start : newRange.end;
|
newRange.cursor = dir == -1 ? newRange.start : newRange.end;
|
||||||
this.multiSelect.addRange(newRange);
|
this.multiSelect.addRange(newRange);
|
||||||
}
|
}
|
||||||
if (skip)
|
if (skip)
|
||||||
this.multiSelect.rangeList.substractPoint(range.cursor);
|
this.multiSelect.substractPoint(range.cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}).call(Editor.prototype);
|
}).call(Editor.prototype);
|
||||||
|
|
@ -476,11 +515,11 @@ exports.exec = function(command, editor, args) {
|
||||||
} else if (command.multiSelectAction == "forEach") {
|
} else if (command.multiSelectAction == "forEach") {
|
||||||
editor.forEachSelection(command, args);
|
editor.forEachSelection(command, args);
|
||||||
} else if (command.multiSelectAction == "single") {
|
} else if (command.multiSelectAction == "single") {
|
||||||
editor.exitMultiSelectMode();
|
editor.exitMultiSelectMode();
|
||||||
command.exec(editor, args || {});
|
command.exec(editor, args || {});
|
||||||
} else {
|
} else {
|
||||||
command.multiSelectAction(editor, args || {});
|
command.multiSelectAction(editor, args || {});
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -494,45 +533,47 @@ function isSamePoint(p1, p2) {
|
||||||
// patch
|
// patch
|
||||||
// adds multicursor support to a session
|
// adds multicursor support to a session
|
||||||
exports.onSessionChange = function(e) {
|
exports.onSessionChange = function(e) {
|
||||||
var session = e.session;
|
var session = e.session;
|
||||||
if (!session.multiSelect) {
|
if (!session.multiSelect) {
|
||||||
session.$selectionMarkers = [];
|
session.$selectionMarkers = [];
|
||||||
session.selection.$initRangeList();
|
session.selection.$initRangeList();
|
||||||
session.multiSelect = session.selection;
|
session.multiSelect = session.selection;
|
||||||
}
|
}
|
||||||
this.multiSelect = session.multiSelect;
|
this.multiSelect = session.multiSelect;
|
||||||
|
|
||||||
var oldSession = e.oldSession;
|
var oldSession = e.oldSession;
|
||||||
if (oldSession) {
|
if (oldSession) {
|
||||||
// todo use events
|
// todo use events
|
||||||
if (oldSession.multiSelect && oldSession.multiSelect.editor == this)
|
if (oldSession.multiSelect && oldSession.multiSelect.editor == this)
|
||||||
oldSession.multiSelect.editor = null;
|
oldSession.multiSelect.editor = null;
|
||||||
|
|
||||||
session.multiSelect.removeEventListener("addRange", this.$onAddRange);
|
session.multiSelect.removeEventListener("addRange", this.$onAddRange);
|
||||||
session.multiSelect.removeEventListener("removeRange", this.$onRemoveRange);
|
session.multiSelect.removeEventListener("removeRange", this.$onRemoveRange);
|
||||||
session.multiSelect.removeEventListener("multiSelect", this.$onMultiSelect);
|
session.multiSelect.removeEventListener("multiSelect", this.$onMultiSelect);
|
||||||
session.multiSelect.removeEventListener("singleSelect", this.$onSingleSelect);
|
session.multiSelect.removeEventListener("singleSelect", this.$onSingleSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
session.multiSelect.on("addRange", this.$onAddRange);
|
session.multiSelect.on("addRange", this.$onAddRange);
|
||||||
session.multiSelect.on("removeRange", this.$onRemoveRange);
|
session.multiSelect.on("removeRange", this.$onRemoveRange);
|
||||||
session.multiSelect.on("multiSelect", this.$onMultiSelect);
|
session.multiSelect.on("multiSelect", this.$onMultiSelect);
|
||||||
session.multiSelect.on("singleSelect", this.$onSingleSelect);
|
session.multiSelect.on("singleSelect", this.$onSingleSelect);
|
||||||
|
|
||||||
if (this.inMultiSelectMode != session.selection.inMultiSelectMode) {
|
// this.$onSelectionChange = this.onSelectionChange.bind(this);
|
||||||
if (session.selection.inMultiSelectMode)
|
|
||||||
this.$onMultiSelect();
|
if (this.inMultiSelectMode != session.selection.inMultiSelectMode) {
|
||||||
else
|
if (session.selection.inMultiSelectMode)
|
||||||
this.$onSingleSelect();
|
this.$onMultiSelect();
|
||||||
}
|
else
|
||||||
|
this.$onSingleSelect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds multicursor support to editor instance
|
// adds multicursor support to editor instance
|
||||||
function MultiSelect(editor) {
|
function MultiSelect(editor) {
|
||||||
editor.$onAddRange = editor.$onAddRange.bind(editor);
|
editor.$onAddRange = editor.$onAddRange.bind(editor);
|
||||||
editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
|
editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
|
||||||
editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
|
editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
|
||||||
editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
|
editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
|
||||||
|
|
||||||
exports.onSessionChange.call(editor, editor);
|
exports.onSessionChange.call(editor, editor);
|
||||||
editor.on("changeSession", exports.onSessionChange.bind(editor));
|
editor.on("changeSession", exports.onSessionChange.bind(editor));
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,6 @@ var RangeList = function(startRow, startColumn, endRow, endColumn) {
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
oop.implement(this, EventEmitter);
|
|
||||||
|
|
||||||
this.comparePoints = function(p1, p2) {
|
this.comparePoints = function(p1, p2) {
|
||||||
return p1.row - p2.row || p1.column - p2.column
|
return p1.row - p2.row || p1.column - p2.column
|
||||||
};
|
};
|
||||||
|
|
@ -84,25 +82,22 @@ var RangeList = function(startRow, startColumn, endRow, endColumn) {
|
||||||
else
|
else
|
||||||
endIndex++;
|
endIndex++;
|
||||||
|
|
||||||
var removed = this.ranges.splice(startIndex, endIndex - startIndex, range);
|
return this.ranges.splice(startIndex, endIndex - startIndex, range);
|
||||||
if (removed.length)
|
|
||||||
this._emit("remove", {ranges: removed});
|
|
||||||
this._emit("add", {range: range});
|
|
||||||
return startIndex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.addList = function(list) {
|
this.addList = function(list) {
|
||||||
list.forEach(this.add, this);
|
var removed = [];
|
||||||
|
for (var i = list.length; i--; ) {
|
||||||
|
removed.push.call(removed, this.add(list[i]))
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.substractPoint = function(pos) {
|
this.substractPoint = function(pos) {
|
||||||
var i = this.pointIndex(pos);
|
var i = this.pointIndex(pos);
|
||||||
|
|
||||||
if (i >= 0) {
|
if (i >= 0)
|
||||||
var removed = this.ranges.splice(i, 1);
|
return this.ranges.splice(i, 1);
|
||||||
this._emit("remove", {ranges: removed});
|
|
||||||
return removed[0]
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// merge overlapping ranges
|
// merge overlapping ranges
|
||||||
|
|
@ -131,8 +126,7 @@ var RangeList = function(startRow, startColumn, endRow, endColumn) {
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removed.length)
|
return removed;
|
||||||
this._emit("remove", {ranges: removed});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.contains = function(row, column) {
|
this.contains = function(row, column) {
|
||||||
|
|
@ -170,8 +164,7 @@ var RangeList = function(startRow, startColumn, endRow, endColumn) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.removeAll = function() {
|
this.removeAll = function() {
|
||||||
if (this.ranges.length)
|
return this.ranges.splice(0, this.ranges.length);
|
||||||
this._emit("remove", {ranges: this.ranges.splice(0, this.ranges.length)});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.attach = function(session) {
|
this.attach = function(session) {
|
||||||
|
|
@ -193,45 +186,45 @@ var RangeList = function(startRow, startColumn, endRow, endColumn) {
|
||||||
|
|
||||||
this.$onChange = function(e) {
|
this.$onChange = function(e) {
|
||||||
var changeRange = e.data.range;
|
var changeRange = e.data.range;
|
||||||
if (e.data.action[0] == "i"){
|
if (e.data.action[0] == "i"){
|
||||||
var start = changeRange.start;
|
var start = changeRange.start;
|
||||||
var end = changeRange.end;
|
var end = changeRange.end;
|
||||||
} else {
|
} else {
|
||||||
var end = changeRange.start;
|
var end = changeRange.start;
|
||||||
var start = changeRange.end;
|
var start = changeRange.end;
|
||||||
}
|
}
|
||||||
var startRow = start.row;
|
var startRow = start.row;
|
||||||
var endRow = end.row;
|
var endRow = end.row;
|
||||||
var lineDif = endRow - startRow;
|
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 colDiff = -start.column + end.column;
|
||||||
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 ) {
|
var ranges = this.ranges;
|
||||||
r.start.column += colDiff;
|
|
||||||
r.start.row += lineDif;
|
for (var i=0, n = ranges.length; i < n; i++) {
|
||||||
}
|
var r = ranges[i];
|
||||||
if (r.end.row == startRow && r.end.column >= start.column) {
|
if (r.end.row < startRow)
|
||||||
r.end.column += colDiff;
|
continue;
|
||||||
r.end.row += lineDif;
|
if (r.start.row > startRow)
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
|
if (r.start.row == startRow && r.start.column >= start.column ) {
|
||||||
if (lineDif != 0 && i < n) {
|
r.start.column += colDiff;
|
||||||
for (; i < n; i++) {
|
r.start.row += lineDif;
|
||||||
var r = ranges[i];
|
}
|
||||||
r.start.row += lineDif;
|
if (r.end.row == startRow && r.end.column >= start.column) {
|
||||||
r.end.row += lineDif;
|
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);
|
}).call(RangeList.prototype);
|
||||||
|
|
|
||||||
|
|
@ -124,25 +124,24 @@ module.exports = {
|
||||||
new Range(8,8,9,9)
|
new Range(8,8,9,9)
|
||||||
]);
|
]);
|
||||||
var removed = [];
|
var removed = [];
|
||||||
rangeList.on('remove', function(e) {removed = e.ranges});
|
|
||||||
|
|
||||||
assert.equal(rangeList.ranges.length, 4);
|
assert.equal(rangeList.ranges.length, 4);
|
||||||
|
|
||||||
rangeList.ranges[1].end.row = 7;
|
rangeList.ranges[1].end.row = 7;
|
||||||
rangeList.merge();
|
removed = rangeList.merge();
|
||||||
assert.equal(removed.length, 1);
|
assert.equal(removed.length, 1);
|
||||||
assert.range(rangeList.ranges[1], 4,2,7,7);
|
assert.range(rangeList.ranges[1], 4,2,7,7);
|
||||||
assert.equal(rangeList.ranges.length, 3);
|
assert.equal(rangeList.ranges.length, 3);
|
||||||
|
|
||||||
rangeList.ranges[0].end.row = 10;
|
rangeList.ranges[0].end.row = 10;
|
||||||
rangeList.merge();
|
removed = rangeList.merge();
|
||||||
assert.range(rangeList.ranges[0], 1,2,10,4);
|
assert.range(rangeList.ranges[0], 1,2,10,4);
|
||||||
assert.equal(removed.length, 2);
|
assert.equal(removed.length, 2);
|
||||||
assert.equal(rangeList.ranges.length, 1);
|
assert.equal(rangeList.ranges.length, 1);
|
||||||
|
|
||||||
rangeList.ranges.push(new Range(10,10,10,10));
|
rangeList.ranges.push(new Range(10,10,10,10));
|
||||||
rangeList.ranges.push(new Range(10,10,10,10));
|
rangeList.ranges.push(new Range(10,10,10,10));
|
||||||
rangeList.merge();
|
removed = rangeList.merge();
|
||||||
assert.equal(rangeList.ranges.length, 2);
|
assert.equal(rangeList.ranges.length, 2);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue