support moving lines up/down (alt-up/down)
This commit is contained in:
parent
960d6abc34
commit
34d851b24e
5 changed files with 191 additions and 36 deletions
|
|
@ -288,6 +288,35 @@ ace.Editor.prototype.toggleCommentLines = function() {
|
||||||
this.shiftSelection(addedColumns);
|
this.shiftSelection(addedColumns);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ace.Editor.prototype.moveLinesDown = function() {
|
||||||
|
this._moveLines(function(firstRow, lastRow) {
|
||||||
|
return this.doc.moveLinesDown(firstRow, lastRow);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ace.Editor.prototype.moveLinesUp = function() {
|
||||||
|
this._moveLines(function(firstRow, lastRow) {
|
||||||
|
return this.doc.moveLinesUp(firstRow, lastRow);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ace.Editor.prototype._moveLines = function(mover) {
|
||||||
|
var range = this.getSelectionRange();
|
||||||
|
var firstRow = range.start.row;
|
||||||
|
var lastRow = range.end.row;
|
||||||
|
if (range.end.column == 0 && (range.start.row !== range.end.row)) {
|
||||||
|
lastRow -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var linesMoved = mover.call(this, firstRow, lastRow);
|
||||||
|
|
||||||
|
this.setSelectionAnchor(lastRow+linesMoved+1, 0);
|
||||||
|
this._moveSelection(function() {
|
||||||
|
this.moveCursorTo(firstRow+linesMoved, 0);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
ace.Editor.prototype.onCompositionStart = function() {
|
ace.Editor.prototype.onCompositionStart = function() {
|
||||||
this.renderer.showComposition(this.cursor);
|
this.renderer.showComposition(this.cursor);
|
||||||
this.onTextInput(" ");
|
this.onTextInput(" ");
|
||||||
|
|
@ -532,21 +561,27 @@ ace.Editor.prototype.moveCursorToPosition = function(position) {
|
||||||
this.moveCursorTo(position.row, position.column);
|
this.moveCursorTo(position.row, position.column);
|
||||||
};
|
};
|
||||||
|
|
||||||
ace.Editor.prototype.moveCursorTo = function(row, column) {
|
ace.Editor.prototype._clipPositionToDocument = function(row, column) {
|
||||||
|
var pos = {};
|
||||||
|
|
||||||
if (row >= this.doc.getLength()) {
|
if (row >= this.doc.getLength()) {
|
||||||
this.cursor.row = this.doc.getLength() - 1;
|
pos.row = this.doc.getLength() - 1;
|
||||||
this.cursor.column = this.doc.getLine(this.cursor.row).length;
|
pos.column = this.doc.getLine(pos.row).length;
|
||||||
}
|
}
|
||||||
else if (row < 0) {
|
else if (row < 0) {
|
||||||
this.cursor.row = 0;
|
pos.row = 0;
|
||||||
this.cursor.column = 0;
|
pos.column = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.cursor.row = row;
|
pos.row = row;
|
||||||
this.cursor.column = Math
|
pos.column = Math.min(this.doc.getLine(pos.row).length,
|
||||||
.min(this.doc.getLine(this.cursor.row).length, Math
|
Math.max(0, column));
|
||||||
.max(0, column));
|
|
||||||
}
|
}
|
||||||
|
return pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
ace.Editor.prototype.moveCursorTo = function(row, column) {
|
||||||
|
this.cursor = this._clipPositionToDocument(row, column);
|
||||||
this.updateCursor();
|
this.updateCursor();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -580,12 +615,7 @@ ace.Editor.prototype.hasMultiLineSelection = function() {
|
||||||
ace.Editor.prototype.setSelectionAnchor = function(row, column) {
|
ace.Editor.prototype.setSelectionAnchor = function(row, column) {
|
||||||
this.clearSelection();
|
this.clearSelection();
|
||||||
|
|
||||||
this.selectionAnchor = {
|
this.selectionAnchor = this._clipPositionToDocument(row, column);
|
||||||
row : Math.min(this.doc.getLength() - 1, Math.max(0, row)),
|
|
||||||
column : Math.min(this.doc.getLine(this.cursor.row).length, Math
|
|
||||||
.max(0, column))
|
|
||||||
};
|
|
||||||
|
|
||||||
this.selectionLead = null;
|
this.selectionLead = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -624,26 +654,21 @@ ace.Editor.prototype.shiftSelection = function(columns) {
|
||||||
};
|
};
|
||||||
|
|
||||||
ace.Editor.prototype.getSelectionRange = function() {
|
ace.Editor.prototype.getSelectionRange = function() {
|
||||||
var anchor = this.selectionAnchor;
|
var anchor = this.selectionAnchor || this.cursor;
|
||||||
var lead = this.selectionLead;
|
var lead = this.selectionLead || this.cursor;
|
||||||
|
|
||||||
if (!anchor) {
|
if (anchor.row > lead.row
|
||||||
return null;
|
|| (anchor.row == lead.row && anchor.column > lead.column)) {
|
||||||
|
return {
|
||||||
|
start : lead,
|
||||||
|
end : anchor
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (anchor.row > lead.row
|
return {
|
||||||
|| (anchor.row == lead.row && anchor.column > lead.column)) {
|
start : anchor,
|
||||||
return {
|
end : lead
|
||||||
start : lead,
|
};
|
||||||
end : anchor
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return {
|
|
||||||
start : anchor,
|
|
||||||
end : lead
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,13 +57,16 @@ ace.KeyBinding = function(element, host) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case keys.UP:
|
case keys.UP:
|
||||||
if (e.metaKey && e.shiftKey) {
|
if (e.altKey) {
|
||||||
|
host.moveLinesUp();
|
||||||
|
}
|
||||||
|
else if (e.metaKey && e.shiftKey) {
|
||||||
host.selectFileStart();
|
host.selectFileStart();
|
||||||
}
|
}
|
||||||
else if (e.metaKey) {
|
else if (e.metaKey) {
|
||||||
host.navigateFileStart();
|
host.navigateFileStart();
|
||||||
}
|
}
|
||||||
if (e.shiftKey) {
|
else if (e.shiftKey) {
|
||||||
host.selectUp();
|
host.selectUp();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -72,13 +75,16 @@ ace.KeyBinding = function(element, host) {
|
||||||
return ace.stopEvent(e);
|
return ace.stopEvent(e);
|
||||||
|
|
||||||
case keys.DOWN:
|
case keys.DOWN:
|
||||||
if (e.metaKey && e.shiftKey) {
|
if (e.altKey) {
|
||||||
|
host.moveLinesDown();
|
||||||
|
}
|
||||||
|
else if (e.metaKey && e.shiftKey) {
|
||||||
host.selectFileEnd();
|
host.selectFileEnd();
|
||||||
}
|
}
|
||||||
else if (e.metaKey) {
|
else if (e.metaKey) {
|
||||||
host.navigateFileEnd();
|
host.navigateFileEnd();
|
||||||
}
|
}
|
||||||
if (e.shiftKey) {
|
else if (e.shiftKey) {
|
||||||
host.selectDown();
|
host.selectDown();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -301,4 +301,30 @@ ace.TextDocument.prototype.outdentRows = function(range, indentString) {
|
||||||
|
|
||||||
this.fireChangeEvent(range.start.row, range.end.row);
|
this.fireChangeEvent(range.start.row, range.end.row);
|
||||||
return -outdentLength;
|
return -outdentLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
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.fireChangeEvent(firstRow-1, lastRow);
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
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.fireChangeEvent(firstRow, lastRow+1);
|
||||||
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
@ -31,5 +31,37 @@ var TextDocumentTest = new TestCase("TextDocumentTest", {
|
||||||
assertPosition(0, 0, doc.findMatchingBracket({row: 1, column: 1}));
|
assertPosition(0, 0, doc.findMatchingBracket({row: 1, column: 1}));
|
||||||
assertPosition(0, 2, doc.findMatchingBracket({row: 1, column: 2}));
|
assertPosition(0, 2, doc.findMatchingBracket({row: 1, column: 2}));
|
||||||
assertPosition(0, 1, doc.findMatchingBracket({row: 1, column: 3}));
|
assertPosition(0, 1, doc.findMatchingBracket({row: 1, column: 3}));
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: move lines down" : function() {
|
||||||
|
var doc = new ace.TextDocument(["1", "2", "3", "4"].join("\n"));
|
||||||
|
|
||||||
|
doc.moveLinesDown(0, 1);
|
||||||
|
assertEquals(["3", "1", "2", "4"].join("\n"), doc.toString());
|
||||||
|
|
||||||
|
doc.moveLinesDown(1, 2);
|
||||||
|
assertEquals(["3", "4", "1", "2"].join("\n"), doc.toString());
|
||||||
|
|
||||||
|
doc.moveLinesDown(2, 3);
|
||||||
|
assertEquals(["3", "4", "1", "2"].join("\n"), doc.toString());
|
||||||
|
|
||||||
|
doc.moveLinesDown(2, 2);
|
||||||
|
assertEquals(["3", "4", "2", "1"].join("\n"), doc.toString());
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: move lines up" : function() {
|
||||||
|
var doc = new ace.TextDocument(["1", "2", "3", "4"].join("\n"));
|
||||||
|
|
||||||
|
doc.moveLinesUp(2, 3);
|
||||||
|
assertEquals(["1", "3", "4", "2"].join("\n"), doc.toString());
|
||||||
|
|
||||||
|
doc.moveLinesUp(1, 2);
|
||||||
|
assertEquals(["3", "4", "1", "2"].join("\n"), doc.toString());
|
||||||
|
|
||||||
|
doc.moveLinesUp(0, 1);
|
||||||
|
assertEquals(["3", "4", "1", "2"].join("\n"), doc.toString());
|
||||||
|
|
||||||
|
doc.moveLinesUp(2, 2);
|
||||||
|
assertEquals(["3", "1", "4", "2"].join("\n"), doc.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -107,5 +107,71 @@ var TextEditTest = TestCase("TextEditTest",
|
||||||
var selection = editor.getSelectionRange();
|
var selection = editor.getSelectionRange();
|
||||||
assertPosition(0, 0, selection.start);
|
assertPosition(0, 0, selection.start);
|
||||||
assertPosition(1, 1, selection.end);
|
assertPosition(1, 1, selection.end);
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: move lines down should select moved lines" : function() {
|
||||||
|
var doc = new ace.TextDocument(["11", "22", "33", "44"].join("\n"));
|
||||||
|
var editor = new ace.Editor(new MockRenderer(), doc);
|
||||||
|
|
||||||
|
editor.moveCursorTo(0, 1);
|
||||||
|
editor.selectDown();
|
||||||
|
|
||||||
|
editor.moveLinesDown();
|
||||||
|
assertEquals(["33", "11", "22", "44"].join("\n"), doc.toString());
|
||||||
|
assertPosition(1, 0, editor.getCursorPosition());
|
||||||
|
assertPosition(3, 0, editor.getSelectionAnchor());
|
||||||
|
assertPosition(1, 0, editor.getSelectionLead());
|
||||||
|
|
||||||
|
editor.moveLinesDown();
|
||||||
|
assertEquals(["33", "44", "11", "22"].join("\n"), doc.toString());
|
||||||
|
assertPosition(2, 0, editor.getCursorPosition());
|
||||||
|
assertPosition(3, 2, editor.getSelectionAnchor());
|
||||||
|
assertPosition(2, 0, editor.getSelectionLead());
|
||||||
|
|
||||||
|
// moving again should have no effect
|
||||||
|
editor.moveLinesDown();
|
||||||
|
assertEquals(["33", "44", "11", "22"].join("\n"), doc.toString());
|
||||||
|
assertPosition(2, 0, editor.getCursorPosition());
|
||||||
|
assertPosition(3, 2, editor.getSelectionAnchor());
|
||||||
|
assertPosition(2, 0, editor.getSelectionLead());
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: move lines up should select moved lines" : function() {
|
||||||
|
var doc = new ace.TextDocument(["11", "22", "33", "44"].join("\n"));
|
||||||
|
var editor = new ace.Editor(new MockRenderer(), doc);
|
||||||
|
|
||||||
|
editor.moveCursorTo(2, 1);
|
||||||
|
editor.selectDown();
|
||||||
|
|
||||||
|
editor.moveLinesUp();
|
||||||
|
assertEquals(["11", "33", "44", "22"].join("\n"), doc.toString());
|
||||||
|
assertPosition(1, 0, editor.getCursorPosition());
|
||||||
|
assertPosition(3, 0, editor.getSelectionAnchor());
|
||||||
|
assertPosition(1, 0, editor.getSelectionLead());
|
||||||
|
|
||||||
|
editor.moveLinesUp();
|
||||||
|
assertEquals(["33", "44", "11", "22"].join("\n"), doc.toString());
|
||||||
|
assertPosition(0, 0, editor.getCursorPosition());
|
||||||
|
assertPosition(2, 0, editor.getSelectionAnchor());
|
||||||
|
assertPosition(0, 0, editor.getSelectionLead());
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: move line without active selection should move cursor to start of the moved line" : 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.clearSelection();
|
||||||
|
|
||||||
|
editor.moveLinesDown();
|
||||||
|
assertEquals(["11", "33", "22", "44"].join("\n"), doc.toString());
|
||||||
|
assertPosition(2, 0, editor.getCursorPosition());
|
||||||
|
|
||||||
|
editor.clearSelection();
|
||||||
|
|
||||||
|
editor.moveLinesUp();
|
||||||
|
assertEquals(["11", "22", "33", "44"].join("\n"), doc.toString());
|
||||||
|
assertPosition(1, 0, editor.getCursorPosition());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue