first support for auto indent

This commit is contained in:
Fabian Jakobs 2010-04-14 19:15:52 +02:00
commit e9fe18f657
8 changed files with 129 additions and 25 deletions

View file

@ -77,14 +77,20 @@ ace.BackgroundTokenizer.prototype.stop = function() {
};
ace.BackgroundTokenizer.prototype.getTokens = function(row) {
if (this.lines[row]) {
return this.lines[row].tokens;
}
else {
return this._tokenizeRow(row).tokens;
};
ace.BackgroundTokenizer.prototype.getState = function(row) {
return this._tokenizeRow(row).state;
};
ace.BackgroundTokenizer.prototype._tokenizeRow = function(row) {
if (!this.lines[row]) {
var state = "start";
if (row > 0 && this.lines[row - 1]) {
state = this.lines[row - 1].state;
}
return this.tokenizer.getLineTokens(this.textLines[row] || "", state).tokens;
this.lines[row] = this.tokenizer.getLineTokens(this.textLines[row] || "", state);
}
return this.lines[row];
};

View file

@ -221,15 +221,40 @@ ace.Editor.prototype.onCut = function() {
ace.Editor.prototype.onTextInput = function(text) {
if (this.hasSelection()) {
this.moveCursorToPosition(this.doc.replace(this.getSelectionRange(), text));
var end = this.doc.replace(this.getSelectionRange(), text);
this.clearSelection();
}
else {
this.moveCursorToPosition(this.doc.insert(this.cursor, text));
var end = this.doc.insert(this.cursor, text);
}
// multi line insert
var row = this.cursor.row;
if (row !== end.row) {
var line = this.doc.getLine(row);
var lineState = this.bgTokenizer.getState(row);
var indent = this.mode.getNextLineIndent(line, lineState, this.getTabString());
if (indent) {
var indentRange = {
start: {
row: row+1,
column: 0
},
end : end
};
end.column += this.doc.indentRows(indentRange, indent);
}
}
this.moveCursorToPosition(end);
this.renderer.scrollCursorIntoView();
};
ace.Editor.prototype.getTabString = function() {
return " ";
};
ace.Editor.prototype.removeRight = function() {
if (!this.hasSelection()) {
this.selectRight();
@ -262,18 +287,14 @@ ace.Editor.prototype.removeLine = function() {
};
ace.Editor.prototype.blockIndent = function(indentString) {
if (!this.hasSelection()) return;
var indentString = indentString || " ";
var indentString = indentString || this.getTabString();
var addedColumns = this.doc.indentRows(this.getSelectionRange(), indentString);
this.shiftSelection(addedColumns);
};
ace.Editor.prototype.blockOutdent = function(indentString) {
if (!this.hasSelection()) return;
var indentString = indentString || " ";
var indentString = indentString || this.getTabString();
var addedColumns = this.doc.outdentRows(this.getSelectionRange(), indentString);
this.shiftSelection(addedColumns);
@ -626,7 +647,10 @@ ace.Editor.prototype.getSelectionAnchor = function() {
column: this.selectionAnchor.column
};
} else {
return null;
return {
row: this.cursor.row,
column: this.cursor.column
};
}
};
@ -637,12 +661,18 @@ ace.Editor.prototype.getSelectionLead = function() {
column: this.selectionLead.column
};
} else {
return null;
return {
row: this.cursor.row,
column: this.cursor.column
};
}
};
ace.Editor.prototype.shiftSelection = function(columns) {
if (!this.hasSelection()) return;
if (!this.hasSelection()) {
this.moveCursorTo(this.cursor.row, this.cursor.column + columns);
return;
};
var anchor = this.getSelectionAnchor();
var lead = this.getSelectionLead();

View file

@ -179,14 +179,12 @@ ace.KeyBinding = function(element, host) {
return ace.stopEvent(e);
case keys.TAB:
if (host.hasMultiLineSelection()) {
if (e.shiftKey) {
host.blockOutdent();
} else {
host.blockIndent();
}
if (e.shiftKey) {
host.blockOutdent();
} else if (host.hasMultiLineSelection()) {
host.blockIndent();
} else {
host.onTextInput(" ");
host.onTextInput(host.getTabString());
}
return ace.stopEvent(e);
}

View file

@ -11,4 +11,25 @@ ace.mode.JavaScript.prototype.toggleCommentLines = function(doc, range) {
var addedRows = doc.indentRows(range, "//");
};
return addedRows;
};
ace.mode.JavaScript.prototype.increaseIndentPatterns = {
"start" : /^(\s*).*[\{\(\[]\s*$/
};
ace.mode.JavaScript.prototype.getNextLineIndent = function(line, state, tab) {
var re = this.increaseIndentPatterns[state];
if (!re) return
var match = line.match(re);
if (match) {
return (match[1] || "") + tab;
}
var match = line.match(/^(\s+).*$/);
if (match) {
return match[1];
}
return "";
};

View file

@ -76,8 +76,8 @@ ace.mode.JavaScriptHighlightRules = function() {
token : function(value) {
// return parens[value];
return "text";
},
regex : "[\\[\\]\\(\\)\\{\\}]"
},
regex : "[\\[\\]\\(\\)\\{\\}]"
}, {
token : "text",
regex : "\\s+"

View file

@ -16,4 +16,8 @@ ace.mode.Text.prototype.getTokenizer = function() {
ace.mode.Text.prototype.toggleCommentLines = function(doc, range) {
return 0;
};
ace.mode.Text.prototype.getNextLineIndent = function(line, state, tab) {
return "";
};

View file

@ -44,6 +44,8 @@ var TextEditTest = TestCase("TextEditTest",
assertEquals(["a12345", " b12345", " c12345"].join("\n"),
doc.toString());
assertPosition(2, 7, editor.getCursorPosition());
var selection = editor.getSelectionRange();
assertPosition(1, 7, selection.start);
assertPosition(2, 7, selection.end);
@ -61,6 +63,8 @@ var TextEditTest = TestCase("TextEditTest",
assertEquals([" a12345", "b12345", " c12345"].join("\n"),
doc.toString());
assertPosition(2, 1, editor.getCursorPosition());
var selection = editor.getSelectionRange();
assertPosition(0, 1, selection.start);
assertPosition(2, 1, selection.end);
@ -75,6 +79,17 @@ var TextEditTest = TestCase("TextEditTest",
assertPosition(2, 1, selection.end);
},
"test: outent without a selection should update cursor" : function() {
var doc = new ace.TextDocument(" 12");
var editor = new ace.Editor(new MockRenderer(), doc);
editor.moveCursorTo(0, 3);
editor.blockOutdent(" ");
assertEquals(" 12", doc.toString());
assertPosition(0, 1, editor.getCursorPosition());
},
"test: comment lines should perserve selection" : function() {
var doc = new ace.TextDocument([" abc", "cde"].join("\n"));
var editor = new ace.Editor(new MockRenderer(), doc, new ace.mode.JavaScript());

View file

@ -47,5 +47,35 @@ var JavaScriptTest = new TestCase("mode.JavaScriptTest", {
var comment = this.mode.toggleCommentLines(doc, range);
assertEquals(["//// abc", "////cde", "//fg"].join("\n"), doc.toString());
},
"test: auto indent after opening brace" : function() {
var doc = new ace.TextDocument(["if () {"].join("\n"));
var editor = new ace.Editor(new MockRenderer(), doc, this.mode);
editor.navigateLineEnd();
editor.onTextInput("\n");
assertEquals(["if () {", editor.getTabString()].join("\n"), doc.toString());
},
"test: no auto indent after opening brace in multi line comment" : function() {
var doc = new ace.TextDocument(["/*if () {"].join("\n"));
var editor = new ace.Editor(new MockRenderer(), doc, this.mode);
editor.navigateLineEnd();
editor.onTextInput("\n");
assertEquals(["/*if () {", ""].join("\n"), doc.toString());
},
"test: no auto indent should add to existing indent" : function() {
var doc = new ace.TextDocument([" if () {"].join("\n"));
var editor = new ace.Editor(new MockRenderer(), doc, this.mode);
editor.navigateLineEnd();
editor.onTextInput("\n");
assertEquals([" if () {", " " + editor.getTabString()].join("\n"), doc.toString());
}
});