Fixed outdenting to work correctly with blocks that are separated by newlines, and indented by a mixture of tabs and spaces.
This commit is contained in:
parent
9a8bb6cbf3
commit
1b88d3f45a
3 changed files with 39 additions and 50 deletions
|
|
@ -249,21 +249,10 @@ var Document = function(text, mode) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a verbatim copy of the given line as it is in the document
|
|
||||||
*/
|
|
||||||
this.getLine = function(row) {
|
this.getLine = function(row) {
|
||||||
return this.lines[row] || "";
|
return this.lines[row] || "";
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a line as it is displayed on screen. Tabs are replaced by spaces.
|
|
||||||
*/
|
|
||||||
this.getDisplayLine = function(row) {
|
|
||||||
var tab = new Array(this.getTabSize()+1).join(" ");
|
|
||||||
return this.lines[row].replace(/\t/g, tab);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getLines = function(firstRow, lastRow) {
|
this.getLines = function(firstRow, lastRow) {
|
||||||
return this.lines.slice(firstRow, lastRow+1);
|
return this.lines.slice(firstRow, lastRow+1);
|
||||||
};
|
};
|
||||||
|
|
@ -564,27 +553,34 @@ var Document = function(text, mode) {
|
||||||
return indentString.length;
|
return indentString.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.outdentRows = function(range, indentString) {
|
this.outdentRows = function (range) {
|
||||||
outdentLength = indentString.length;
|
var deleteRange = new Range(0, 0, 0, 0),
|
||||||
|
size = this.getTabSize();
|
||||||
for (var i=range.start.row; i<= range.end.row; i++) {
|
|
||||||
if (this.getLine(i).substr(0, outdentLength) !== indentString) {
|
for (var i = range.start.row; i <= range.end.row; ++i) {
|
||||||
return 0;
|
var line = this.getLine(i);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var deleteRange = new Range(0, 0, 0, outdentLength);
|
|
||||||
|
|
||||||
for (var i=range.start.row; i<= range.end.row; i++)
|
|
||||||
{
|
|
||||||
deleteRange.start.row = i;
|
deleteRange.start.row = i;
|
||||||
deleteRange.end.row = i;
|
deleteRange.end.row = i;
|
||||||
|
for (var j = 0; j < size; ++j)
|
||||||
|
if (line.charAt(j) != ' ')
|
||||||
|
break;
|
||||||
|
if (j < size && line.charAt(j) == '\t') {
|
||||||
|
deleteRange.start.column = j;
|
||||||
|
deleteRange.end.column = j + 1;
|
||||||
|
} else {
|
||||||
|
deleteRange.start.column = 0;
|
||||||
|
deleteRange.end.column = j;
|
||||||
|
}
|
||||||
|
if (i == range.start.row)
|
||||||
|
range.start.column -= deleteRange.end.column - deleteRange.start.column;
|
||||||
|
if (i == range.end.row)
|
||||||
|
range.end.column -= deleteRange.end.column - deleteRange.start.column;
|
||||||
this.$remove(deleteRange);
|
this.$remove(deleteRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fireChangeEvent(range.start.row, range.end.row);
|
this.fireChangeEvent(range.start.row, range.end.row);
|
||||||
return -outdentLength;
|
return range;
|
||||||
};
|
}
|
||||||
|
|
||||||
this.moveLinesUp = function(firstRow, lastRow) {
|
this.moveLinesUp = function(firstRow, lastRow) {
|
||||||
if (firstRow <= 0) return 0;
|
if (firstRow <= 0) return 0;
|
||||||
|
|
|
||||||
|
|
@ -552,14 +552,10 @@ var Editor = function(renderer, doc) {
|
||||||
if (this.$readOnly)
|
if (this.$readOnly)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var indentString = indentString || this.doc.getTabString();
|
var selection = this.doc.getSelection(),
|
||||||
var addedColumns = this.doc.outdentRows(this.getSelectionRange(), indentString);
|
range = this.doc.outdentRows(selection.getRange());
|
||||||
|
|
||||||
// besides the indent string also outdent tabs
|
selection.setSelectionRange(range, selection.isBackwards());
|
||||||
if (addedColumns == 0 && indentString != "\t")
|
|
||||||
var addedColumns = this.doc.outdentRows(this.getSelectionRange(), "\t");
|
|
||||||
|
|
||||||
this.selection.shiftSelection(addedColumns);
|
|
||||||
this.$updateDesiredColumn();
|
this.$updateDesiredColumn();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ var Selection = function(doc) {
|
||||||
var anchor = this.getSelectionAnchor();
|
var anchor = this.getSelectionAnchor();
|
||||||
var lead = this.getSelectionLead();
|
var lead = this.getSelectionLead();
|
||||||
|
|
||||||
var isBackwards = this.$isBackwards();
|
var isBackwards = this.isBackwards();
|
||||||
|
|
||||||
if (!isBackwards || anchor.column !== 0)
|
if (!isBackwards || anchor.column !== 0)
|
||||||
this.setSelectionAnchor(anchor.row, anchor.column + columns);
|
this.setSelectionAnchor(anchor.row, anchor.column + columns);
|
||||||
|
|
@ -91,7 +91,7 @@ var Selection = function(doc) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$isBackwards = function() {
|
this.isBackwards = function() {
|
||||||
var anchor = this.selectionAnchor || this.selectionLead;
|
var anchor = this.selectionAnchor || this.selectionLead;
|
||||||
var lead = this.selectionLead;
|
var lead = this.selectionLead;
|
||||||
return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
|
return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
|
||||||
|
|
@ -101,7 +101,7 @@ var Selection = function(doc) {
|
||||||
var anchor = this.selectionAnchor || this.selectionLead;
|
var anchor = this.selectionAnchor || this.selectionLead;
|
||||||
var lead = this.selectionLead;
|
var lead = this.selectionLead;
|
||||||
|
|
||||||
if (this.$isBackwards()) {
|
if (this.isBackwards()) {
|
||||||
return Range.fromPoints(lead, anchor);
|
return Range.fromPoints(lead, anchor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -116,7 +116,6 @@ var Selection = function(doc) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.selectAll = function() {
|
this.selectAll = function() {
|
||||||
var lastRow = this.doc.getLength() - 1;
|
var lastRow = this.doc.getLength() - 1;
|
||||||
this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length);
|
this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length);
|
||||||
|
|
@ -126,9 +125,14 @@ var Selection = function(doc) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setSelectionRange = function(range) {
|
this.setSelectionRange = function(range, reverse) {
|
||||||
this.setSelectionAnchor(range.start.row, range.start.column);
|
if (reverse) {
|
||||||
this.selectTo(range.end.row, range.end.column);
|
this.setSelectionAnchor(range.end.row, range.end.column);
|
||||||
|
this.selectTo(range.start.row, range.start.column);
|
||||||
|
} else {
|
||||||
|
this.setSelectionAnchor(range.start.row, range.start.column);
|
||||||
|
this.selectTo(range.end.row, range.end.column);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$moveSelection = function(mover) {
|
this.$moveSelection = function(mover) {
|
||||||
|
|
@ -281,14 +285,7 @@ var Selection = function(doc) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.moveCursorLineStart = function() {
|
this.moveCursorLineStart = function() {
|
||||||
var row = this.selectionLead.row;
|
this.moveCursorTo(this.selectionLead.row, 0);
|
||||||
var column = this.selectionLead.column;
|
|
||||||
var beforeCursor = this.doc.getDisplayLine(row).slice(0, column);
|
|
||||||
var leadingSpace = beforeCursor.match(/^\s+/);
|
|
||||||
if (!leadingSpace || leadingSpace[0].length >= column)
|
|
||||||
this.moveCursorTo(this.selectionLead.row, 0);
|
|
||||||
else
|
|
||||||
this.moveCursorTo(this.selectionLead.row, leadingSpace[0].length);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.moveCursorLineEnd = function() {
|
this.moveCursorLineEnd = function() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue