Merge pull request #243 from nightwing/pullreq

fixed several annoying bugs
This commit is contained in:
Fabian Jakobs 2011-05-16 06:09:07 -07:00
commit ec986e2f28
11 changed files with 205 additions and 66 deletions

View file

@ -376,8 +376,8 @@ exports.launch = function(env) {
mode = "python"; mode = "python";
} else if (/^.*\.php$/i.test(file.name)) { } else if (/^.*\.php$/i.test(file.name)) {
mode = "php"; mode = "php";
} else if (/^.*\.cs$/i.test(file.name)) { } else if (/^.*\.cs$/i.test(file.name)) {
mode = "csharp"; mode = "csharp";
} else if (/^.*\.java$/i.test(file.name)) { } else if (/^.*\.java$/i.test(file.name)) {
mode = "java"; mode = "java";
} else if (/^.*\.rb$/i.test(file.name)) { } else if (/^.*\.rb$/i.test(file.name)) {
@ -474,28 +474,58 @@ exports.launch = function(env) {
mac: "Alt-L", mac: "Alt-L",
sender: "editor" sender: "editor"
}, },
exec: function() { exec: function(env) {
var session = env.editor.session, toggleFold(env, false)
range = env.editor.selection.getRange(),
placeHolder = session.getTextRange(range).substring(0, 3) + "...";
session.addFold(placeHolder, range);
} }
}); });
canon.addCommand({ canon.addCommand({
name: "undfold", name: "unfold",
bindKey: { bindKey: {
win: "Alt-Shift-L", win: "Alt-Shift-L",
mac: "Alt-Shift-L", mac: "Alt-Shift-L",
sender: "editor" sender: "editor"
}, },
exec: function() { exec: function(env) {
var session = env.editor.session, toggleFold(env, true)
range = env.editor.selection.getRange();
session.expandFolds(session.getFoldsInRange(range));
} }
}); });
function toggleFold(env, tryToUnfold) {
var session = env.editor.session,
selection = env.editor.selection,
range = selection.getRange(), addFold;
if(range.isEmpty()) {
var br = session.findMatchingBracket(range.start);
var fold = session.getFoldAt(range.start.row, range.start.column)
if(fold) {
session.expandFold(fold);
selection.setSelectionRange(fold.range)
} else if(br) {
if(range.compare(br.row,br.column) == 1)
range.end = br;
else
range.start = br;
addFold = true;
}
} else {
var folds = session.getFoldsInRange(range);
if(tryToUnfold && folds.length)
session.expandFolds(folds);
else if(folds.length == 1 && folds[0].range.compare(range) == 0)
session.expandFolds(folds);
else
addFold = true;
}
if(addFold) {
var placeHolder = session.getTextRange(range);
if(placeHolder.length < 3)
return;
placeHolder = placeHolder.trim().substring(0, 3).replace(' ','','g') + "...";
session.addFold(placeHolder, range);
}
}
}; };
}); });

View file

@ -152,7 +152,7 @@ canon.addCommand({
}); });
canon.addCommand({ canon.addCommand({
name: "selecttostart", name: "selecttostart",
bindKey: bindKey("Alt-Shift-Up", "Command-Shift-Up"), bindKey: bindKey("Ctrl-Shift-Home|Alt-Shift-Up", "Command-Shift-Up"),
exec: function(env, args, request) { env.editor.getSelection().selectFileStart(); } exec: function(env, args, request) { env.editor.getSelection().selectFileStart(); }
}); });
canon.addCommand({ canon.addCommand({
@ -182,7 +182,7 @@ canon.addCommand({
}); });
canon.addCommand({ canon.addCommand({
name: "selecttoend", name: "selecttoend",
bindKey: bindKey("Alt-Shift-Down", "Command-Shift-Down"), bindKey: bindKey("Ctrl-Shift-End|Alt-Shift-Down", "Command-Shift-Down"),
exec: function(env, args, request) { env.editor.getSelection().selectFileEnd(); } exec: function(env, args, request) { env.editor.getSelection().selectFileEnd(); }
}); });
canon.addCommand({ canon.addCommand({

View file

@ -123,6 +123,7 @@
.ace_marker-layer { .ace_marker-layer {
cursor: text; cursor: text;
pointer-events: none;
} }
.ace_marker-layer .ace_step { .ace_marker-layer .ace_step {

View file

@ -691,7 +691,7 @@ var EditSession = function(text, mode) {
if (delta.group == "doc") { if (delta.group == "doc") {
this.doc.revertDeltas(delta.deltas); this.doc.revertDeltas(delta.deltas);
lastUndoRange = lastUndoRange =
this.$setUndoSelection(delta.deltas, true, lastUndoRange); this.$getUndoSelection(delta.deltas, true, lastUndoRange);
} else { } else {
delta.deltas.forEach(function(foldDelta) { delta.deltas.forEach(function(foldDelta) {
this.addFolds(foldDelta.folds); this.addFolds(foldDelta.folds);
@ -699,6 +699,7 @@ var EditSession = function(text, mode) {
} }
} }
this.$fromUndo = false; this.$fromUndo = false;
lastUndoRange && this.selection.setSelectionRange(lastUndoRange);
}, },
this.redoChanges = function(deltas) { this.redoChanges = function(deltas) {
@ -712,13 +713,14 @@ var EditSession = function(text, mode) {
if (delta.group == "doc") { if (delta.group == "doc") {
this.doc.applyDeltas(delta.deltas); this.doc.applyDeltas(delta.deltas);
lastUndoRange = lastUndoRange =
this.$setUndoSelection(delta.deltas, false, lastUndoRange); this.$getUndoSelection(delta.deltas, false, lastUndoRange);
} }
} }
this.$fromUndo = false; this.$fromUndo = false;
lastUndoRange && this.selection.setSelectionRange(lastUndoRange);
}, },
this.$setUndoSelection = function(deltas, isUndo, lastUndoRange) { this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) {
function isInsert(delta) { function isInsert(delta) {
var insert = var insert =
delta.action == "insertText" || delta.action == "insertLines"; delta.action == "insertText" || delta.action == "insertLines";
@ -726,7 +728,7 @@ var EditSession = function(text, mode) {
} }
var delta = deltas[0]; var delta = deltas[0];
var range; var range, point;
var lastDeltaIsInsert = false; var lastDeltaIsInsert = false;
if (isInsert(delta)) { if (isInsert(delta)) {
range = delta.range.clone(); range = delta.range.clone();
@ -739,15 +741,18 @@ var EditSession = function(text, mode) {
for (var i = 1; i < deltas.length; i++) { for (var i = 1; i < deltas.length; i++) {
delta = deltas[i]; delta = deltas[i];
if (isInsert(delta)) { if (isInsert(delta)) {
if (range.compare(delta.range.start) == -1) { point = delta.range.start;
if (range.compare(point.row, point.column) == -1) {
range.setStart(delta.range.start); range.setStart(delta.range.start);
} }
if (range.compare(delta.range.end) == 1) { point = delta.range.end;
if (range.compare(point.row, point.column) == 1) {
range.setEnd(delta.range.end); range.setEnd(delta.range.end);
} }
lastDeltaIsInsert = true; lastDeltaIsInsert = true;
} else { } else {
if (range.compare(delta.range.start) == -1) { point = delta.range.start;
if (range.compare(point.row, point.column) == -1) {
range = range =
Range.fromPoints(delta.range.start, delta.range.start); Range.fromPoints(delta.range.start, delta.range.start);
} }
@ -766,11 +771,6 @@ var EditSession = function(text, mode) {
} }
} }
if (!range.isEmpty()) {
this.selection.setSelectionRange(range);
} else {
this.selection.moveCursorToPosition(range.start);
}
return range; return range;
}, },
@ -1389,12 +1389,10 @@ var EditSession = function(text, mode) {
var docRow = 0; var docRow = 0;
var docColumn = 0; var docColumn = 0;
var column; var column;
var foldLine;
var foldLineRowLength; var foldLineRowLength;
var row = 0; var row = 0;
var rowLength = 0; var rowLength = 0;
var splits = null; var splits = null;
var split = 0;
var rowCache = this.$rowCache; var rowCache = this.$rowCache;
var doCache = !rowCache.length; var doCache = !rowCache.length;
@ -1406,6 +1404,11 @@ var EditSession = function(text, mode) {
} }
} }
var docRowCacheLast = docRow; var docRowCacheLast = docRow;
// clamp row before clamping column, for selection on last line
var maxRow = this.getLength() - 1;
var foldLine = this.getNextFold(docRow);
var foldStart = foldLine ?foldLine.start.row :Infinity;
while (row <= screenRow) { while (row <= screenRow) {
if (doCache if (doCache
@ -1417,30 +1420,41 @@ var EditSession = function(text, mode) {
docRowCacheLast = docRow; docRowCacheLast = docRow;
} }
rowLength = this.getRowLength(docRow); rowLength = this.getRowLength(docRow);
if (row + rowLength - 1 >= screenRow) { if (row + rowLength - 1 >= screenRow || docRow >= maxRow) {
break; break;
} else { } else {
row += rowLength; row += rowLength;
docRow = this.getRowFoldEnd(docRow) + 1; docRow++;
if(docRow > foldStart) {
docRow = foldLine.end.row+1;
foldLine = this.getNextFold(docRow);
foldStart = foldLine ?foldLine.start.row :Infinity;
}
} }
} }
splits = this.$wrapData[docRow] || []; if (foldLine && foldLine.start.row <= docRow)
foldLine = this.getFoldLine(docRow); line = this.getFoldDisplayLine(foldLine);
line = foldLine else {
? this.getFoldDisplayLine(foldLine) line = this.getLine(docRow);
: this.getLine(docRow); foldLine = null;
}
if (this.$useWrapMode) { if (this.$useWrapMode) {
docColumn = split = splits[screenRow - row - 1] || 0; splits = this.$wrapData[docRow];
line = line.substring(split); if (splits) {
column = splits[screenRow - row]
if(screenRow > row && splits.length) {
docColumn = splits[screenRow - row - 1] || splits[splits.length - 1];
line = line.substring(docColumn);
}
}
} }
docColumn += this.$getStringScreenWidth(line, screenColumn)[1]; docColumn += this.$getStringScreenWidth(line, screenColumn)[1];
// Need to do some clamping action here. // Need to do some clamping action here.
if (this.$useWrapMode) { if (this.$useWrapMode) {
column = splits[screenRow - row]
if (docColumn >= column) { if (docColumn >= column) {
// We remove one character at the end such that the docColumn // We remove one character at the end such that the docColumn
// position returned is not associated to the next row on the // position returned is not associated to the next row on the

View file

@ -191,7 +191,11 @@ function Folding() {
this.getFoldLine = function(docRow, startFoldLine) { this.getFoldLine = function(docRow, startFoldLine) {
var foldData = this.$foldData; var foldData = this.$foldData;
var i = Math.max(foldData.indexOf(startFoldLine), 0); var i = 0;
if(startFoldLine)
i = foldData.indexOf(startFoldLine);
if(i == -1)
i = 0;
for (i; i < foldData.length; i++) { for (i; i < foldData.length; i++) {
var foldLine = foldData[i]; var foldLine = foldData[i];
if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) { if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {
@ -203,6 +207,47 @@ function Folding() {
return null; return null;
} }
// returns the fold which starts after or contains docRow
this.getNextFold = function(docRow, startFoldLine) {
var foldData = this.$foldData, ans;
var i = 0;
if(startFoldLine)
i = foldData.indexOf(startFoldLine);
if(i == -1)
i = 0;
for (i; i < foldData.length; i++) {
var foldLine = foldData[i];
if (foldLine.end.row >= docRow) {
return foldLine;
}
}
return null;
}
this.getFoldedRowCount = function(first, last) {
var foldData = this.$foldData, rowCount = last-first+1;
for (var i = 0; i < foldData.length; i++) {
var foldLine = foldData[i],
end = foldLine.end.row,
start = foldLine.start.row;
if(end >= last) {
if(start < last) {
if(start >= first)
rowCount -= last-start;
else
rowCount = 0;//in one fold
}
break;
} else if(end >= first){
if (start >= first) //fold inside range
rowCount -= end-start;
else
rowCount -= end-first+1;
}
}
return rowCount;
}
this.$addFoldLine = function(foldLine) { this.$addFoldLine = function(foldLine) {
this.$foldData.push(foldLine); this.$foldData.push(foldLine);
this.$foldData.sort(function(a, b) { this.$foldData.sort(function(a, b) {
@ -428,6 +473,7 @@ function Folding() {
}; };
this.getRowFoldEnd = function(docRow, startFoldRow) { this.getRowFoldEnd = function(docRow, startFoldRow) {
//console.trace()
var foldLine = this.getFoldLine(docRow, startFoldRow); var foldLine = this.getFoldLine(docRow, startFoldRow);
return (foldLine return (foldLine
? foldLine.end.row ? foldLine.end.row

View file

@ -348,8 +348,6 @@ var Editor =function(renderer, session) {
session.$selectionMarker = session.addMarker(range, "ace_selection", style); session.$selectionMarker = session.addMarker(range, "ace_selection", style);
} }
this.onCursorChange(e);
if (this.$highlightSelectedWord) if (this.$highlightSelectedWord)
this.session.getMode().highlightSelection(this); this.session.getMode().highlightSelection(this);
}; };

View file

@ -99,12 +99,22 @@ var Gutter = function(parentEl) {
this.update = function(config) { this.update = function(config) {
this.$config = config; this.$config = config;
var emptyAnno = {className: "", text: []};
var html = []; var html = [];
for ( var i = config.firstRow; i <= config.lastRow; i++) { var i = config.firstRow, lastRow = config.lastRow
var annotation = this.$annotations[i] || { fold = this.session.getNextFold(i),
className: "", foldStart = fold ?fold.start.row :Infinity;
text: []
}; while (true) {
if(i > foldStart) {
i = fold.end.row+1;
fold = this.session.getNextFold(i);
foldStart = fold ?fold.start.row :Infinity;
}
if(i > lastRow)
break;
var annotation = this.$annotations[i] || emptyAnno;
html.push("<div class='ace_gutter-cell", html.push("<div class='ace_gutter-cell",
this.$decorations[i] || "", this.$decorations[i] || "",
this.$breakpoints[i] ? " ace_breakpoint " : " ", this.$breakpoints[i] ? " ace_breakpoint " : " ",
@ -112,10 +122,9 @@ var Gutter = function(parentEl) {
"' title='", annotation.text.join("\n"), "' title='", annotation.text.join("\n"),
"' style='height:", this.session.getRowHeight(config, i), "px;'>", (i+1), "</div>"); "' style='height:", this.session.getRowHeight(config, i), "px;'>", (i+1), "</div>");
i++;
i = this.session.getRowFoldEnd(i);
} }
this.element = dom.setInnerHtml(this.element, html.join("")); this.element = dom.setInnerHtml(this.element, html.join(""));
this.element.style.height = config.minHeight + "px"; this.element.style.height = config.minHeight + "px";
}; };

View file

@ -230,13 +230,12 @@ var Text = function(parentEl) {
return this.update(config); return this.update(config);
var el = this.element; var el = this.element;
if (oldConfig.firstRow < config.firstRow) if (oldConfig.firstRow < config.firstRow)
for (var row=oldConfig.firstRow; row<config.firstRow; row = this.session.getRowFoldEnd(row) + 1) for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)
el.removeChild(el.firstChild); el.removeChild(el.firstChild);
if (oldConfig.lastRow > config.lastRow) if (oldConfig.lastRow > config.lastRow)
for (var row=config.lastRow+1; row<=oldConfig.lastRow; row = this.session.getRowFoldEnd(row) + 1) for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--)
el.removeChild(el.lastChild); el.removeChild(el.lastChild);
if (config.firstRow < oldConfig.firstRow) { if (config.firstRow < oldConfig.firstRow) {
@ -254,8 +253,20 @@ var Text = function(parentEl) {
}; };
this.$renderLinesFragment = function(config, firstRow, lastRow) { this.$renderLinesFragment = function(config, firstRow, lastRow) {
var fragment = document.createDocumentFragment(); var fragment = document.createDocumentFragment(),
for (var row=firstRow; row<=lastRow; row++) { row = firstRow,
fold = this.session.getNextFold(row),
foldStart = fold ?fold.start.row :Infinity;
while (true) {
if(row > foldStart) {
row = fold.end.row+1;
fold = this.session.getNextFold(row);
foldStart = fold ?fold.start.row :Infinity;
}
if(row > lastRow)
break;
var lineEl = dom.createElement("div"); var lineEl = dom.createElement("div");
lineEl.className = "ace_line"; lineEl.className = "ace_line";
@ -276,7 +287,7 @@ var Text = function(parentEl) {
lineEl.innerHTML = html.join(""); lineEl.innerHTML = html.join("");
fragment.appendChild(lineEl); fragment.appendChild(lineEl);
row = this.session.getRowFoldEnd(row); row++;
} }
return fragment; return fragment;
}; };
@ -286,12 +297,36 @@ var Text = function(parentEl) {
this.config = config; this.config = config;
var html = []; var html = [];
var tokens = this.session.getTokens(config.firstRow, config.lastRow) var firstRow = config.firstRow, lastRow = config.lastRow;
var fragment = this.$renderLinesFragment(config, config.firstRow, config.lastRow);
// Clear the current content of the element and add the rendered fragment. var row = firstRow,
this.element.innerHTML = ""; fold = this.session.getNextFold(row),
this.element.appendChild(fragment); foldStart = fold ?fold.start.row :Infinity;
while (true) {
if(row > foldStart) {
row = fold.end.row+1;
fold = this.session.getNextFold(row);
foldStart = fold ?fold.start.row :Infinity;
}
if(row > lastRow)
break;
html.push("<div class='ace_line' style='height:",
this.session.getRowHeight(config, row) + "px;", "width", config.width + "px'>"
)
// Get the tokens per line as there might be some lines in between
// beeing folded.
// OPTIMIZE: If there is a long block of unfolded lines, just make
// this call once for that big block of unfolded lines.
var tokens = this.session.getTokens(row, row);
if (tokens.length == 1)
this.$renderLine(html, row, tokens[0].tokens);
html.push("</div>")
row++;
}
this.element = dom.setInnerHtml(this.element, html.join(""));
}; };
this.$textToken = { this.$textToken = {

View file

@ -123,8 +123,6 @@ var MouseHandler = function(editor) {
onStartSelect(pos); onStartSelect(pos);
} }
editor.renderer.scrollCursorIntoView();
var mousePageX, mousePageY; var mousePageX, mousePageY;
var overwrite = editor.getOverwrite(); var overwrite = editor.getOverwrite();
var mousedownTime = (new Date()).getTime(); var mousedownTime = (new Date()).getTime();

View file

@ -63,7 +63,16 @@ var RenderLoop = function(onRender) {
} }
}; };
if (window.postMessage) { this.setTimeoutZero = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame;
if (this.setTimeoutZero) {
this.setTimeoutZero = this.setTimeoutZero.bind(window)
} else if (window.postMessage) {
this.messageName = "zero-timeout-message"; this.messageName = "zero-timeout-message";

View file

@ -410,7 +410,6 @@ var VirtualRenderer = function(container, theme) {
this.$markerFront.update(this.layerConfig); this.$markerFront.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig); this.$cursorLayer.update(this.layerConfig);
this.$updateScrollBar(); this.$updateScrollBar();
this.scrollCursorIntoView();
return; return;
} }