add indent/outdent support

This commit is contained in:
Fabian Jakobs 2010-04-12 17:11:09 +02:00
commit 879539f32a
3 changed files with 117 additions and 1 deletions

View file

@ -155,7 +155,15 @@ var KeyBinding = function(element, host) {
return ace.stopEvent(e);
case keys.TAB:
host.onTextInput(" ");
if (host.hasMultiLineSelection()) {
if (e.shiftKey) {
host.blockOutdent();
} else {
host.blockIndent();
}
} else {
host.onTextInput(" ");
}
return ace.stopEvent(e);
}
});
@ -366,6 +374,38 @@ ace.Editor.prototype.removeLine = function() {
}
};
ace.Editor.prototype.blockIndent = function(indentString) {
if (!this.hasSelection()) {
return;
};
var range = this.getSelectionRange();
var indentString = indentString || " ";
this.doc.indentRows(range, indentString);
this.setSelectionAnchor(range.start.row, range.start.column + indentString.length);
this._moveSelection(function() {
this.moveCursorTo(range.end.row, range.end.column + indentString.length);
});
};
ace.Editor.prototype.blockOutdent = function(indentString) {
if (!this.hasSelection()) {
return;
};
var range = this.getSelectionRange();
var indentString = indentString || " ";
var removedColumns = this.doc.outdentRows(range, indentString);
this.setSelectionAnchor(range.start.row, range.start.column - removedColumns);
this._moveSelection(function() {
this.moveCursorTo(range.end.row, range.end.column - removedColumns);
});
};
ace.Editor.prototype.onCompositionStart = function() {
this.renderer.showComposition(this.cursor);
this.onTextInput(" ");
@ -625,6 +665,15 @@ ace.Editor.prototype.hasSelection = function() {
return !!this.selectionLead;
};
ace.Editor.prototype.hasMultiLineSelection = function() {
if (!this.hasSelection()) {
return false;
}
var range = this.getSelectionRange();
return (range.start.row !== range.end.row);
};
ace.Editor.prototype.setSelectionAnchor = function(row, column) {
this.clearSelection();

View file

@ -181,4 +181,28 @@ ace.TextDocument.prototype.replace = function(range, text) {
: undefined);
return end;
};
ace.TextDocument.prototype.indentRows = function(range, indentString) {
for (var i=range.start.row; i<= range.end.row; i++) {
this.lines[i] = indentString + this.getLine(i);
}
this.fireChangeEvent(range.start.row, range.end.row);
};
ace.TextDocument.prototype.outdentRows = function(range, indentString) {
outdentLength = indentString.length;
for (var i=range.start.row; i<= range.end.row; i++) {
if (this.getLine(i).substr(0, outdentLength) !== indentString) {
return 0;
}
}
for (var i=range.start.row; i<= range.end.row; i++) {
this.lines[i] = this.getLine(i).substring(outdentLength);
}
this.fireChangeEvent(range.start.row, range.end.row);
return outdentLength;
};

View file

@ -30,5 +30,48 @@ var TextEditTest = TestCase("TextEditTest",
assertEquals("a\nb", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
},
"test: indent block" : function() {
var doc = new ace.TextDocument(["a12345", "b12345", "c12345"].join("\n"));
var editor = new ace.Editor(doc, new MockRenderer());
editor.moveCursorTo(1, 3);
editor.selectDown();
editor.blockIndent(" ");
assertEquals(["a12345", " b12345", " c12345"].join("\n"),
doc.toString());
var selection = editor.getSelectionRange();
assertPosition(1, 7, selection.start);
assertPosition(2, 7, selection.end);
},
"test: outdent block" : function() {
var doc = new ace.TextDocument([" a12345", " b12345", " c12345"].join("\n"));
var editor = new ace.Editor(doc, new MockRenderer());
editor.moveCursorTo(0, 3);
editor.selectDown();
editor.selectDown();
editor.blockOutdent(" ");
assertEquals([" a12345", "b12345", " c12345"].join("\n"),
doc.toString());
var selection = editor.getSelectionRange();
assertPosition(0, 1, selection.start);
assertPosition(2, 1, selection.end);
editor.blockOutdent(" ");
assertEquals([" a12345", "b12345", " c12345"].join("\n"),
doc.toString());
var selection = editor.getSelectionRange();
assertPosition(0, 1, selection.start);
assertPosition(2, 1, selection.end);
}
});