add delete line command
This commit is contained in:
parent
c8ffa9d3dd
commit
f5a61599cf
6 changed files with 131 additions and 103 deletions
107
src/Editor.js
107
src/Editor.js
|
|
@ -15,7 +15,8 @@ var keys = {
|
|||
DELETE : 46,
|
||||
BACKSPACE : 8,
|
||||
TAB : 9,
|
||||
A : 65
|
||||
A : 65,
|
||||
D: 68
|
||||
};
|
||||
|
||||
var KeyBinding = function(element, host) {
|
||||
|
|
@ -30,6 +31,13 @@ var KeyBinding = function(element, host) {
|
|||
}
|
||||
break;
|
||||
|
||||
case keys.D:
|
||||
if (e.metaKey) {
|
||||
host.removeLine();
|
||||
return ace.stopEvent(e);
|
||||
}
|
||||
break;
|
||||
|
||||
case keys.UP:
|
||||
if (e.metaKey && e.shiftKey) {
|
||||
host.selectFileStart();
|
||||
|
|
@ -165,7 +173,7 @@ ace.Editor = function(doc, renderer) {
|
|||
ace.addListener(container, "dblclick", ace
|
||||
.bind(this.onMouseDoubleClick, this));
|
||||
ace.addMouseWheelListener(container, ace.bind(this.onMouseWheel, this));
|
||||
ace.addTripleClickListener(container, ace.bind(this.selectCurrentLine,
|
||||
ace.addTripleClickListener(container, ace.bind(this.selectLine,
|
||||
this));
|
||||
|
||||
this.doc = doc;
|
||||
|
|
@ -221,7 +229,7 @@ ace.Editor.prototype.onMouseDown = function(e) {
|
|||
this.textInput.focus();
|
||||
|
||||
var pos = this.renderer.screenToTextCoordinates(e.pageX, e.pageY);
|
||||
this.moveCursorTo(pos.row, pos.column);
|
||||
this.moveCursorToPosition(pos);
|
||||
this.setSelectionAnchor(pos.row, pos.column);
|
||||
this.renderer.scrollCursorIntoView();
|
||||
|
||||
|
|
@ -245,7 +253,7 @@ ace.Editor.prototype.onMouseDown = function(e) {
|
|||
mousePageY);
|
||||
|
||||
_self._moveSelection(function() {
|
||||
_self.moveCursorTo(selectionLead.row, selectionLead.column);
|
||||
_self.moveCursorToPosition(selectionLead);
|
||||
});
|
||||
_self.renderer.scrollCursorIntoView();
|
||||
};
|
||||
|
|
@ -311,79 +319,57 @@ ace.Editor.prototype.getCopyText = function() {
|
|||
|
||||
ace.Editor.prototype.onCut = function() {
|
||||
if (this.hasSelection()) {
|
||||
this.cursor = this.doc.remove(this.getSelectionRange());
|
||||
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
|
||||
this.clearSelection();
|
||||
this.renderer.updateCursor(this.cursor);
|
||||
}
|
||||
};
|
||||
|
||||
ace.Editor.prototype.onTextInput = function(text) {
|
||||
if (this.hasSelection()) {
|
||||
this.cursor = this.doc.replace(this.getSelectionRange(), text);
|
||||
this.moveCursorToPosition(this.doc.replace(this.getSelectionRange(), text));
|
||||
this.clearSelection();
|
||||
}
|
||||
else {
|
||||
this.cursor = this.doc.insert(this.cursor, text);
|
||||
this.moveCursorToPosition(this.doc.insert(this.cursor, text));
|
||||
}
|
||||
this.renderer.updateCursor(this.cursor);
|
||||
this.renderer.scrollCursorIntoView();
|
||||
};
|
||||
|
||||
ace.Editor.prototype.removeRight = function() {
|
||||
if (this.hasSelection()) {
|
||||
this.cursor = this.doc.remove(this.getSelectionRange());
|
||||
this.renderer.updateCursor(this.cursor);
|
||||
this.clearSelection();
|
||||
}
|
||||
else {
|
||||
var rangeEnd = {
|
||||
row : this.cursor.row,
|
||||
column : this.cursor.column + 1
|
||||
};
|
||||
if (rangeEnd.column > this.doc.getLine(this.cursor.row).length) {
|
||||
rangeEnd.row += 1;
|
||||
rangeEnd.column = 0;
|
||||
}
|
||||
this.doc.remove( {
|
||||
start : this.cursor,
|
||||
end : renageEnd
|
||||
});
|
||||
if (!this.hasSelection()) {
|
||||
this.selectRight();
|
||||
}
|
||||
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
|
||||
this.clearSelection();
|
||||
|
||||
this.renderer.scrollCursorIntoView();
|
||||
};
|
||||
|
||||
ace.Editor.prototype.removeLeft = function() {
|
||||
if (this.hasSelection()) {
|
||||
this.cursor = this.doc.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
}
|
||||
else {
|
||||
if (this.cursor.row == 0 && this.cursor.column == 0) { return; }
|
||||
ace.Editor.prototype.removeLeft = function() {
|
||||
if (!this.hasSelection()) {
|
||||
this.selectLeft();
|
||||
}
|
||||
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
|
||||
this.clearSelection();
|
||||
|
||||
var rangeStart = {
|
||||
row : this.cursor.row,
|
||||
column : this.cursor.column + -1
|
||||
};
|
||||
if (rangeStart.column < 0) {
|
||||
rangeStart.row -= 1;
|
||||
rangeStart.column = this.doc
|
||||
.getLine(this.cursor.row - 1).length;
|
||||
}
|
||||
this.cursor = this.doc.remove( {
|
||||
start : rangeStart,
|
||||
end : this.cursor
|
||||
});
|
||||
}
|
||||
this.renderer.scrollCursorIntoView();
|
||||
},
|
||||
|
||||
this.renderer.updateCursor(this.cursor);
|
||||
this.renderer.scrollCursorIntoView();
|
||||
},
|
||||
ace.Editor.prototype.removeLine = function() {
|
||||
this.selectLine();
|
||||
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
|
||||
this.clearSelection();
|
||||
|
||||
ace.Editor.prototype.onCompositionStart = function() {
|
||||
this.renderer.showComposition(this.cursor);
|
||||
this.onTextInput(" ");
|
||||
};
|
||||
if (this.cursor.row == this.doc.getLength() - 1) {
|
||||
this.removeLeft();
|
||||
this.moveCursorLineStart();
|
||||
}
|
||||
};
|
||||
|
||||
ace.Editor.prototype.onCompositionStart = function() {
|
||||
this.renderer.showComposition(this.cursor);
|
||||
this.onTextInput(" ");
|
||||
};
|
||||
|
||||
ace.Editor.prototype.onCompositionUpdate = function(text) {
|
||||
this.renderer.setCompositionText(text);
|
||||
|
|
@ -440,7 +426,7 @@ ace.Editor.prototype.navigateDown = function() {
|
|||
ace.Editor.prototype.navigateLeft = function() {
|
||||
if (this.hasSelection()) {
|
||||
var selectionStart = this.getSelectionRange().start;
|
||||
this.moveCursorTo(selectionStart.row, selectionStart.column);
|
||||
this.moveCursorToPosition(selectionStart);
|
||||
}
|
||||
else {
|
||||
this.moveCursorLeft();
|
||||
|
|
@ -453,7 +439,7 @@ ace.Editor.prototype.navigateLeft = function() {
|
|||
ace.Editor.prototype.navigateRight = function() {
|
||||
if (this.hasSelection()) {
|
||||
var selectionEnd = this.getSelectionRange().end;
|
||||
this.moveCursorTo(selectionEnd.row, selectionEnd.column);
|
||||
this.moveCursorToPosition(selectionEnd);
|
||||
}
|
||||
else {
|
||||
this.moveCursorRight();
|
||||
|
|
@ -605,6 +591,11 @@ ace.Editor.prototype.moveCursorBy = function(rows, chars) {
|
|||
this.moveCursorTo(this.cursor.row + rows, this.cursor.column + chars);
|
||||
};
|
||||
|
||||
|
||||
ace.Editor.prototype.moveCursorToPosition = function(position) {
|
||||
this.moveCursorTo(position.row, position.column);
|
||||
};
|
||||
|
||||
ace.Editor.prototype.moveCursorTo = function(row, column) {
|
||||
if (row >= this.doc.getLength()) {
|
||||
this.cursor.row = this.doc.getLength() - 1;
|
||||
|
|
@ -774,7 +765,7 @@ ace.Editor.prototype.selectWordLeft = function() {
|
|||
this._moveSelection(this.moveCursorWordLeft);
|
||||
};
|
||||
|
||||
ace.Editor.prototype.selectCurrentLine = function() {
|
||||
ace.Editor.prototype.selectLine = function() {
|
||||
this.setSelectionAnchor(this.cursor.row, 0);
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(this.cursor.row + 1, 0);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ ace.TextDocument.prototype._split = function(text) {
|
|||
return text.split(/[\n\r]/);
|
||||
};
|
||||
|
||||
ace.TextDocument.prototype.toString = function() {
|
||||
return this.lines.join("\n");
|
||||
};
|
||||
|
||||
ace.TextDocument.prototype.addChangeListener = function(listener) {
|
||||
this.listeners.push(listener);
|
||||
};
|
||||
|
|
@ -19,8 +23,7 @@ ace.TextDocument.prototype.addChangeListener = function(listener) {
|
|||
ace.TextDocument.prototype.fireChangeEvent = function(firstRow, lastRow) {
|
||||
for ( var i = 0; i < this.listeners.length; i++) {
|
||||
this.listeners[i](firstRow, lastRow);
|
||||
}
|
||||
;
|
||||
};
|
||||
};
|
||||
|
||||
ace.TextDocument.prototype.getWidth = function() {
|
||||
|
|
@ -141,12 +144,12 @@ ace.TextDocument.prototype._insert = function(position, text) {
|
|||
};
|
||||
|
||||
ace.TextDocument.prototype.remove = function(range) {
|
||||
var end = this._remove(range);
|
||||
this._remove(range);
|
||||
|
||||
this.fireChangeEvent(range.start.row,
|
||||
range.end.row == range.start.row ? range.start.row
|
||||
: undefined);
|
||||
return end;
|
||||
return range.start;
|
||||
};
|
||||
|
||||
ace.TextDocument.prototype._remove = function(range) {
|
||||
|
|
|
|||
|
|
@ -58,5 +58,8 @@ MockRenderer.prototype.scrollToRow = function(row) {
|
|||
MockRenderer.prototype.draw = function() {
|
||||
};
|
||||
|
||||
MockRenderer.prototype.updateLines = function(startRow, endRow) {
|
||||
};
|
||||
|
||||
MockRenderer.prototype.addMarker = function() {
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,19 +6,12 @@ var NavigationTest = TestCase("NavigationTest",
|
|||
return new ace.TextDocument(text);
|
||||
},
|
||||
|
||||
assertPosition : function(row, column, cursor) {
|
||||
assertEquals(row, cursor.row);
|
||||
assertEquals(column, cursor.column);
|
||||
},
|
||||
|
||||
// End of file, start of files tests
|
||||
|
||||
"test: navigate to end of file should place the cursor on last row and column" : function() {
|
||||
var editor = new ace.Editor(this.createTextDocument(200, 10),
|
||||
new MockRenderer());
|
||||
|
||||
editor.navigateFileEnd();
|
||||
this.assertPosition(199, 10, editor.getCursorPosition());
|
||||
assertPosition(199, 10, editor.getCursorPosition());
|
||||
},
|
||||
|
||||
"test: navigate to end of file should scroll the last line into view" : function() {
|
||||
|
|
@ -37,7 +30,7 @@ var NavigationTest = TestCase("NavigationTest",
|
|||
new MockRenderer());
|
||||
|
||||
editor.navigateFileStart();
|
||||
this.assertPosition(0, 0, editor.getCursorPosition());
|
||||
assertPosition(0, 0, editor.getCursorPosition());
|
||||
},
|
||||
|
||||
"test: navigate to start of file should scroll the first row into view" : function() {
|
||||
|
|
@ -59,8 +52,8 @@ var NavigationTest = TestCase("NavigationTest",
|
|||
|
||||
var selection = editor.getSelectionRange();
|
||||
|
||||
this.assertPosition(100, 5, selection.start);
|
||||
this.assertPosition(199, 10, selection.end);
|
||||
assertPosition(100, 5, selection.start);
|
||||
assertPosition(199, 10, selection.end);
|
||||
},
|
||||
|
||||
"test: move selection lead to start of file" : function() {
|
||||
|
|
@ -72,8 +65,8 @@ var NavigationTest = TestCase("NavigationTest",
|
|||
|
||||
var selection = editor.getSelectionRange();
|
||||
|
||||
this.assertPosition(0, 0, selection.start);
|
||||
this.assertPosition(100, 5, selection.end);
|
||||
assertPosition(0, 0, selection.start);
|
||||
assertPosition(100, 5, selection.end);
|
||||
},
|
||||
|
||||
"test: navigate word right" : function() {
|
||||
|
|
@ -82,38 +75,38 @@ var NavigationTest = TestCase("NavigationTest",
|
|||
var editor = new ace.Editor(doc, new MockRenderer());
|
||||
|
||||
editor.navigateDown();
|
||||
this.assertPosition(1, 0, editor.getCursorPosition());
|
||||
assertPosition(1, 0, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(1, 1, editor.getCursorPosition());
|
||||
assertPosition(1, 1, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(1, 5, editor.getCursorPosition());
|
||||
assertPosition(1, 5, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(1, 6, editor.getCursorPosition());
|
||||
assertPosition(1, 6, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(1, 13, editor.getCursorPosition());
|
||||
assertPosition(1, 13, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(1, 15, editor.getCursorPosition());
|
||||
assertPosition(1, 15, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(1, 18, editor.getCursorPosition());
|
||||
assertPosition(1, 18, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(1, 20, editor.getCursorPosition());
|
||||
assertPosition(1, 20, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(1, 22, editor.getCursorPosition());
|
||||
assertPosition(1, 22, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(1, 23, editor.getCursorPosition());
|
||||
assertPosition(1, 23, editor.getCursorPosition());
|
||||
|
||||
// wrap line
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(2, 0, editor.getCursorPosition());
|
||||
assertPosition(2, 0, editor.getCursorPosition());
|
||||
},
|
||||
|
||||
"test: select word right if cursor in word" : function() {
|
||||
|
|
@ -123,7 +116,7 @@ var NavigationTest = TestCase("NavigationTest",
|
|||
editor.moveCursorTo(0, 2);
|
||||
|
||||
editor.navigateWordRight();
|
||||
this.assertPosition(0, 4, editor.getCursorPosition());
|
||||
assertPosition(0, 4, editor.getCursorPosition());
|
||||
},
|
||||
|
||||
"test: navigate word left" : function() {
|
||||
|
|
@ -133,38 +126,38 @@ var NavigationTest = TestCase("NavigationTest",
|
|||
|
||||
editor.navigateDown();
|
||||
editor.navigateLineEnd();
|
||||
this.assertPosition(1, 23, editor.getCursorPosition());
|
||||
assertPosition(1, 23, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(1, 22, editor.getCursorPosition());
|
||||
assertPosition(1, 22, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(1, 20, editor.getCursorPosition());
|
||||
assertPosition(1, 20, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(1, 18, editor.getCursorPosition());
|
||||
assertPosition(1, 18, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(1, 15, editor.getCursorPosition());
|
||||
assertPosition(1, 15, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(1, 13, editor.getCursorPosition());
|
||||
assertPosition(1, 13, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(1, 6, editor.getCursorPosition());
|
||||
assertPosition(1, 6, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(1, 5, editor.getCursorPosition());
|
||||
assertPosition(1, 5, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(1, 1, editor.getCursorPosition());
|
||||
assertPosition(1, 1, editor.getCursorPosition());
|
||||
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(1, 0, editor.getCursorPosition());
|
||||
assertPosition(1, 0, editor.getCursorPosition());
|
||||
|
||||
// wrap line
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(0, 2, editor.getCursorPosition());
|
||||
assertPosition(0, 2, editor.getCursorPosition());
|
||||
},
|
||||
|
||||
"test: select word left if cursor in word" : function() {
|
||||
|
|
@ -174,7 +167,7 @@ var NavigationTest = TestCase("NavigationTest",
|
|||
editor.moveCursorTo(0, 8);
|
||||
|
||||
editor.navigateWordLeft();
|
||||
this.assertPosition(0, 5, editor.getCursorPosition());
|
||||
assertPosition(0, 5, editor.getCursorPosition());
|
||||
},
|
||||
|
||||
"test: select word right and select" : function() {
|
||||
|
|
@ -186,8 +179,8 @@ var NavigationTest = TestCase("NavigationTest",
|
|||
|
||||
var selection = editor.getSelectionRange();
|
||||
|
||||
this.assertPosition(0, 0, selection.start);
|
||||
this.assertPosition(0, 4, selection.end);
|
||||
assertPosition(0, 0, selection.start);
|
||||
assertPosition(0, 4, selection.end);
|
||||
},
|
||||
|
||||
"test: select word left and select" : function() {
|
||||
|
|
@ -199,7 +192,7 @@ var NavigationTest = TestCase("NavigationTest",
|
|||
|
||||
var selection = editor.getSelectionRange();
|
||||
|
||||
this.assertPosition(0, 0, selection.start);
|
||||
this.assertPosition(0, 3, selection.end);
|
||||
assertPosition(0, 0, selection.start);
|
||||
assertPosition(0, 3, selection.end);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
34
test/TextEditTest.js
Normal file
34
test/TextEditTest.js
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
var TextEditTest = TestCase("TextEditTest",
|
||||
{
|
||||
"test: delete line from the middle" : function() {
|
||||
var doc = new ace.TextDocument(["a", "b", "c", "d"].join("\n"));
|
||||
var editor = new ace.Editor(doc, new MockRenderer());
|
||||
|
||||
editor.moveCursorTo(1, 1);
|
||||
editor.removeLine();
|
||||
|
||||
assertEquals("a\nc\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(doc, new MockRenderer());
|
||||
|
||||
editor.removeLine();
|
||||
|
||||
assertEquals("b\nc", doc.toString());
|
||||
assertPosition(0, 0, editor.getCursorPosition());
|
||||
},
|
||||
|
||||
"test: delete last" : function() {
|
||||
var doc = new ace.TextDocument(["a", "b", "c"].join("\n"));
|
||||
var editor = new ace.Editor(doc, new MockRenderer());
|
||||
|
||||
editor.moveCursorTo(2, 1);
|
||||
editor.removeLine();
|
||||
|
||||
assertEquals("a\nb", doc.toString());
|
||||
assertPosition(1, 0, editor.getCursorPosition());
|
||||
}
|
||||
});
|
||||
4
test/assertions.js
Normal file
4
test/assertions.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
assertPosition = function(row, column, cursor) {
|
||||
assertEquals(row, cursor.row);
|
||||
assertEquals(column, cursor.column);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue