refactor selection to use anchors
This commit is contained in:
parent
f9d3155f08
commit
b74a322c7d
2 changed files with 95 additions and 152 deletions
|
|
@ -578,8 +578,7 @@ var Editor =function(renderer, session) {
|
|||
if (range.start.row < range.end.row || range.start.column < range.end.column) {
|
||||
var rows = this.$getSelectedRows();
|
||||
var count = session.indentRows(rows.first, rows.last, "\t");
|
||||
|
||||
this.selection.shiftSelection(count);
|
||||
// TODO remove count from indent
|
||||
} else {
|
||||
var indentString;
|
||||
|
||||
|
|
@ -602,8 +601,8 @@ var Editor =function(renderer, session) {
|
|||
|
||||
var selection = this.session.getSelection();
|
||||
var range = this.session.outdentRows(selection.getRange());
|
||||
|
||||
selection.setSelectionRange(range, selection.isBackwards());
|
||||
// TODO remove range from outdent
|
||||
//selection.setSelectionRange(range, selection.isBackwards());
|
||||
};
|
||||
|
||||
this.toggleCommentLines = function() {
|
||||
|
|
@ -613,7 +612,7 @@ var Editor =function(renderer, session) {
|
|||
var state = this.bgTokenizer.getState(this.getCursorPosition().row);
|
||||
var rows = this.$getSelectedRows()
|
||||
var addedColumns = this.mode.toggleCommentLines(state, this.session, rows.first, rows.last);
|
||||
this.selection.shiftSelection(addedColumns);
|
||||
// TODO remove addedColumns
|
||||
};
|
||||
|
||||
this.removeLines = function() {
|
||||
|
|
@ -689,7 +688,6 @@ var Editor =function(renderer, session) {
|
|||
|
||||
this.onCompositionStart = function(text) {
|
||||
this.renderer.showComposition(this.getCursorPosition());
|
||||
//this.onTextInput(text);
|
||||
};
|
||||
|
||||
this.onCompositionUpdate = function(text) {
|
||||
|
|
@ -698,7 +696,6 @@ var Editor =function(renderer, session) {
|
|||
|
||||
this.onCompositionEnd = function() {
|
||||
this.renderer.hideComposition();
|
||||
//this.removeLeft();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -42,15 +42,27 @@ var oop = require("pilot/oop");
|
|||
var lang = require("pilot/lang");
|
||||
var EventEmitter = require("pilot/event_emitter").EventEmitter;
|
||||
var Range = require("ace/range").Range;
|
||||
var Anchor = require("ace/anchor").Anchor;
|
||||
|
||||
var Selection = function(doc) {
|
||||
this.doc = doc;
|
||||
var Selection = function(session) {
|
||||
this.session = session;
|
||||
this.doc = session.getDocument();
|
||||
|
||||
this.clearSelection();
|
||||
this.selectionLead = {
|
||||
row: 0,
|
||||
column: 0
|
||||
};
|
||||
this.selectionLead = new Anchor(this.doc, 0, 0);
|
||||
this.selectionAnchor = new Anchor(this.doc, 0, 0);
|
||||
|
||||
var _self = this;
|
||||
this.selectionLead.on("change", function() {
|
||||
_self._dispatchEvent("changeCursor");
|
||||
if (!_self.$isEmpty)
|
||||
_self._dispatchEvent("changeSelection");
|
||||
});
|
||||
|
||||
this.selectionAnchor.on("change", function() {
|
||||
if (!_self.$isEmpty)
|
||||
_self._dispatchEvent("changeSelection");
|
||||
});
|
||||
};
|
||||
|
||||
(function() {
|
||||
|
|
@ -58,9 +70,10 @@ var Selection = function(doc) {
|
|||
oop.implement(this, EventEmitter);
|
||||
|
||||
this.isEmpty = function() {
|
||||
return (!this.selectionAnchor ||
|
||||
(this.selectionAnchor.row == this.selectionLead.row &&
|
||||
this.selectionAnchor.column == this.selectionLead.column));
|
||||
return (this.$isEmpty || (
|
||||
this.selectionAnchor.row == this.selectionLead.row &&
|
||||
this.selectionAnchor.column == this.selectionLead.column
|
||||
));
|
||||
};
|
||||
|
||||
this.isMultiLine = function() {
|
||||
|
|
@ -72,37 +85,31 @@ var Selection = function(doc) {
|
|||
};
|
||||
|
||||
this.getCursor = function() {
|
||||
return this.selectionLead;
|
||||
return this.selectionLead.getPosition();
|
||||
};
|
||||
|
||||
this.setSelectionAnchor = function(row, column) {
|
||||
var anchor = this.$clipPositionToDocument(row, column);
|
||||
this.selectionAnchor.setPosition(row, column);
|
||||
|
||||
if (!this.selectionAnchor) {
|
||||
this.selectionAnchor = anchor;
|
||||
this._dispatchEvent("changeSelection", {});
|
||||
if (this.$isEmpty) {
|
||||
this.$isEmpty = false;
|
||||
this._dispatchEvent("changeSelection");
|
||||
}
|
||||
else if (this.selectionAnchor.row !== anchor.row || this.selectionAnchor.column !== anchor.column) {
|
||||
this.selectionAnchor = anchor;
|
||||
this._dispatchEvent("changeSelection", {});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.getSelectionAnchor = function() {
|
||||
if (this.selectionAnchor) {
|
||||
return this.$clone(this.selectionAnchor);
|
||||
} else {
|
||||
return this.$clone(this.selectionLead);
|
||||
}
|
||||
if (this.$isEmpty)
|
||||
return this.getSelectionLead()
|
||||
else
|
||||
return this.selectionAnchor.getPosition();
|
||||
};
|
||||
|
||||
this.getSelectionLead = function() {
|
||||
return this.$clone(this.selectionLead);
|
||||
return this.selectionLead.getPosition();
|
||||
};
|
||||
|
||||
this.shiftSelection = function(columns) {
|
||||
if (this.isEmpty()) {
|
||||
if (this.$isEmpty) {
|
||||
this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns);
|
||||
return;
|
||||
};
|
||||
|
|
@ -123,15 +130,18 @@ var Selection = function(doc) {
|
|||
};
|
||||
|
||||
this.isBackwards = function() {
|
||||
var anchor = this.selectionAnchor || this.selectionLead;
|
||||
var anchor = this.selectionAnchor;
|
||||
var lead = this.selectionLead;
|
||||
return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
|
||||
};
|
||||
|
||||
this.getRange = function() {
|
||||
var anchor = this.selectionAnchor || this.selectionLead;
|
||||
var anchor = this.selectionAnchor;
|
||||
var lead = this.selectionLead;
|
||||
|
||||
if (this.isEmpty())
|
||||
return Range.fromPoints(lead, lead);
|
||||
|
||||
if (this.isBackwards()) {
|
||||
return Range.fromPoints(lead, anchor);
|
||||
}
|
||||
|
|
@ -141,26 +151,17 @@ var Selection = function(doc) {
|
|||
};
|
||||
|
||||
this.clearSelection = function() {
|
||||
if (this.selectionAnchor) {
|
||||
this.selectionAnchor = null;
|
||||
this._dispatchEvent("changeSelection", {});
|
||||
if (!this.$isEmpty) {
|
||||
this.$isEmpty = true;
|
||||
this._dispatchEvent("changeSelection");
|
||||
}
|
||||
};
|
||||
|
||||
this.selectAll = function() {
|
||||
var lastRow = this.doc.getLength() - 1;
|
||||
this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length);
|
||||
|
||||
if (!this.selectionAnchor) {
|
||||
this.selectionAnchor = this.$clone(this.selectionLead);
|
||||
}
|
||||
|
||||
var cursor = {row:0, column:0};
|
||||
// only dispatch change if the cursor actually changed
|
||||
if (cursor.row !== this.selectionLead.row || cursor.column !== this.selectionLead.column) {
|
||||
this.selectionLead = cursor;
|
||||
this._dispatchEvent("changeSelection", {blockScrolling: true});
|
||||
}
|
||||
this.setSelectionLead(0, 0);
|
||||
// this._dispatchEvent("changeSelection", {blockScrolling: true});
|
||||
};
|
||||
|
||||
this.setSelectionRange = function(range, reverse) {
|
||||
|
|
@ -177,27 +178,16 @@ var Selection = function(doc) {
|
|||
this.$updateDesiredColumn = function() {
|
||||
var cursor = this.getCursor();
|
||||
if (cursor) {
|
||||
this.$desiredColumn = this.doc.documentToScreenColumn(cursor.row, cursor.column);
|
||||
this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column);
|
||||
}
|
||||
};
|
||||
|
||||
this.$moveSelection = function(mover) {
|
||||
var changed = false;
|
||||
var lead = this.selectionLead;
|
||||
if (this.$isEmpty)
|
||||
this.setSelectionAnchor(lead.row, lead.column);
|
||||
|
||||
if (!this.selectionAnchor) {
|
||||
changed = true;
|
||||
this.selectionAnchor = this.$clone(this.selectionLead);
|
||||
}
|
||||
|
||||
var cursor = this.$clone(this.selectionLead);
|
||||
mover.call(this);
|
||||
|
||||
if (cursor.row !== this.selectionLead.row || cursor.column !== this.selectionLead.column) {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
this._dispatchEvent("changeSelection", {});
|
||||
};
|
||||
|
||||
this.selectTo = function(row, column) {
|
||||
|
|
@ -253,15 +243,9 @@ var Selection = function(doc) {
|
|||
};
|
||||
|
||||
this.selectWord = function() {
|
||||
var cursor = this.selectionLead;
|
||||
var column = cursor.column;
|
||||
var range = this.doc.getWordRange(cursor.row, column);
|
||||
var cursor = this.getCursor();
|
||||
var range = this.session.getWordRange(cursor.row, cursor.column);
|
||||
this.setSelectionRange(range);
|
||||
|
||||
/*this.setSelectionAnchor(cursor.row, start);
|
||||
this.$moveSelection(function() {
|
||||
this.moveCursorTo(cursor.row, end);
|
||||
});*/
|
||||
};
|
||||
|
||||
this.selectLine = function() {
|
||||
|
|
@ -280,18 +264,16 @@ var Selection = function(doc) {
|
|||
};
|
||||
|
||||
this.moveCursorLeft = function() {
|
||||
if (this.selectionLead.column == 0) {
|
||||
var cursor = this.selectionLead.getPosition();
|
||||
if (cursor.column == 0) {
|
||||
// cursor is a line (start
|
||||
if (this.selectionLead.row > 0) {
|
||||
this.moveCursorTo(this.selectionLead.row - 1, this.doc
|
||||
.getLine(this.selectionLead.row - 1).length);
|
||||
if (cursor.row > 0) {
|
||||
this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var doc = this.doc;
|
||||
var tabSize = doc.getTabSize();
|
||||
var cursor = this.selectionLead;
|
||||
if (doc.isTabStop(cursor) && doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize)
|
||||
var tabSize = this.session.getTabSize();
|
||||
if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize)
|
||||
this.moveCursorBy(0, -tabSize);
|
||||
else
|
||||
this.moveCursorBy(0, -1);
|
||||
|
|
@ -305,10 +287,9 @@ var Selection = function(doc) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
var doc = this.doc;
|
||||
var tabSize = doc.getTabSize();
|
||||
var tabSize = this.session.getTabSize();
|
||||
var cursor = this.selectionLead;
|
||||
if (doc.isTabStop(cursor) && doc.getLine(cursor.row).slice(cursor.column, cursor.column+tabSize).split(" ").length-1 == tabSize)
|
||||
if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column, cursor.column+tabSize).split(" ").length-1 == tabSize)
|
||||
this.moveCursorBy(0, tabSize);
|
||||
else
|
||||
this.moveCursorBy(0, 1);
|
||||
|
|
@ -318,12 +299,12 @@ var Selection = function(doc) {
|
|||
this.moveCursorLineStart = function() {
|
||||
var row = this.selectionLead.row;
|
||||
var column = this.selectionLead.column;
|
||||
var screenRow = this.doc.documentToScreenRow(row, column);
|
||||
var firstRowColumn = this.doc.getScreenFirstRowColumn(screenRow);
|
||||
var screenRow = this.session.documentToScreenRow(row, column);
|
||||
var firstRowColumn = this.session.getScreenFirstRowColumn(screenRow);
|
||||
var beforeCursor = this.doc.getLine(row).slice(firstRowColumn, column);
|
||||
var leadingSpace = beforeCursor.match(/^\s*/);
|
||||
if (leadingSpace[0].length == 0) {
|
||||
var lastRowColumn = this.doc.getDocumentLastRowColumn(row, column);
|
||||
var lastRowColumn = this.session.getDocumentLastRowColumn(row, column);
|
||||
leadingSpace = this.doc.getLine(row).
|
||||
substring(firstRowColumn, lastRowColumn).
|
||||
match(/^\s*/);
|
||||
|
|
@ -336,9 +317,8 @@ var Selection = function(doc) {
|
|||
};
|
||||
|
||||
this.moveCursorLineEnd = function() {
|
||||
var selLead = this.selectionLead;
|
||||
this.moveCursorTo(selLead.row,
|
||||
this.doc.getDocumentLastRowColumn(selLead.row, selLead.column));
|
||||
var lead = this.selectionLead;
|
||||
this.moveCursorTo(lead.row, this.session.getDocumentLastRowColumn(lead.row, lead.column));
|
||||
};
|
||||
|
||||
this.moveCursorFileEnd = function() {
|
||||
|
|
@ -358,20 +338,20 @@ var Selection = function(doc) {
|
|||
var rightOfCursor = line.substring(column);
|
||||
|
||||
var match;
|
||||
this.doc.nonTokenRe.lastIndex = 0;
|
||||
this.doc.tokenRe.lastIndex = 0;
|
||||
this.session.nonTokenRe.lastIndex = 0;
|
||||
this.session.tokenRe.lastIndex = 0;
|
||||
|
||||
if (column == line.length) {
|
||||
this.moveCursorRight();
|
||||
return;
|
||||
}
|
||||
else if (match = this.doc.nonTokenRe.exec(rightOfCursor)) {
|
||||
column += this.doc.nonTokenRe.lastIndex;
|
||||
this.doc.nonTokenRe.lastIndex = 0;
|
||||
else if (match = this.session.nonTokenRe.exec(rightOfCursor)) {
|
||||
column += this.session.nonTokenRe.lastIndex;
|
||||
this.session.nonTokenRe.lastIndex = 0;
|
||||
}
|
||||
else if (match = this.doc.tokenRe.exec(rightOfCursor)) {
|
||||
column += this.doc.tokenRe.lastIndex;
|
||||
this.doc.tokenRe.lastIndex = 0;
|
||||
else if (match = this.session.tokenRe.exec(rightOfCursor)) {
|
||||
column += this.session.tokenRe.lastIndex;
|
||||
this.session.tokenRe.lastIndex = 0;
|
||||
}
|
||||
|
||||
this.moveCursorTo(row, column);
|
||||
|
|
@ -384,83 +364,49 @@ var Selection = function(doc) {
|
|||
var leftOfCursor = lang.stringReverse(line.substring(0, column));
|
||||
|
||||
var match;
|
||||
this.doc.nonTokenRe.lastIndex = 0;
|
||||
this.doc.tokenRe.lastIndex = 0;
|
||||
this.session.nonTokenRe.lastIndex = 0;
|
||||
this.session.tokenRe.lastIndex = 0;
|
||||
|
||||
if (column == 0) {
|
||||
this.moveCursorLeft();
|
||||
return;
|
||||
}
|
||||
else if (match = this.doc.nonTokenRe.exec(leftOfCursor)) {
|
||||
column -= this.doc.nonTokenRe.lastIndex;
|
||||
this.doc.nonTokenRe.lastIndex = 0;
|
||||
else if (match = this.session.nonTokenRe.exec(leftOfCursor)) {
|
||||
column -= this.session.nonTokenRe.lastIndex;
|
||||
this.session.nonTokenRe.lastIndex = 0;
|
||||
}
|
||||
else if (match = this.doc.tokenRe.exec(leftOfCursor)) {
|
||||
column -= this.doc.tokenRe.lastIndex;
|
||||
this.doc.tokenRe.lastIndex = 0;
|
||||
else if (match = this.session.tokenRe.exec(leftOfCursor)) {
|
||||
column -= this.session.tokenRe.lastIndex;
|
||||
this.session.tokenRe.lastIndex = 0;
|
||||
}
|
||||
|
||||
this.moveCursorTo(row, column);
|
||||
};
|
||||
|
||||
this.moveCursorBy = function(rows, chars) {
|
||||
if (this.doc.getUseWrapMode()) {
|
||||
var screenPos = this.doc.documentToScreenPosition(
|
||||
this.selectionLead.row, this.selectionLead.column);
|
||||
var screenCol =
|
||||
(chars == 0 && this.$desiredColumn) || screenPos.column;
|
||||
|
||||
var docPos = this.doc.screenToDocumentPosition(
|
||||
screenPos.row + rows, screenCol);
|
||||
if (this.session.getUseWrapMode()) {
|
||||
var screenPos = this.session.documentToScreenPosition(
|
||||
this.selectionLead.row,
|
||||
this.selectionLead.column
|
||||
);
|
||||
var screenCol = (chars == 0 && this.$desiredColumn) || screenPos.column;
|
||||
var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenCol);
|
||||
|
||||
this.moveCursorTo(docPos.row, docPos.column + chars, chars == 0);
|
||||
} else {
|
||||
var docColumn =
|
||||
(chars == 0 && this.$desiredColumn) || this.selectionLead.column;
|
||||
this.moveCursorTo(
|
||||
this.selectionLead.row + rows, docColumn + chars, chars == 0);
|
||||
var docColumn = (chars == 0 && this.$desiredColumn) || this.selectionLead.column;
|
||||
this.moveCursorTo(this.selectionLead.row + rows, docColumn + chars, chars == 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.moveCursorToPosition = function(position) {
|
||||
this.moveCursorTo(position.row, position.column);
|
||||
};
|
||||
|
||||
this.moveCursorTo = function(row, column, preventUpdateDesiredColumn) {
|
||||
var cursor = this.$clipPositionToDocument(row, column);
|
||||
|
||||
// only dispatch change if the cursor actually changed
|
||||
if (cursor.row !== this.selectionLead.row || cursor.column !== this.selectionLead.column) {
|
||||
this.selectionLead = cursor;
|
||||
!preventUpdateDesiredColumn && this.$updateDesiredColumn(column);
|
||||
this._dispatchEvent("changeCursor", { data: this.getCursor() });
|
||||
}
|
||||
};
|
||||
|
||||
this.$clipPositionToDocument = function(row, column) {
|
||||
var pos = {};
|
||||
|
||||
if (row >= this.doc.getLength()) {
|
||||
pos.row = Math.max(0, this.doc.getLength() - 1);
|
||||
pos.column = this.doc.getLine(pos.row).length;
|
||||
}
|
||||
else if (row < 0) {
|
||||
pos.row = 0;
|
||||
pos.column = 0;
|
||||
}
|
||||
else {
|
||||
pos.row = row;
|
||||
pos.column = Math.min(this.doc.getLine(pos.row).length,
|
||||
Math.max(0, column));
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
this.$clone = function(pos) {
|
||||
return {
|
||||
row: pos.row,
|
||||
column: pos.column
|
||||
};
|
||||
this.selectionLead.setPosition(row, column);
|
||||
if (!preventUpdateDesiredColumn)
|
||||
this.$updateDesiredColumn(column);
|
||||
};
|
||||
|
||||
}).call(Selection.prototype);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue