add copy lines down/up functionality and fix "delete line"

This commit is contained in:
Fabian Jakobs 2010-04-16 10:46:47 +02:00
commit 299894795e
6 changed files with 166 additions and 42 deletions

View file

@ -290,17 +290,6 @@ ace.Editor.prototype.removeLeft = function() {
this.clearSelection();
};
ace.Editor.prototype.removeLine = function() {
this.selection.selectLine();
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
this.clearSelection();
if (this.getCursorPosition().row == this.doc.getLength() - 1) {
this.removeLeft();
this.selection.moveCursorLineStart();
}
};
ace.Editor.prototype.blockIndent = function(indentString) {
var indentString = indentString || this.doc.getTabString();
var addedColumns = this.doc.indentRows(this.getSelectionRange(), indentString);
@ -324,6 +313,15 @@ ace.Editor.prototype.toggleCommentLines = function() {
this.selection.shiftSelection(addedColumns);
};
ace.Editor.prototype.removeLines = function() {
var rows = this._getSelectedRows();
this.selection.setSelectionAnchor(rows.last+1, 0);
this.selection.selectTo(rows.first, 0);
this.doc.remove(this.getSelectionRange());
this.clearSelection();
};
ace.Editor.prototype.moveLinesDown = function() {
this._moveLines(function(firstRow, lastRow) {
return this.doc.moveLinesDown(firstRow, lastRow);
@ -336,7 +334,33 @@ ace.Editor.prototype.moveLinesUp = function() {
});
};
ace.Editor.prototype.copyLinesUp = function() {
this._moveLines(function(firstRow, lastRow) {
this.doc.duplicateLines(firstRow, lastRow);
return 0;
});
};
ace.Editor.prototype.copyLinesDown = function() {
this._moveLines(function(firstRow, lastRow) {
return this.doc.duplicateLines(firstRow, lastRow);
});
};
ace.Editor.prototype._moveLines = function(mover) {
var rows = this._getSelectedRows();
var linesMoved = mover.call(this, rows.first, rows.last);
var selection = this.selection;
selection.setSelectionAnchor(rows.last+linesMoved+1, 0);
selection._moveSelection(function() {
selection.moveCursorTo(rows.first+linesMoved, 0);
});
};
ace.Editor.prototype._getSelectedRows = function() {
var range = this.getSelectionRange();
var firstRow = range.start.row;
var lastRow = range.end.row;
@ -344,16 +368,12 @@ ace.Editor.prototype._moveLines = function(mover) {
lastRow -= 1;
}
var linesMoved = mover.call(this, firstRow, lastRow);
var selection = this.selection;
selection.setSelectionAnchor(lastRow+linesMoved+1, 0);
selection._moveSelection(function() {
selection.moveCursorTo(firstRow+linesMoved, 0);
});
return {
first: firstRow,
last: lastRow
};
};
ace.Editor.prototype.onCompositionStart = function() {
this.renderer.showComposition(this.getCursorPosition());
this.onTextInput(" ");

View file

@ -35,7 +35,7 @@ ace.KeyBinding = function(element, editor) {
case keys.D:
if (e.metaKey) {
editor.removeLine();
editor.removeLines();
return ace.stopEvent(e);
}
break;
@ -58,7 +58,10 @@ ace.KeyBinding = function(element, editor) {
break;
case keys.UP:
if (e.altKey) {
if (e.altKey && e.metaKey ) {
editor.copyLinesUp();
}
else if (e.altKey) {
editor.moveLinesUp();
}
else if (e.metaKey && e.shiftKey) {
@ -76,7 +79,10 @@ ace.KeyBinding = function(element, editor) {
return ace.stopEvent(e);
case keys.DOWN:
if (e.altKey) {
if (e.altKey && e.metaKey ) {
editor.copyLinesDown();
}
else if (e.altKey) {
editor.moveLinesDown();
}
else if (e.metaKey && e.shiftKey) {

View file

@ -114,6 +114,12 @@ ace.Selection.prototype._moveSelection = function(mover) {
this.updateSelection();
};
ace.Selection.prototype.selectTo = function(row, column) {
this._moveSelection(function() {
this.moveCursorTo(row, column);
});
};
ace.Selection.prototype.selectToPosition = function(pos) {
this._moveSelection(function() {
this.moveCursorToPosition(pos);

View file

@ -92,10 +92,8 @@ ace.TextDocument.prototype.getTextRange = function(range) {
else {
var lines = [];
lines.push(this.lines[range.start.row].substring(range.start.column));
lines.push.apply(lines, this.lines.slice(range.start.row + 1,
range.end.row));
lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
lines.push(this.lines[range.end.row].substring(0, range.end.column));
return lines.join("\n");
}
};
@ -203,6 +201,12 @@ ace.TextDocument.prototype.insert = function(position, text) {
return end;
};
ace.TextDocument.prototype._insertLines = function(row, lines) {
var args = [row, 0];
args.push.apply(args, lines);
this.lines.splice.apply(this.lines, args);
},
ace.TextDocument.prototype._insert = function(position, text) {
this.modified = true;
@ -237,9 +241,7 @@ ace.TextDocument.prototype._insert = function(position, text) {
+ line.substring(position.column);
if (newLines.length > 2) {
var args = [ position.row + 1, 0 ];
args.push.apply(args, newLines.slice(1, -1));
this.lines.splice.apply(this.lines, args);
this._insertLines(position.row + 1, newLines.slice(1, -1));
}
return {
@ -318,10 +320,7 @@ ace.TextDocument.prototype.moveLinesUp = function(firstRow, lastRow) {
if (firstRow <= 0) return 0;
var removed = this.lines.splice(firstRow, lastRow-firstRow+1);
var args = [firstRow - 1, 0];
args.push.apply(args, removed);
this.lines.splice.apply(this.lines, args);
this._insertLines(firstRow-1, removed);
this.fireChangeEvent(firstRow-1, lastRow);
return -1;
@ -331,11 +330,26 @@ ace.TextDocument.prototype.moveLinesDown = function(firstRow, lastRow) {
if (lastRow >= this.lines.length-1) return 0;
var removed = this.lines.splice(firstRow, lastRow-firstRow+1);
var args = [firstRow + 1, 0];
args.push.apply(args, removed);
this.lines.splice.apply(this.lines, args);
this._insertLines(firstRow+1, removed);
this.fireChangeEvent(firstRow, lastRow+1);
return 1;
};
};
ace.TextDocument.prototype.duplicateLines = function(firstRow, lastRow) {
var firstRow = this._clipRowToDocument(firstRow);
var lastRow = this._clipRowToDocument(lastRow);
var lines = this.getLines(firstRow, lastRow);
this._insertLines(firstRow, lines);
var addedRows = lastRow - firstRow + 1;
this.fireChangeEvent(firstRow, lastRow+addedRows);
return addedRows;
};
ace.TextDocument.prototype._clipRowToDocument = function(row) {
return Math.max(0, Math.min(row, this.lines.length-1));
};

View file

@ -63,5 +63,26 @@ var TextDocumentTest = new TestCase("TextDocumentTest", {
doc.moveLinesUp(2, 2);
assertEquals(["3", "1", "4", "2"].join("\n"), doc.toString());
},
"test: duplicate lines" : function() {
var doc = new ace.TextDocument(["1", "2", "3", "4"].join("\n"));
doc.duplicateLines(1, 2);
assertEquals(["1", "2", "3", "2", "3", "4"].join("\n"), doc.toString());
},
"test: duplicate last line" : function() {
var doc = new ace.TextDocument(["1", "2", "3"].join("\n"));
doc.duplicateLines(2, 2);
assertEquals(["1", "2", "3", "3"].join("\n"), doc.toString());
},
"test: duplicate first line" : function() {
var doc = new ace.TextDocument(["1", "2", "3"].join("\n"));
doc.duplicateLines(0, 0);
assertEquals(["1", "1", "2", "3"].join("\n"), doc.toString());
}
});

View file

@ -5,17 +5,44 @@ var TextEditTest = TestCase("TextEditTest",
var editor = new ace.Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 1);
editor.removeLine();
editor.removeLines();
assertEquals("a\nc\nd", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
editor.removeLines();
assertEquals("a\nd", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
editor.removeLines();
assertEquals("a\n", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
editor.removeLines();
assertEquals("a\n", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
},
"test: delete multiple selected lines" : function() {
var doc = new ace.TextDocument(["a", "b", "c", "d"].join("\n"));
var editor = new ace.Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 1);
editor.getSelection().selectDown();
editor.removeLines();
assertEquals("a\nd", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
},
"test: delete first line" : function() {
var doc = new ace.TextDocument(["a", "b", "c"].join("\n"));
var editor = new ace.Editor(new MockRenderer(), doc);
editor.removeLine();
editor.removeLines();
assertEquals("b\nc", doc.toString());
assertPosition(0, 0, editor.getCursorPosition());
@ -26,10 +53,10 @@ var TextEditTest = TestCase("TextEditTest",
var editor = new ace.Editor(new MockRenderer(), doc);
editor.moveCursorTo(2, 1);
editor.removeLine();
editor.removeLines();
assertEquals("a\nb", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
assertEquals("a\nb\n", doc.toString());
assertPosition(2, 0, editor.getCursorPosition());
},
"test: indent block" : function() {
@ -190,6 +217,36 @@ var TextEditTest = TestCase("TextEditTest",
assertPosition(1, 0, editor.getCursorPosition());
},
"test: copy lines down should select lines and place cursor at the selection start" : function() {
var doc = new ace.TextDocument(["11", "22", "33", "44"].join("\n"));
var editor = new ace.Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 1);
editor.getSelection().selectDown();
editor.copyLinesDown();
assertEquals(["11", "22", "33", "22", "33", "44"].join("\n"), doc.toString());
assertPosition(3, 0, editor.getCursorPosition());
assertPosition(5, 0, editor.getSelection().getSelectionAnchor());
assertPosition(3, 0, editor.getSelection().getSelectionLead());
},
"test: copy lines up should select lines and place cursor at the selection start" : function() {
var doc = new ace.TextDocument(["11", "22", "33", "44"].join("\n"));
var editor = new ace.Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 1);
editor.getSelection().selectDown();
editor.copyLinesUp();
assertEquals(["11", "22", "33", "22", "33", "44"].join("\n"), doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
assertPosition(3, 0, editor.getSelection().getSelectionAnchor());
assertPosition(1, 0, editor.getSelection().getSelectionLead());
},
"test: input a tab with soft tab should convert it to spaces" : function() {
var doc = new ace.TextDocument("");
var editor = new ace.Editor(new MockRenderer(), doc);