fix handling of desiredcolumn

This commit is contained in:
nightwing 2012-03-25 12:15:33 +05:00
commit ec9ef6c843
2 changed files with 363 additions and 381 deletions

View file

@ -44,221 +44,178 @@ var Selection = require("./selection").Selection;
var Range = require("./range").Range; var Range = require("./range").Range;
var event = require("./lib/event"); var event = require("./lib/event");
function VirtualSelection(selection) {
this.session = selection.session;
this.doc = selection.doc;
this.clearSelection();
this.selectionLead = this.doc.createAnchor(0, 0);
this.selectionAnchor = this.doc.createAnchor(0, 0);
/*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)
}
this.toRange = function(r) {
var r1 = this.getRange()
r.start.column = r1.start.column
r.start.row = r1.start.row
r.end.column = r1.end.column
r.end.row = r1.end.row
r.cursor = this.isBackwards() ? r.start : r.end;
}
}
VirtualSelection.prototype = Selection.prototype;
function forEachSelection(editor, cmd, args) { function forEachSelection(editor, cmd, args) {
if (editor.session.multiSelection.inVirtualMode) if (editor.session.multiSelection.inVirtualMode)
return return
var session = editor.session var session = editor.session
var selection = editor.selection var selection = editor.selection
var rangeList = selection.rangeList var rangeList = selection.rangeList
var reg = selection._eventRegistry; var reg = selection._eventRegistry;
selection._eventRegistry = {}; selection._eventRegistry = {};
var sh = new VirtualSelection(selection) var sh = new Selection(session);
editor.session.multiSelection.inVirtualMode = true editor.session.multiSelection.inVirtualMode = true;
for (var i = rangeList.ranges.length; i--;) { for (var i = rangeList.ranges.length; i--;) {
sh.fromRange(rangeList.ranges[i]) sh.fromOrientedRange(rangeList.ranges[i])
editor.selection = session.selection = sh editor.selection = session.selection = sh
cmd.exec(editor, args || {}) cmd.exec(editor, args || {})
sh.toOrientedRange(rangeList.ranges[i])
sh.toRange(rangeList.ranges[i]) }
} sh.detach();
sh.detach();
rangeList.merge()
rangeList.merge() editor.selection = session.selection = selection;
editor.selection = session.selection = selection; editor.session.multiSelection.inVirtualMode = false;
editor.session.multiSelection.inVirtualMode = false; selection._eventRegistry = reg;
selection._eventRegistry = reg;
selection.fromOrientedRange(selection.rangeList.all[0])
selection.setSelectionRange(selection.rangeList.all[0]) editor.renderer.updateCursor();
editor.renderer.updateCursor(); editor.renderer.updateBackMarkers();
editor.renderer.updateBackMarkers();
if (selection.rangeCount == 1 && editor.inMultiSelectMode)
if (selection.rangeCount == 1 && editor.inMultiSelectMode) exitMultiSelectMode(editor)
exitMultiSelectMode(editor)
} }
function exec(command, editor, args) { function exec(command, editor, args) {
if (typeof command === 'string') if (typeof command === 'string')
command = this.commands[command]; command = this.commands[command];
if (!command) if (!command)
return false; return false;
if (editor && editor.$readOnly && !command.readOnly) if (editor && editor.$readOnly && !command.readOnly)
return false; return false;
if (/^(remove|insert|select|go|jumptomatching|del|backspace)/.test(command.name)) { if (/^(remove|insert|select|go|jumptomatching|del|backspace|to(?:upp|low)ercase)/.test(command.name)) {
forEachSelection(editor, command, args) forEachSelection(editor, command, args)
}else }else
command.exec(editor, args || {}); command.exec(editor, args || {});
return true; return true;
}; };
function enterMultiSelectMode(editor) { function enterMultiSelectMode(editor) {
if (editor.inMultiSelectMode) if (editor.inMultiSelectMode)
return return
editor.inMultiSelectMode = true editor.inMultiSelectMode = true
editor.setStyle("multiselect") editor.setStyle("multiselect")
editor.keyBinding.addKeyboardHandler(exports.keyboardHandler); editor.keyBinding.addKeyboardHandler(exports.keyboardHandler);
editor.commands.__exec = editor.commands.exec editor.commands.__exec = editor.commands.exec
editor.commands.exec = exec editor.commands.exec = exec
editor.session.$undoSelect = false editor.session.$undoSelect = false
editor.selection.rangeList.attach(editor.session); editor.selection.rangeList.attach(editor.session);
} }
function exitMultiSelectMode(editor) { function exitMultiSelectMode(editor) {
if (editor.session.multiSelection.inVirtualMode) if (editor.session.multiSelection.inVirtualMode)
return return
editor.inMultiSelectMode = false; editor.inMultiSelectMode = false;
editor.selection.secondarySelections = []; editor.selection.secondarySelections = [];
editor.unsetStyle("multiselect"); editor.unsetStyle("multiselect");
editor.selection.rangeList.removeAll(); editor.selection.rangeList.removeAll();
editor.keyBinding.removeKeyboardHandler(exports.keyboardHandler); editor.keyBinding.removeKeyboardHandler(exports.keyboardHandler);
editor.commands.exec = editor.commands.__exec; editor.commands.exec = editor.commands.__exec;
editor.renderer.updateCursor(); editor.renderer.updateCursor();
editor.renderer.updateBackMarkers(); editor.renderer.updateBackMarkers();
editor.session.$undoSelect = true editor.session.$undoSelect = true
editor.selection.rangeList.detach(editor.session); editor.selection.rangeList.detach(editor.session);
} }
function initSession(session) { function initSession(session) {
if (session.selection.rangeList) if (session.selection.rangeList)
return return
session.multiSelection = session.selection session.multiSelection = session.selection
var rangeList = new RangeList; var rangeList = new RangeList;
rangeList.all = []; rangeList.all = [];
rangeList.on("add", function(e) { rangeList.on("add", function(e) {
rangeList.all.unshift(e.range) rangeList.all.unshift(e.range)
}) })
rangeList.on("remove", function(e) { rangeList.on("remove", function(e) {
var ranges = e.ranges var ranges = e.ranges
for (var i = ranges.length; i--; ) { for (var i = ranges.length; i--; ) {
var index = rangeList.all.indexOf(ranges[i]); var index = rangeList.all.indexOf(ranges[i]);
rangeList.all.splice(index, 1); rangeList.all.splice(index, 1);
} }
}); });
session.selection.rangeList = rangeList; session.selection.rangeList = rangeList;
session.selection.cursor = session.selection.selectionLead; session.selection.cursor = session.selection.selectionLead;
session.selection.secondarySelections = []; session.selection.secondarySelections = [];
session.selection.getAllRanges = function() { session.selection.getAllRanges = function() {
return this.rangeList.ranges.concat(this.secondarySelections) return this.rangeList.ranges.concat(this.secondarySelections)
}; };
session.selection.rangeCount = 1; session.selection.rangeCount = 1;
} }
var addSelectionRange = function(editor, orientedRange) { var addSelectionRange = function(editor, orientedRange) {
if (!editor.inMultiSelectMode) if (!editor.inMultiSelectMode)
enterMultiSelectMode(editor) enterMultiSelectMode(editor)
if (!orientedRange.cursor)
orientedRange.cursor = orientedRange.end
var style = editor.getSelectionStyle(); if (!orientedRange.cursor)
orientedRange.marker = editor.session.addMarker(orientedRange, "ace_selection", style); orientedRange.cursor = orientedRange.end
// use this to not conflict with virtualSelections added by forEachSelection var style = editor.getSelectionStyle();
var selection = editor.session.multiSelection; orientedRange.marker = editor.session.addMarker(orientedRange, "ace_selection", style);
selection.rangeList.add(orientedRange);
selection.rangeCount = selection.rangeList.all.length + selection.secondarySelections.length; // use this to not conflict with virtualSelections added by forEachSelection
var selection = editor.session.multiSelection;
selection.setSelectionRange(orientedRange, orientedRange.cursor == orientedRange.start) selection.rangeList.add(orientedRange);
editor.renderer.updateCursor(); selection.rangeCount = selection.rangeList.all.length + selection.secondarySelections.length;
editor.renderer.updateBackMarkers();
selection.fromOrientedRange(orientedRange)
editor.renderer.updateCursor();
editor.renderer.updateBackMarkers();
}; };
function addCursorV(editor, dir){ function addCursorV(editor, dir){
var range = editor.selection.getRange() var range = editor.selection.getRange()
var isBackwards = editor.selection.isBackwards() var isBackwards = editor.selection.isBackwards()
range.cursor = isBackwards ? range.start : range.end; range.cursor = isBackwards ? range.start : range.end;
var screenLead = editor.session.documentToScreenPosition(range.cursor); var screenLead = editor.session.documentToScreenPosition(range.cursor);
var lead = editor.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column); screenLead.column = editor.selection.$desiredColumn;
if (!range.isEmpty()) { var lead = editor.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);
var screenAnchor = editor.session.documentToScreenPosition(isBackwards ? range.end : range.start);
var anchor = editor.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column); if (!range.isEmpty()) {
} else { var screenAnchor = editor.session.documentToScreenPosition(isBackwards ? range.end : range.start);
var anchor = lead var anchor = editor.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);
} } else {
var anchor = lead
if (isBackwards) { }
var newRange = Range.fromPoints(lead, anchor)
newRange.cursor = newRange.start if (isBackwards) {
} else { var newRange = Range.fromPoints(lead, anchor)
var newRange = Range.fromPoints(anchor, lead) newRange.cursor = newRange.start
newRange.cursor = newRange.end } else {
} var newRange = Range.fromPoints(anchor, lead)
if (!editor.inMultiSelectMode) { newRange.cursor = newRange.end
addSelectionRange(editor, range) }
} else { newRange.desiredColumn = editor.selection.$desiredColumn
var allRanges = editor.selection.rangeList.ranges if (!editor.inMultiSelectMode) {
// remove range if at end addSelectionRange(editor, range)
if (range.isEequal(allRanges[dir == 1 ? 0 : allRanges.length - 1])) } else {
var toRemove = range.cursor var allRanges = editor.selection.rangeList.ranges
} // remove range if at end
addSelectionRange(editor, newRange) if (range.isEequal(allRanges[dir == 1 ? 0 : allRanges.length - 1]))
if (toRemove) var toRemove = range.cursor
editor.selection.rangeList.substractPoint(toRemove) }
addSelectionRange(editor, newRange)
if (toRemove)
editor.selection.rangeList.substractPoint(toRemove)
} }
// commands // commands
exports.defaultCommands = [{ exports.defaultCommands = [{
name: "addCursorAbove", name: "addCursorAbove",
exec: function(editor) { exec: function(editor) {
addCursorV(editor, -1) addCursorV(editor, -1)
}, },
bindKey: { bindKey: {
win: "Alt-Shift-Up", win: "Alt-Shift-Up",
@ -267,7 +224,7 @@ exports.defaultCommands = [{
}, { }, {
name: "addCursorBelow", name: "addCursorBelow",
exec: function(editor) { exec: function(editor) {
addCursorV(editor, 1) addCursorV(editor, 1)
}, },
bindKey: { bindKey: {
win: "Alt-Shift-Down", win: "Alt-Shift-Down",
@ -279,7 +236,7 @@ exports.multiEditCommands = [{
name: "singleSelection", name: "singleSelection",
bindKey: "esc", bindKey: "esc",
exec: function(editor) { exec: function(editor) {
console.log(editor) console.log(editor)
exitMultiSelectMode(editor) exitMultiSelectMode(editor)
}, },
}]; }];
@ -289,208 +246,205 @@ exports.keyboardHandler = new HashHandler(exports.multiEditCommands);
// mouse // mouse
function isSamePoint(p1, p2) { function isSamePoint(p1, p2) {
return p1.row == p2.row && p1.column == p2.column return p1.row == p2.row && p1.column == p2.column
} }
function onMouseDown(e) { 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 = ev.ctrlKey;
var button = e.getButton(); var button = e.getButton();
if (!ctrl && !alt) {
if (e.editor.selection.rangeCount > 1) {
if (button == 0) {
exitMultiSelectMode(e.editor)
} else if (button == 2) {
var editor = e.editor;
var selectionEmpty = editor.selection.isEmpty()
editor.textInput.onContextMenu({x: e.clientX, y: e.clientY}, selectionEmpty);
event.capture(editor.container, function(){}, editor.textInput.onContextMenuClose);
e.stop();
}
}
return;
}
var editor = e.editor;
var selection = editor.selection;
var isMultiSelect = selection.rangeCount > 1
var pos = e.getDocumentPosition();
var rangeList = selection.rangeList;
var cursor = selection.getCursor()
var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
if (ctrl && !shift && !alt && button == 0) {
if (!isMultiSelect && inSelection)
return // dragging
if (!isMultiSelect) {
var tmpSel = selection.getRange();
tmpSel.cursor = selection.isBackwards() ? tmpSel.start : tmpSel.end;
addSelectionRange(editor, tmpSel)
}
if (inSelection)
selection.clearSelection();
selection.secondarySelections.push(selection)
selection.rangeCount++
var oldRange = rangeList.substractPoint(pos)
event.capture(editor.container, function(){}, function() {
var i = selection.secondarySelections.indexOf(selection);
if (i != -1) {
selection.rangeCount--
selection.secondarySelections.splice(i, 1);
}
var tmpSel = selection.getRange();
tmpSel.cursor = selection.isBackwards() ? tmpSel.start : tmpSel.end;
if (oldRange && oldRange.isEmpty() && tmpSel.isEequal(oldRange)) { if (!ctrl && !alt) {
var range = selection.rangeList.all[0] if (e.editor.selection.rangeCount > 1) {
editor.selection.rangeList._emit("remove", {ranges: []}) if (button == 0) {
selection.setSelectionRange(range, range.cursor == range.start) exitMultiSelectMode(e.editor)
selection._emit("changeSelection"); } else if (button == 2) {
selection._emit("changeCursor"); var editor = e.editor;
return; var selectionEmpty = editor.selection.isEmpty()
} editor.textInput.onContextMenu({x: e.clientX, y: e.clientY}, selectionEmpty);
event.capture(editor.container, function(){}, editor.textInput.onContextMenuClose);
e.stop();
}
}
return;
}
addSelectionRange(editor, tmpSel) var editor = e.editor;
}); var selection = editor.selection;
var isMultiSelect = selection.rangeCount > 1
var pos = e.getDocumentPosition();
var rangeList = selection.rangeList;
var cursor = selection.getCursor()
var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
//e.stop() if (ctrl && !shift && !alt && button == 0) {
} else if (!shift && alt && button == 0) { if (!isMultiSelect && inSelection)
e.stop() return // dragging
var mouseX = e.pageX, mouseY = e.pageY;
var onMouseSelection = function(e) {
mouseX = event.getDocumentX(e);
mouseY = event.getDocumentY(e);
};
selection.moveCursorToPosition(pos); if (!isMultiSelect) {
selection.clearSelection(); addSelectionRange(editor, selection.toOrientedRange())
if (!isMultiSelect) { }
enterMultiSelectMode(editor) if (inSelection)
selection.rangeCount = Infinity selection.clearSelection();
}
var rectSel = []
selection.secondarySelections = rectSel
var session = editor.session
var style = editor.getSelectionStyle();
function addMarker(range) {
range.marker = session.addMarker(range, "ace_selection", style);
}
function removeMarker(range) {
session.removeMarker(range.marker);
}
var onMouseSelectionEnd = function(e) {
clearInterval(timerId);
rectSel.forEach(removeMarker)
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();
var screenAnchor = session.documentToScreenPosition(anchor);
var screenCursor = screenAnchor
var screenLength = session.getScreenLength() - 1
var onSelectionInterval = function() {
var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
if (isSamePoint(screenCursor, newCursor))
return
rectSel.forEach(removeMarker)
rectSel.splice(0, rectSel.length)
screenCursor = newCursor
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 (endRow > screenLength)
endRow = screenLength
for (var row = startRow; row <= endRow; row++) {
var r = Range.fromPoints(
session.screenToDocumentPosition(row, startColumn),
session.screenToDocumentPosition(row, endColumn)
)
r.cursor = xBackwards ? r.start : r.end
rectSel.push(r)
}
rectSel.forEach(addMarker)
var lastIndex = yBackwards ? 0 : rectSel.length - 1
selection.moveCursorToPosition(rectSel[lastIndex].cursor);
selection.clearSelection()
editor.renderer.scrollCursorIntoView();
editor.renderer.updateCursor();
editor.renderer.updateBackMarkers();
};
event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
var timerId = setInterval(onSelectionInterval, 20);
return e.preventDefault(); selection.secondarySelections.push(selection)
} selection.rangeCount++
var oldRange = rangeList.substractPoint(pos)
event.capture(editor.container, function(){}, function() {
var i = selection.secondarySelections.indexOf(selection);
if (i != -1) {
selection.rangeCount--
selection.secondarySelections.splice(i, 1);
}
var tmpSel = selection.toOrientedRange();
if (oldRange && oldRange.isEmpty() && tmpSel.isEequal(oldRange)) {
var range = selection.rangeList.all[0]
editor.selection.rangeList._emit("remove", {ranges: []})
selection.setSelectionRange(range, range.cursor == range.start)
selection._emit("changeSelection");
selection._emit("changeCursor");
return;
}
addSelectionRange(editor, tmpSel)
});
//e.stop()
} else if (!shift && alt && button == 0) {
e.stop()
var mouseX = e.pageX, mouseY = e.pageY;
var onMouseSelection = function(e) {
mouseX = event.getDocumentX(e);
mouseY = event.getDocumentY(e);
};
selection.moveCursorToPosition(pos);
selection.clearSelection();
if (!isMultiSelect) {
enterMultiSelectMode(editor)
selection.rangeCount = Infinity
}
var rectSel = []
selection.secondarySelections = rectSel
var session = editor.session
var style = editor.getSelectionStyle();
function addMarker(range) {
range.marker = session.addMarker(range, "ace_selection", style);
}
function removeMarker(range) {
session.removeMarker(range.marker);
}
var onMouseSelectionEnd = function(e) {
clearInterval(timerId);
rectSel.forEach(removeMarker)
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();
var screenAnchor = session.documentToScreenPosition(anchor);
var screenCursor = screenAnchor
var screenLength = session.getScreenLength() - 1
var onSelectionInterval = function() {
var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
if (isSamePoint(screenCursor, newCursor))
return
rectSel.forEach(removeMarker)
rectSel.splice(0, rectSel.length)
screenCursor = newCursor
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 (endRow > screenLength)
endRow = screenLength
for (var row = startRow; row <= endRow; row++) {
var r = Range.fromPoints(
session.screenToDocumentPosition(row, startColumn),
session.screenToDocumentPosition(row, endColumn)
)
r.cursor = xBackwards ? r.start : r.end
rectSel.push(r)
}
rectSel.forEach(addMarker)
var lastIndex = yBackwards ? 0 : rectSel.length - 1
selection.moveCursorToPosition(rectSel[lastIndex].cursor);
selection.clearSelection()
editor.renderer.scrollCursorIntoView();
editor.renderer.updateCursor();
editor.renderer.updateBackMarkers();
};
event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
var timerId = setInterval(onSelectionInterval, 20);
return e.preventDefault();
}
} }
function altSelect(ev) { function altSelect(ev) {
} }
// MultiCursor // MultiCursor
function MultiCursor(editor) { function MultiCursor(editor) {
initSession(editor.session); initSession(editor.session);
editor.on("changeSession", function(e) { editor.on("changeSession", function(e) {
initSession(e.session) initSession(e.session)
}.bind(editor)); }.bind(editor));
editor.selection.rangeList.on("remove", function(e) { editor.selection.rangeList.on("remove", function(e) {
var ranges = e.ranges; var ranges = e.ranges;
for (var i = ranges.length; i--; ) { for (var i = ranges.length; i--; ) {
var range = ranges[i]; var range = ranges[i];
if (range.marker != null) if (range.marker != null)
this.session.removeMarker(range.marker); this.session.removeMarker(range.marker);
this.rangeCount --; this.rangeCount --;
} }
if (this.rangeCount == 1 && editor.inMultiSelectMode)
exitMultiSelectMode(editor)
}.bind(editor.selection));
if (this.rangeCount == 1 && editor.inMultiSelectMode)
exitMultiSelectMode(editor)
}.bind(editor.selection));
editor.on("mousedown", onMouseDown); editor.on("mousedown", onMouseDown);
editor.commands.addCommands(exports.defaultCommands); editor.commands.addCommands(exports.defaultCommands);
} }

View file

@ -392,14 +392,14 @@ var Selection = function(session) {
this.moveCursorTo(fold.end.row, fold.end.column); this.moveCursorTo(fold.end.row, fold.end.column);
return; return;
} }
// first skip space // first skip space
if (match = this.session.nonTokenRe.exec(rightOfCursor)) { if (match = this.session.nonTokenRe.exec(rightOfCursor)) {
column += this.session.nonTokenRe.lastIndex; column += this.session.nonTokenRe.lastIndex;
this.session.nonTokenRe.lastIndex = 0; this.session.nonTokenRe.lastIndex = 0;
rightOfCursor = line.substring(column); rightOfCursor = line.substring(column);
} }
// if at line end proceed with next line // if at line end proceed with next line
if (column >= line.length) { if (column >= line.length) {
this.moveCursorTo(row, line.length); this.moveCursorTo(row, line.length);
@ -408,7 +408,7 @@ var Selection = function(session) {
this.moveCursorWordRight(); this.moveCursorWordRight();
return; return;
} }
// advance to the end of the next token // advance to the end of the next token
if (match = this.session.tokenRe.exec(rightOfCursor)) { if (match = this.session.tokenRe.exec(rightOfCursor)) {
column += this.session.tokenRe.lastIndex; column += this.session.tokenRe.lastIndex;
@ -433,19 +433,19 @@ var Selection = function(session) {
if (str == null) { if (str == null) {
str = this.doc.getLine(row).substring(0, column) str = this.doc.getLine(row).substring(0, column)
} }
var leftOfCursor = lang.stringReverse(str); var leftOfCursor = lang.stringReverse(str);
var match; var match;
this.session.nonTokenRe.lastIndex = 0; this.session.nonTokenRe.lastIndex = 0;
this.session.tokenRe.lastIndex = 0; this.session.tokenRe.lastIndex = 0;
// skip whitespace // skip whitespace
if (match = this.session.nonTokenRe.exec(leftOfCursor)) { if (match = this.session.nonTokenRe.exec(leftOfCursor)) {
column -= this.session.nonTokenRe.lastIndex; column -= this.session.nonTokenRe.lastIndex;
leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex); leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);
this.session.nonTokenRe.lastIndex = 0; this.session.nonTokenRe.lastIndex = 0;
} }
// if at begin of the line proceed in line above // if at begin of the line proceed in line above
if (column <= 0) { if (column <= 0) {
this.moveCursorTo(row, 0); this.moveCursorTo(row, 0);
@ -504,6 +504,34 @@ var Selection = function(session) {
this.moveCursorTo(row, column, preventUpdateDesiredColumn); this.moveCursorTo(row, column, preventUpdateDesiredColumn);
}; };
// remove listeners from document
this.detach = function() {
this.selectionLead.detach();
this.selectionAnchor.detach();
this.session = this.doc = null;
}
this.fromOrientedRange = function(range) {
this.setSelectionRange(range, range.cursor == range.start);
this.$desiredColumn = range.desiredColumn || this.$desiredColumn;
}
this.toOrientedRange = function(range) {
var r = this.getRange();
if (range) {
range.start.column = r.start.column;
range.start.row = r.start.row;
range.end.column = r.end.column;
range.end.row = r.end.row;
} else {
range = r;
}
range.cursor = this.isBackwards() ? range.start : range.end;
range.desiredColumn = this.$desiredColumn;
return range;
}
}).call(Selection.prototype); }).call(Selection.prototype);
exports.Selection = Selection; exports.Selection = Selection;