Merge branch 'anchor'

This commit is contained in:
Fabian Jakobs 2011-02-11 11:57:23 +01:00
commit 8683abd9af
17 changed files with 267 additions and 292 deletions

View file

@ -127,6 +127,26 @@ exports.launch = function(env) {
var container = document.getElementById("editor"); var container = document.getElementById("editor");
env.editor = new Editor(new Renderer(container, theme)); env.editor = new Editor(new Renderer(container, theme));
var Anchor = require("ace/anchor").Anchor;
var Range = require("ace/range").Range;
var anchorStart = new Anchor(docs.js, 2, 8);
var anchorEnd = new Anchor(docs.js, 2, 13);
var marker;
function updateFloat() {
if (marker)
env.editor.renderer.removeMarker(marker);
var range = Range.fromPoints(
anchorStart.getPosition(),
anchorEnd.getPosition()
);
marker = env.editor.renderer.addMarker(range, "cool", "text");
};
updateFloat();
anchorStart.on("change", updateFloat);
anchorEnd.on("change", updateFloat);
var modes = { var modes = {
text: new TextMode(), text: new TextMode(),
xml: new XmlMode(), xml: new XmlMode(),

View file

@ -15,6 +15,12 @@ body {
color: white; color: white;
} }
#editor .cool {
position: absolute;
z-index: 4;
background: orange;
}
#editor { #editor {
position: absolute; position: absolute;
top: 60px; top: 60px;

View file

@ -46,11 +46,14 @@ var EventEmitter = require("pilot/event_emitter").EventEmitter;
*/ */
var Anchor = exports.Anchor = function(doc, row, column) { var Anchor = exports.Anchor = function(doc, row, column) {
this.document = doc; this.document = doc;
this.pos = {
row: row, if (typeof column == "undefined")
column: column this.setPosition(row.row, row.column)
}; else
doc.on("change", this.onChange.bind(this)); this.setPosition(row, column);
this.$onChange = this.onChange.bind(this);
doc.on("change", this.$onChange);
}; };
(function() { (function() {
@ -58,10 +61,7 @@ var Anchor = exports.Anchor = function(doc, row, column) {
oop.implement(this, EventEmitter); oop.implement(this, EventEmitter);
this.getPosition = function() { this.getPosition = function() {
return { return this.$clipPositionToDocument(this.row, this.column);
row: this.pos.row,
column: this.pos.column
};
}; };
this.getDocument = function() { this.getDocument = function() {
@ -72,80 +72,103 @@ var Anchor = exports.Anchor = function(doc, row, column) {
var delta = e.data; var delta = e.data;
var range = delta.range; var range = delta.range;
if (range.start.row == range.end.row && range.start.row != this.pos.row) if (range.start.row == range.end.row && range.start.row != this.row)
return; return;
if (range.start.row > this.pos.row) if (range.start.row > this.row)
return; return;
if (range.start.row == this.pos.row && range.start.column > this.pos.column) if (range.start.row == this.row && range.start.column > this.column)
return; return;
var pos = this.getPosition(); var row = this.row;
var column = this.column;
if (delta.action === "insertText") { if (delta.action === "insertText") {
if (range.start.row === pos.row && range.start.column <= pos.column) { if (range.start.row === row && range.start.column <= column) {
if (range.start.row === range.end.row) { if (range.start.row === range.end.row) {
pos.column += range.end.column - range.start.column; column += range.end.column - range.start.column;
} }
else { else {
pos.column -= range.start.column; column -= range.start.column;
pos.row += range.end.row - range.start.row; row += range.end.row - range.start.row;
} }
} }
else if (range.start.row !== range.end.row && range.start.row < pos.row) { else if (range.start.row !== range.end.row && range.start.row < row) {
pos.row += range.end.row - range.start.row; row += range.end.row - range.start.row;
} }
} else if (delta.action === "insertLines") { } else if (delta.action === "insertLines") {
if (range.start.row <= pos.row) { if (range.start.row <= row) {
pos.row += range.end.row - range.start.row; row += range.end.row - range.start.row;
} }
} }
else if (delta.action == "removeText") { else if (delta.action == "removeText") {
if (range.start.row == pos.row && range.start.column < pos.column) { if (range.start.row == row && range.start.column < column) {
if (range.end.column >= pos.column) if (range.end.column >= column)
pos.column = range.start.column; column = range.start.column;
else else
pos.column = Math.max(0, pos.column - (range.end.column - range.start.column)); column = Math.max(0, column - (range.end.column - range.start.column));
} else if (range.start.row !== range.end.row && range.start.row < pos.row) { } else if (range.start.row !== range.end.row && range.start.row < row) {
if (range.end.row == pos.row) { if (range.end.row == row) {
pos.column = Math.max(0, pos.column - range.end.column) + range.start.column; column = Math.max(0, column - range.end.column) + range.start.column;
} }
pos.row -= (range.end.row - range.start.row); row -= (range.end.row - range.start.row);
} }
else if (range.end.row == pos.row) { else if (range.end.row == row) {
pos.row -= range.end.row - range.start.row; row -= range.end.row - range.start.row;
pos.column = Math.max(0, pos.column - range.end.column) + range.start.column; column = Math.max(0, column - range.end.column) + range.start.column;
} }
} else if (delta.action == "removeLines") { } else if (delta.action == "removeLines") {
if (range.start.row <= pos.row) { if (range.start.row <= row) {
if (range.end.row <= pos.row) if (range.end.row <= row)
pos.row -= range.end.row - range.start.row; row -= range.end.row - range.start.row;
else { else {
pos.row = range.start.row; row = range.start.row;
pos.column = 0; column = 0;
} }
} }
} }
// clip this.setPosition(row, column);
var len = this.document.getLength();
if (pos.row > len) {
pos.row = len - 1;
pos.column = this.document.getLine(len-1).length;
}
this.setPosition(pos);
}; };
this.setPosition = function(pos) { this.setPosition = function(row, column) {
if (this.pos.row == pos.row && this.pos.column == pos.column) pos = this.$clipPositionToDocument(row, column);
if (this.row == pos.row && this.column == pos.column)
return; return;
this.pos = pos; this.row = pos.row;
this.column = pos.column;
this._dispatchEvent("change"); this._dispatchEvent("change");
}; };
this.detach = function() {
this.document.removeEventListener("change", this.$onChange);
};
this.$clipPositionToDocument = function(row, column) {
var pos = {};
if (row >= this.document.getLength()) {
pos.row = Math.max(0, this.document.getLength() - 1);
pos.column = this.document.getLine(pos.row).length;
}
else if (row < 0) {
pos.row = 0;
pos.column = 0;
}
else {
pos.row = row;
pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
}
if (column < 0)
pos.column = 0;
return pos;
};
}).call(Anchor.prototype); }).call(Anchor.prototype);
}); });

View file

@ -49,7 +49,6 @@ var NO_CHANGE_DELTAS = {};
var EditSession = function(text, mode) { var EditSession = function(text, mode) {
this.$modified = true; this.$modified = true;
this.selection = new Selection(this);
this.$breakpoints = []; this.$breakpoints = [];
this.$wrapData = []; this.$wrapData = [];
this.listeners = []; this.listeners = [];
@ -60,6 +59,7 @@ var EditSession = function(text, mode) {
this.setDocument(new Document(text)); this.setDocument(new Document(text));
} }
this.selection = new Selection(this);
if (mode) if (mode)
this.setMode(mode); this.setMode(mode);
}; };
@ -576,7 +576,6 @@ var EditSession = function(text, mode) {
for (var row=startRow; row<=endRow; row++) { for (var row=startRow; row<=endRow; row++) {
this.insert({row: row, column:0}, indentString); this.insert({row: row, column:0}, indentString);
} }
return indentString.length;
}; };
this.outdentRows = function (range) { this.outdentRows = function (range) {
@ -599,13 +598,8 @@ var EditSession = function(text, mode) {
deleteRange.start.column = 0; deleteRange.start.column = 0;
deleteRange.end.column = j; deleteRange.end.column = j;
} }
if (i == range.start.row)
range.start.column -= deleteRange.end.column - deleteRange.start.column;
if (i == range.end.row)
range.end.column -= deleteRange.end.column - deleteRange.start.column;
this.remove(deleteRange); this.remove(deleteRange);
} }
return range;
}; };
this.moveLinesUp = function(firstRow, lastRow) { this.moveLinesUp = function(firstRow, lastRow) {

View file

@ -375,7 +375,7 @@ var Editor =function(renderer, session) {
return; return;
if (!this.selection.isEmpty()) { if (!this.selection.isEmpty()) {
this.moveCursorToPosition(this.session.remove(this.getSelectionRange())); this.session.remove(this.getSelectionRange())
this.clearSelection(); this.clearSelection();
} }
}; };
@ -405,14 +405,6 @@ var Editor =function(renderer, session) {
var lineIndent = this.mode.getNextLineIndent(lineState, line.slice(0, cursor.column), this.session.getTabString()); var lineIndent = this.mode.getNextLineIndent(lineState, line.slice(0, cursor.column), this.session.getTabString());
var end = this.session.insert(cursor, text); var end = this.session.insert(cursor, text);
/* TODO: This shortcut is somehow broken
if (!shouldOutdent && line != this.session.getLine(row) && text != "\n") {
this.moveCursorToPosition(end);
this.renderer.scrollCursorIntoView();
return;
}
*/
var lineState = this.bgTokenizer.getState(cursor.row); var lineState = this.bgTokenizer.getState(cursor.row);
// multi line insert // multi line insert
if (cursor.row !== end.row) { if (cursor.row !== end.row) {
@ -445,15 +437,12 @@ var Editor =function(renderer, session) {
outdent -= 1; outdent -= 1;
this.session.replace(new Range(row, 0, row, line.length), line.substr(i)); this.session.replace(new Range(row, 0, row, line.length), line.substr(i));
} }
end.column += this.session.indentRows(cursor.row + 1, end.row, lineIndent); this.session.indentRows(cursor.row + 1, end.row, lineIndent);
} else { } else {
if (shouldOutdent) { if (shouldOutdent) {
end.column += this.mode.autoOutdent(lineState, this.session, cursor.row); this.mode.autoOutdent(lineState, this.session, cursor.row);
} }
} }
this.moveCursorToPosition(end);
this.renderer.scrollCursorIntoView();
} }
this.onTextInput = function(text) { this.onTextInput = function(text) {
@ -561,7 +550,7 @@ var Editor =function(renderer, session) {
if (this.selection.isEmpty()) { if (this.selection.isEmpty()) {
this.selection.selectRight(); this.selection.selectRight();
} }
this.moveCursorToPosition(this.session.remove(this.getSelectionRange())); this.session.remove(this.getSelectionRange())
this.clearSelection(); this.clearSelection();
}; };
@ -572,7 +561,7 @@ var Editor =function(renderer, session) {
if (this.selection.isEmpty()) if (this.selection.isEmpty())
this.selection.selectLeft(); this.selection.selectLeft();
this.moveCursorToPosition(this.session.remove(this.getSelectionRange())); this.session.remove(this.getSelectionRange());
this.clearSelection(); this.clearSelection();
}; };
@ -585,9 +574,7 @@ var Editor =function(renderer, session) {
if (range.start.row < range.end.row || range.start.column < range.end.column) { if (range.start.row < range.end.row || range.start.column < range.end.column) {
var rows = this.$getSelectedRows(); var rows = this.$getSelectedRows();
var count = session.indentRows(rows.first, rows.last, "\t"); session.indentRows(rows.first, rows.last, "\t");
this.selection.shiftSelection(count);
} else { } else {
var indentString; var indentString;
@ -609,9 +596,7 @@ var Editor =function(renderer, session) {
return; return;
var selection = this.session.getSelection(); var selection = this.session.getSelection();
var range = this.session.outdentRows(selection.getRange()); this.session.outdentRows(selection.getRange());
selection.setSelectionRange(range, selection.isBackwards());
}; };
this.toggleCommentLines = function() { this.toggleCommentLines = function() {
@ -620,8 +605,7 @@ var Editor =function(renderer, session) {
var state = this.bgTokenizer.getState(this.getCursorPosition().row); var state = this.bgTokenizer.getState(this.getCursorPosition().row);
var rows = this.$getSelectedRows() var rows = this.$getSelectedRows()
var addedColumns = this.mode.toggleCommentLines(state, this.session, rows.first, rows.last); this.mode.toggleCommentLines(state, this.session, rows.first, rows.last);
this.selection.shiftSelection(addedColumns);
}; };
this.removeLines = function() { this.removeLines = function() {
@ -629,10 +613,7 @@ var Editor =function(renderer, session) {
return; return;
var rows = this.$getSelectedRows(); var rows = this.$getSelectedRows();
this.selection.setSelectionAnchor(rows.last+1, 0); this.session.remove(new Range(rows.first, 0, rows.last+1, 0));
this.selection.selectTo(rows.first, 0);
this.session.remove(this.getSelectionRange());
this.clearSelection(); this.clearSelection();
}; };
@ -697,7 +678,6 @@ var Editor =function(renderer, session) {
this.onCompositionStart = function(text) { this.onCompositionStart = function(text) {
this.renderer.showComposition(this.getCursorPosition()); this.renderer.showComposition(this.getCursorPosition());
//this.onTextInput(text);
}; };
this.onCompositionUpdate = function(text) { this.onCompositionUpdate = function(text) {
@ -706,7 +686,6 @@ var Editor =function(renderer, session) {
this.onCompositionEnd = function() { this.onCompositionEnd = function() {
this.renderer.hideComposition(); this.renderer.hideComposition();
//this.removeLeft();
}; };

View file

@ -69,16 +69,16 @@ oop.inherits(Mode, TextMode);
var deleteRange = new Range(0, 0, 0, 0); var deleteRange = new Range(0, 0, 0, 0);
for (var i=startRow; i<= endRow; i++) for (var i=startRow; i<= endRow; i++)
{ {
var line = doc.getLine(i).replace(re, "$1"); var line = doc.getLine(i);
var m = line.match(re);
deleteRange.start.row = i; deleteRange.start.row = i;
deleteRange.end.row = i; deleteRange.end.row = i;
deleteRange.end.column = line.length + 2; deleteRange.end.column = m[0].length;
doc.replace(deleteRange, line); doc.replace(deleteRange, m[1]);
} }
return -2;
} }
else { else {
return doc.indentRows(startRow, endRow, "//"); doc.indentRows(startRow, endRow, "//");
} }
}; };
@ -119,7 +119,7 @@ oop.inherits(Mode, TextMode);
}; };
this.autoOutdent = function(state, doc, row) { this.autoOutdent = function(state, doc, row) {
return this.$outdent.autoOutdent(doc, row); this.$outdent.autoOutdent(doc, row);
}; };
}).call(Mode.prototype); }).call(Mode.prototype);

View file

@ -37,52 +37,63 @@
define(function(require, exports, module) { define(function(require, exports, module) {
var Tokenizer = require("ace/tokenizer").Tokenizer var Tokenizer = require("ace/tokenizer").Tokenizer;
, Rules = require("ace/mode/coffee_highlight_rules").CoffeeHighlightRules var Rules = require("ace/mode/coffee_highlight_rules").CoffeeHighlightRules;
, Outdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent var Outdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent;
, Range = require("ace/range").Range var Range = require("ace/range").Range;
; var TextMode = require("ace/mode/text").Mode;
require("pilot/oop").inherits(CoffeeMode, require("ace/mode/text").Mode); var oop = require("pilot/oop")
function CoffeeMode() { function CoffeeMode() {
this.$tokenizer = new Tokenizer(new Rules().getRules()); this.$tokenizer = new Tokenizer(new Rules().getRules());
this.$outdent = new Outdent(); this.$outdent = new Outdent();
} };
var proto = CoffeeMode.prototype
, indenter = /(?:[({[=:]|[-=]>|\b(?:else|switch|try|catch(?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$/ oop.inherits(CoffeeMode, TextMode);
, commentLine = /^(\s*)#/
, hereComment = /^\s*###(?!#)/ var proto = CoffeeMode.prototype;
, indentation = /^\s*/ var indenter = /(?:[({[=:]|[-=]>|\b(?:else|switch|try|catch(?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$/;
; var commentLine = /^(\s*)#/;
proto.getNextLineIndent = function(state, line, tab){ var hereComment = /^\s*###(?!#)/;
var indent = this.$getIndent(line) var indentation = /^\s*/;
, tokens = this.$tokenizer.getLineTokens(line, state).tokens
; proto.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);
var tokens = this.$tokenizer.getLineTokens(line, state).tokens;
if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') && if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') &&
state === 'start' && indenter.test(line)) state === 'start' && indenter.test(line))
indent += tab; indent += tab;
return indent; return indent;
}; };
proto.toggleCommentLines = function(state, doc, startRow, endRow){ proto.toggleCommentLines = function(state, doc, startRow, endRow){
var out, range = new Range(0, 0, 0, 0); console.log("toggle");
var range = new Range(0, 0, 0, 0);
for (var i = startRow; i <= endRow; ++i) { for (var i = startRow; i <= endRow; ++i) {
var line = doc.getLine(i); var line = doc.getLine(i);
if (hereComment.test(line)) continue; if (hereComment.test(line))
line = (out = commentLine.test(line)) continue;
? line.replace(commentLine, '$1')
: line.replace(indentation, '$&#'); if (commentLine.test(line))
line = line.replace(commentLine, '$1');
else
line = line.replace(indentation, '$&#');
range.end.row = range.start.row = i; range.end.row = range.start.row = i;
range.end.column = line.length + 1; range.end.column = line.length + 1;
doc.replace(range, line); doc.replace(range, line);
} }
return 1 - out * 2;
}; };
proto.checkOutdent = function(state, line, input) { proto.checkOutdent = function(state, line, input) {
return this.$outdent.checkOutdent(line, input); return this.$outdent.checkOutdent(line, input);
}; };
proto.autoOutdent = function(state, doc, row) { proto.autoOutdent = function(state, doc, row) {
return this.$outdent.autoOutdent(doc, row); this.$outdent.autoOutdent(doc, row);
}; };
exports.Mode = CoffeeMode; exports.Mode = CoffeeMode;
});
});

View file

@ -73,7 +73,7 @@ oop.inherits(Mode, TextMode);
}; };
this.autoOutdent = function(state, doc, row) { this.autoOutdent = function(state, doc, row) {
return this.$outdent.autoOutdent(doc, row); this.$outdent.autoOutdent(doc, row);
}; };
}).call(Mode.prototype); }).call(Mode.prototype);

View file

@ -55,7 +55,7 @@ oop.inherits(Mode, TextMode);
(function() { (function() {
this.toggleCommentLines = function(state, doc, startRow, endRow) { this.toggleCommentLines = function(state, doc, startRow, endRow) {
return this.$delegate("toggleCommentLines", arguments, function() { this.$delegate("toggleCommentLines", arguments, function() {
return 0; return 0;
}); });
}; };
@ -74,7 +74,7 @@ oop.inherits(Mode, TextMode);
}; };
this.autoOutdent = function(state, doc, row) { this.autoOutdent = function(state, doc, row) {
return this.$delegate("autoOutdent", arguments); this.$delegate("autoOutdent", arguments);
}; };
this.$delegate = function(method, args, defaultHandler) { this.$delegate = function(method, args, defaultHandler) {

View file

@ -69,16 +69,16 @@ oop.inherits(Mode, TextMode);
var deleteRange = new Range(0, 0, 0, 0); var deleteRange = new Range(0, 0, 0, 0);
for (var i=startRow; i<= endRow; i++) for (var i=startRow; i<= endRow; i++)
{ {
var line = doc.getLine(i).replace(re, "$1"); var line = doc.getLine(i);
var m = line.match(re);
deleteRange.start.row = i; deleteRange.start.row = i;
deleteRange.end.row = i; deleteRange.end.row = i;
deleteRange.end.column = line.length + 2; deleteRange.end.column = m[0].length;
doc.replace(deleteRange, line); doc.replace(deleteRange, m[1]);
} }
return -2;
} }
else { else {
return doc.indentRows(startRow, endRow, "//"); doc.indentRows(startRow, endRow, "//");
} }
}; };
@ -119,7 +119,7 @@ oop.inherits(Mode, TextMode);
}; };
this.autoOutdent = function(state, doc, row) { this.autoOutdent = function(state, doc, row) {
return this.$outdent.autoOutdent(doc, row); this.$outdent.autoOutdent(doc, row);
}; };
this.createWorker = function(session) { this.createWorker = function(session) {

View file

@ -63,8 +63,6 @@ var MatchingBraceOutdent = function() {};
var indent = this.$getIndent(doc.getLine(openBracePos.row)); var indent = this.$getIndent(doc.getLine(openBracePos.row));
doc.replace(new Range(row, 0, row, column-1), indent); doc.replace(new Range(row, 0, row, column-1), indent);
return indent.length - (column-1);
}; };
this.$getIndent = function(line) { this.$getIndent = function(line) {

View file

@ -68,16 +68,16 @@ oop.inherits(Mode, TextMode);
var deleteRange = new Range(0, 0, 0, 0); var deleteRange = new Range(0, 0, 0, 0);
for (var i=startRow; i<= endRow; i++) for (var i=startRow; i<= endRow; i++)
{ {
var line = doc.getLine(i).replace(re, "$1"); var line = doc.getLine(i);
var m = line.match(re);
deleteRange.start.row = i; deleteRange.start.row = i;
deleteRange.end.row = i; deleteRange.end.row = i;
deleteRange.end.column = line.length + 2; deleteRange.end.column = m[0].length;
doc.replace(deleteRange, line); doc.replace(deleteRange, m[1]);
} }
return -2;
} }
else { else {
return doc.indentRows(startRow, endRow, "#"); doc.indentRows(startRow, endRow, "#");
} }
}; };
@ -107,7 +107,7 @@ oop.inherits(Mode, TextMode);
}; };
this.autoOutdent = function(state, doc, row) { this.autoOutdent = function(state, doc, row) {
return this.$outdent.autoOutdent(doc, row); this.$outdent.autoOutdent(doc, row);
}; };
}).call(Mode.prototype); }).call(Mode.prototype);

View file

@ -69,16 +69,16 @@ oop.inherits(Mode, TextMode);
var deleteRange = new Range(0, 0, 0, 0); var deleteRange = new Range(0, 0, 0, 0);
for (var i=startRow; i<= endRow; i++) for (var i=startRow; i<= endRow; i++)
{ {
var line = doc.getLine(i).replace(re, "$1"); var line = doc.getLine(i);
var m = line.match(re);
deleteRange.start.row = i; deleteRange.start.row = i;
deleteRange.end.row = i; deleteRange.end.row = i;
deleteRange.end.column = line.length + 2; deleteRange.end.column = m[0].length;
doc.replace(deleteRange, line); doc.replace(deleteRange, m[1]);
} }
return -2;
} }
else { else {
return doc.indentRows(startRow, endRow, "#"); doc.indentRows(startRow, endRow, "#");
} }
}; };
@ -108,7 +108,7 @@ oop.inherits(Mode, TextMode);
}; };
this.autoOutdent = function(state, doc, row) { this.autoOutdent = function(state, doc, row) {
return this.$outdent.autoOutdent(doc, row); this.$outdent.autoOutdent(doc, row);
}; };
}).call(Mode.prototype); }).call(Mode.prototype);

View file

@ -69,16 +69,16 @@ oop.inherits(Mode, TextMode);
var deleteRange = new Range(0, 0, 0, 0); var deleteRange = new Range(0, 0, 0, 0);
for (var i=startRow; i<= endRow; i++) for (var i=startRow; i<= endRow; i++)
{ {
var line = doc.getLine(i).replace(re, "$1"); var line = doc.getLine(i);
var m = line.match(re);
deleteRange.start.row = i; deleteRange.start.row = i;
deleteRange.end.row = i; deleteRange.end.row = i;
deleteRange.end.column = line.length + 2; deleteRange.end.column = m[0].length;
doc.replace(deleteRange, line); doc.replace(deleteRange, m[1]);
} }
return -2;
} }
else { else {
return doc.indentRows(startRow, endRow, "#"); doc.indentRows(startRow, endRow, "#");
} }
}; };
@ -108,7 +108,7 @@ oop.inherits(Mode, TextMode);
}; };
this.autoOutdent = function(state, doc, row) { this.autoOutdent = function(state, doc, row) {
return this.$outdent.autoOutdent(doc, row); this.$outdent.autoOutdent(doc, row);
}; };
}).call(Mode.prototype); }).call(Mode.prototype);

View file

@ -51,7 +51,6 @@ var Mode = function() {
}; };
this.toggleCommentLines = function(state, doc, startRow, endRow) { this.toggleCommentLines = function(state, doc, startRow, endRow) {
return 0;
}; };
this.getNextLineIndent = function(state, line, tab) { this.getNextLineIndent = function(state, line, tab) {

View file

@ -42,15 +42,27 @@ var oop = require("pilot/oop");
var lang = require("pilot/lang"); var lang = require("pilot/lang");
var EventEmitter = require("pilot/event_emitter").EventEmitter; var EventEmitter = require("pilot/event_emitter").EventEmitter;
var Range = require("ace/range").Range; var Range = require("ace/range").Range;
var Anchor = require("ace/anchor").Anchor;
var Selection = function(doc) { var Selection = function(session) {
this.doc = doc; this.session = session;
this.doc = session.getDocument();
this.clearSelection(); this.clearSelection();
this.selectionLead = { this.selectionLead = new Anchor(this.doc, 0, 0);
row: 0, this.selectionAnchor = new Anchor(this.doc, 0, 0);
column: 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() { (function() {
@ -58,9 +70,10 @@ var Selection = function(doc) {
oop.implement(this, EventEmitter); oop.implement(this, EventEmitter);
this.isEmpty = function() { this.isEmpty = function() {
return (!this.selectionAnchor || return (this.$isEmpty || (
(this.selectionAnchor.row == this.selectionLead.row && this.selectionAnchor.row == this.selectionLead.row &&
this.selectionAnchor.column == this.selectionLead.column)); this.selectionAnchor.column == this.selectionLead.column
));
}; };
this.isMultiLine = function() { this.isMultiLine = function() {
@ -72,37 +85,31 @@ var Selection = function(doc) {
}; };
this.getCursor = function() { this.getCursor = function() {
return this.selectionLead; return this.selectionLead.getPosition();
}; };
this.setSelectionAnchor = function(row, column) { this.setSelectionAnchor = function(row, column) {
var anchor = this.$clipPositionToDocument(row, column); this.selectionAnchor.setPosition(row, column);
if (!this.selectionAnchor) { if (this.$isEmpty) {
this.selectionAnchor = anchor; this.$isEmpty = false;
this._dispatchEvent("changeSelection", {}); this._dispatchEvent("changeSelection");
} }
else if (this.selectionAnchor.row !== anchor.row || this.selectionAnchor.column !== anchor.column) {
this.selectionAnchor = anchor;
this._dispatchEvent("changeSelection", {});
}
}; };
this.getSelectionAnchor = function() { this.getSelectionAnchor = function() {
if (this.selectionAnchor) { if (this.$isEmpty)
return this.$clone(this.selectionAnchor); return this.getSelectionLead()
} else { else
return this.$clone(this.selectionLead); return this.selectionAnchor.getPosition();
}
}; };
this.getSelectionLead = function() { this.getSelectionLead = function() {
return this.$clone(this.selectionLead); return this.selectionLead.getPosition();
}; };
this.shiftSelection = function(columns) { this.shiftSelection = function(columns) {
if (this.isEmpty()) { if (this.$isEmpty) {
this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns); this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns);
return; return;
}; };
@ -123,15 +130,18 @@ var Selection = function(doc) {
}; };
this.isBackwards = function() { this.isBackwards = function() {
var anchor = this.selectionAnchor || this.selectionLead; var anchor = this.selectionAnchor;
var lead = this.selectionLead; var lead = this.selectionLead;
return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column)); return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
}; };
this.getRange = function() { this.getRange = function() {
var anchor = this.selectionAnchor || this.selectionLead; var anchor = this.selectionAnchor;
var lead = this.selectionLead; var lead = this.selectionLead;
if (this.isEmpty())
return Range.fromPoints(lead, lead);
if (this.isBackwards()) { if (this.isBackwards()) {
return Range.fromPoints(lead, anchor); return Range.fromPoints(lead, anchor);
} }
@ -141,26 +151,17 @@ var Selection = function(doc) {
}; };
this.clearSelection = function() { this.clearSelection = function() {
if (this.selectionAnchor) { if (!this.$isEmpty) {
this.selectionAnchor = null; this.$isEmpty = true;
this._dispatchEvent("changeSelection", {}); this._dispatchEvent("changeSelection");
} }
}; };
this.selectAll = function() { this.selectAll = function() {
var lastRow = this.doc.getLength() - 1; var lastRow = this.doc.getLength() - 1;
this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length); this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length);
this.setSelectionLead(0, 0);
if (!this.selectionAnchor) { // this._dispatchEvent("changeSelection", {blockScrolling: true});
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.setSelectionRange = function(range, reverse) { this.setSelectionRange = function(range, reverse) {
@ -177,27 +178,16 @@ var Selection = function(doc) {
this.$updateDesiredColumn = function() { this.$updateDesiredColumn = function() {
var cursor = this.getCursor(); var cursor = this.getCursor();
if (cursor) { if (cursor) {
this.$desiredColumn = this.doc.documentToScreenColumn(cursor.row, cursor.column); this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column);
} }
}; };
this.$moveSelection = function(mover) { 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); 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) { this.selectTo = function(row, column) {
@ -253,15 +243,9 @@ var Selection = function(doc) {
}; };
this.selectWord = function() { this.selectWord = function() {
var cursor = this.selectionLead; var cursor = this.getCursor();
var column = cursor.column; var range = this.session.getWordRange(cursor.row, cursor.column);
var range = this.doc.getWordRange(cursor.row, column);
this.setSelectionRange(range); this.setSelectionRange(range);
/*this.setSelectionAnchor(cursor.row, start);
this.$moveSelection(function() {
this.moveCursorTo(cursor.row, end);
});*/
}; };
this.selectLine = function() { this.selectLine = function() {
@ -280,18 +264,16 @@ var Selection = function(doc) {
}; };
this.moveCursorLeft = function() { this.moveCursorLeft = function() {
if (this.selectionLead.column == 0) { var cursor = this.selectionLead.getPosition();
if (cursor.column == 0) {
// cursor is a line (start // cursor is a line (start
if (this.selectionLead.row > 0) { if (cursor.row > 0) {
this.moveCursorTo(this.selectionLead.row - 1, this.doc this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);
.getLine(this.selectionLead.row - 1).length);
} }
} }
else { else {
var doc = this.doc; var tabSize = this.session.getTabSize();
var tabSize = doc.getTabSize(); if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize)
var cursor = this.selectionLead;
if (doc.isTabStop(cursor) && doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize)
this.moveCursorBy(0, -tabSize); this.moveCursorBy(0, -tabSize);
else else
this.moveCursorBy(0, -1); this.moveCursorBy(0, -1);
@ -305,10 +287,9 @@ var Selection = function(doc) {
} }
} }
else { else {
var doc = this.doc; var tabSize = this.session.getTabSize();
var tabSize = doc.getTabSize();
var cursor = this.selectionLead; 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); this.moveCursorBy(0, tabSize);
else else
this.moveCursorBy(0, 1); this.moveCursorBy(0, 1);
@ -318,12 +299,12 @@ var Selection = function(doc) {
this.moveCursorLineStart = function() { this.moveCursorLineStart = function() {
var row = this.selectionLead.row; var row = this.selectionLead.row;
var column = this.selectionLead.column; var column = this.selectionLead.column;
var screenRow = this.doc.documentToScreenRow(row, column); var screenRow = this.session.documentToScreenRow(row, column);
var firstRowColumn = this.doc.getScreenFirstRowColumn(screenRow); var firstRowColumn = this.session.getScreenFirstRowColumn(screenRow);
var beforeCursor = this.doc.getLine(row).slice(firstRowColumn, column); var beforeCursor = this.doc.getLine(row).slice(firstRowColumn, column);
var leadingSpace = beforeCursor.match(/^\s*/); var leadingSpace = beforeCursor.match(/^\s*/);
if (leadingSpace[0].length == 0) { if (leadingSpace[0].length == 0) {
var lastRowColumn = this.doc.getDocumentLastRowColumn(row, column); var lastRowColumn = this.session.getDocumentLastRowColumn(row, column);
leadingSpace = this.doc.getLine(row). leadingSpace = this.doc.getLine(row).
substring(firstRowColumn, lastRowColumn). substring(firstRowColumn, lastRowColumn).
match(/^\s*/); match(/^\s*/);
@ -336,9 +317,8 @@ var Selection = function(doc) {
}; };
this.moveCursorLineEnd = function() { this.moveCursorLineEnd = function() {
var selLead = this.selectionLead; var lead = this.selectionLead;
this.moveCursorTo(selLead.row, this.moveCursorTo(lead.row, this.session.getDocumentLastRowColumn(lead.row, lead.column));
this.doc.getDocumentLastRowColumn(selLead.row, selLead.column));
}; };
this.moveCursorFileEnd = function() { this.moveCursorFileEnd = function() {
@ -358,20 +338,20 @@ var Selection = function(doc) {
var rightOfCursor = line.substring(column); var rightOfCursor = line.substring(column);
var match; var match;
this.doc.nonTokenRe.lastIndex = 0; this.session.nonTokenRe.lastIndex = 0;
this.doc.tokenRe.lastIndex = 0; this.session.tokenRe.lastIndex = 0;
if (column == line.length) { if (column == line.length) {
this.moveCursorRight(); this.moveCursorRight();
return; return;
} }
else if (match = this.doc.nonTokenRe.exec(rightOfCursor)) { else if (match = this.session.nonTokenRe.exec(rightOfCursor)) {
column += this.doc.nonTokenRe.lastIndex; column += this.session.nonTokenRe.lastIndex;
this.doc.nonTokenRe.lastIndex = 0; this.session.nonTokenRe.lastIndex = 0;
} }
else if (match = this.doc.tokenRe.exec(rightOfCursor)) { else if (match = this.session.tokenRe.exec(rightOfCursor)) {
column += this.doc.tokenRe.lastIndex; column += this.session.tokenRe.lastIndex;
this.doc.tokenRe.lastIndex = 0; this.session.tokenRe.lastIndex = 0;
} }
this.moveCursorTo(row, column); this.moveCursorTo(row, column);
@ -384,83 +364,49 @@ var Selection = function(doc) {
var leftOfCursor = lang.stringReverse(line.substring(0, column)); var leftOfCursor = lang.stringReverse(line.substring(0, column));
var match; var match;
this.doc.nonTokenRe.lastIndex = 0; this.session.nonTokenRe.lastIndex = 0;
this.doc.tokenRe.lastIndex = 0; this.session.tokenRe.lastIndex = 0;
if (column == 0) { if (column == 0) {
this.moveCursorLeft(); this.moveCursorLeft();
return; return;
} }
else if (match = this.doc.nonTokenRe.exec(leftOfCursor)) { else if (match = this.session.nonTokenRe.exec(leftOfCursor)) {
column -= this.doc.nonTokenRe.lastIndex; column -= this.session.nonTokenRe.lastIndex;
this.doc.nonTokenRe.lastIndex = 0; this.session.nonTokenRe.lastIndex = 0;
} }
else if (match = this.doc.tokenRe.exec(leftOfCursor)) { else if (match = this.session.tokenRe.exec(leftOfCursor)) {
column -= this.doc.tokenRe.lastIndex; column -= this.session.tokenRe.lastIndex;
this.doc.tokenRe.lastIndex = 0; this.session.tokenRe.lastIndex = 0;
} }
this.moveCursorTo(row, column); this.moveCursorTo(row, column);
}; };
this.moveCursorBy = function(rows, chars) { this.moveCursorBy = function(rows, chars) {
if (this.doc.getUseWrapMode()) { if (this.session.getUseWrapMode()) {
var screenPos = this.doc.documentToScreenPosition( var screenPos = this.session.documentToScreenPosition(
this.selectionLead.row, this.selectionLead.column); this.selectionLead.row,
var screenCol = this.selectionLead.column
(chars == 0 && this.$desiredColumn) || screenPos.column; );
var screenCol = (chars == 0 && this.$desiredColumn) || screenPos.column;
var docPos = this.doc.screenToDocumentPosition( var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenCol);
screenPos.row + rows, screenCol);
this.moveCursorTo(docPos.row, docPos.column + chars, chars == 0); this.moveCursorTo(docPos.row, docPos.column + chars, chars == 0);
} else { } else {
var docColumn = var docColumn = (chars == 0 && this.$desiredColumn) || this.selectionLead.column;
(chars == 0 && this.$desiredColumn) || this.selectionLead.column; this.moveCursorTo(this.selectionLead.row + rows, docColumn + chars, chars == 0);
this.moveCursorTo(
this.selectionLead.row + rows, docColumn + chars, chars == 0);
} }
}; };
this.moveCursorToPosition = function(position) { this.moveCursorToPosition = function(position) {
this.moveCursorTo(position.row, position.column); this.moveCursorTo(position.row, position.column);
}; };
this.moveCursorTo = function(row, column, preventUpdateDesiredColumn) { this.moveCursorTo = function(row, column, preventUpdateDesiredColumn) {
var cursor = this.$clipPositionToDocument(row, column); this.selectionLead.setPosition(row, column);
if (!preventUpdateDesiredColumn)
// only dispatch change if the cursor actually changed this.$updateDesiredColumn(this.selectionLead.column);
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
};
}; };
}).call(Selection.prototype); }).call(Selection.prototype);

View file

@ -104,7 +104,6 @@ var Test = {
var anchor = new Anchor(doc, 1, 4); var anchor = new Anchor(doc, 1, 4);
doc.remove(new Range(1, 4, 1, 5)); doc.remove(new Range(1, 4, 1, 5));
console.log(doc.$lines);
assert.position(anchor.getPosition(), 1, 4); assert.position(anchor.getPosition(), 1, 4);
}, },