This commit is contained in:
Daniel Felder 2014-08-11 09:20:25 +00:00
commit 69dcab3479
28 changed files with 911 additions and 573 deletions

View file

@ -359,7 +359,7 @@ function buildAce(options) {
buildSubmodule(options, { buildSubmodule(options, {
projectType: "theme", projectType: "theme",
require: ["ace/theme/" + name] require: ["ace/theme/" + name]
}, "theme-" + name.replace("_theme", "")); }, "theme-" + name);
}); });
// keybindings // keybindings
["vim", "emacs"].forEach(function(name) { ["vim", "emacs"].forEach(function(name) {

View file

@ -52,6 +52,7 @@ var $singleLineEditor = function(el) {
editor.renderer.setHighlightGutterLine(false); editor.renderer.setHighlightGutterLine(false);
editor.$mouseHandler.$focusWaitTimout = 0; editor.$mouseHandler.$focusWaitTimout = 0;
editor.$highlightTagPending = true;
return editor; return editor;
}; };
@ -103,7 +104,7 @@ var AcePopup = function(parentNode) {
popup.session.removeMarker(hoverMarker.id); popup.session.removeMarker(hoverMarker.id);
hoverMarker.id = null; hoverMarker.id = null;
} }
} };
popup.setSelectOnHover(false); popup.setSelectOnHover(false);
popup.on("mousemove", function(e) { popup.on("mousemove", function(e) {
if (!lastMouseEvent) { if (!lastMouseEvent) {
@ -171,8 +172,8 @@ var AcePopup = function(parentNode) {
}; };
var bgTokenizer = popup.session.bgTokenizer; var bgTokenizer = popup.session.bgTokenizer;
bgTokenizer.$tokenizeRow = function(i) { bgTokenizer.$tokenizeRow = function(row) {
var data = popup.data[i]; var data = popup.data[row];
var tokens = []; var tokens = [];
if (!data) if (!data)
return tokens; return tokens;
@ -206,7 +207,7 @@ var AcePopup = function(parentNode) {
popup.session.$computeWidth = function() { popup.session.$computeWidth = function() {
return this.screenWidth = 0; return this.screenWidth = 0;
} };
// public // public
popup.isOpen = false; popup.isOpen = false;
@ -240,6 +241,7 @@ var AcePopup = function(parentNode) {
popup.on("changeSelection", function() { popup.on("changeSelection", function() {
if (popup.isOpen) if (popup.isOpen)
popup.setRow(popup.selection.lead.row); popup.setRow(popup.selection.lead.row);
popup.renderer.scrollCursorIntoView();
}); });
popup.hide = function() { popup.hide = function() {

View file

@ -205,12 +205,14 @@ exports.commands = [{
bindKey: bindKey("Shift-Up", "Shift-Up"), bindKey: bindKey("Shift-Up", "Shift-Up"),
exec: function(editor) { editor.getSelection().selectUp(); }, exec: function(editor) { editor.getSelection().selectUp(); },
multiSelectAction: "forEach", multiSelectAction: "forEach",
scrollIntoView: "cursor",
readOnly: true readOnly: true
}, { }, {
name: "golineup", name: "golineup",
bindKey: bindKey("Up", "Up|Ctrl-P"), bindKey: bindKey("Up", "Up|Ctrl-P"),
exec: function(editor, args) { editor.navigateUp(args.times); }, exec: function(editor, args) { editor.navigateUp(args.times); },
multiSelectAction: "forEach", multiSelectAction: "forEach",
scrollIntoView: "cursor",
readOnly: true readOnly: true
}, { }, {
name: "selecttoend", name: "selecttoend",
@ -395,12 +397,21 @@ exports.commands = [{
bindKey: bindKey("Ctrl-P", "Ctrl-P"), bindKey: bindKey("Ctrl-P", "Ctrl-P"),
exec: function(editor) { editor.jumpToMatching(); }, exec: function(editor) { editor.jumpToMatching(); },
multiSelectAction: "forEach", multiSelectAction: "forEach",
scrollIntoView: "animate",
readOnly: true readOnly: true
}, { }, {
name: "selecttomatching", name: "selecttomatching",
bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"), bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
exec: function(editor) { editor.jumpToMatching(true); }, exec: function(editor) { editor.jumpToMatching(true); },
multiSelectAction: "forEach", multiSelectAction: "forEach",
scrollIntoView: "animate",
readOnly: true
}, {
name: "expandToMatching",
bindKey: bindKey("Ctrl-Shift-M", "Ctrl-Shift-M"),
exec: function(editor) { editor.jumpToMatching(true, true); },
multiSelectAction: "forEach",
scrollIntoView: "animate",
readOnly: true readOnly: true
}, { }, {
name: "passKeysToBrowser", name: "passKeysToBrowser",
@ -458,11 +469,13 @@ exports.commands = [{
name: "modifyNumberUp", name: "modifyNumberUp",
bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"), bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
exec: function(editor) { editor.modifyNumber(1); }, exec: function(editor) { editor.modifyNumber(1); },
scrollIntoView: "cursor",
multiSelectAction: "forEach" multiSelectAction: "forEach"
}, { }, {
name: "modifyNumberDown", name: "modifyNumberDown",
bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"), bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"),
exec: function(editor) { editor.modifyNumber(-1); }, exec: function(editor) { editor.modifyNumber(-1); },
scrollIntoView: "cursor",
multiSelectAction: "forEach" multiSelectAction: "forEach"
}, { }, {
name: "replace", name: "replace",
@ -629,7 +642,7 @@ exports.commands = [{
var isBackwards = editor.selection.isBackwards(); var isBackwards = editor.selection.isBackwards();
var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor(); var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor();
var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead(); var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead();
var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length;
var selectedText = editor.session.doc.getTextRange(editor.selection.getRange()); var selectedText = editor.session.doc.getTextRange(editor.selection.getRange());
var selectedCount = selectedText.replace(/\n\s*/, " ").length; var selectedCount = selectedText.replace(/\n\s*/, " ").length;
var insertLine = editor.session.doc.getLine(selectionStart.row); var insertLine = editor.session.doc.getLine(selectionStart.row);
@ -640,7 +653,7 @@ exports.commands = [{
curLine = " " + curLine; curLine = " " + curLine;
} }
insertLine += curLine; insertLine += curLine;
}; }
if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) { if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) {
// Don't insert a newline at the end of the document // Don't insert a newline at the end of the document

View file

@ -35,41 +35,49 @@ exports.defaultCommands = [{
name: "addCursorAbove", name: "addCursorAbove",
exec: function(editor) { editor.selectMoreLines(-1); }, exec: function(editor) { editor.selectMoreLines(-1); },
bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"}, bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
scrollIntoView: "cursor",
readonly: true readonly: true
}, { }, {
name: "addCursorBelow", name: "addCursorBelow",
exec: function(editor) { editor.selectMoreLines(1); }, exec: function(editor) { editor.selectMoreLines(1); },
bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"}, bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
scrollIntoView: "cursor",
readonly: true readonly: true
}, { }, {
name: "addCursorAboveSkipCurrent", name: "addCursorAboveSkipCurrent",
exec: function(editor) { editor.selectMoreLines(-1, true); }, exec: function(editor) { editor.selectMoreLines(-1, true); },
bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"}, bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"},
scrollIntoView: "cursor",
readonly: true readonly: true
}, { }, {
name: "addCursorBelowSkipCurrent", name: "addCursorBelowSkipCurrent",
exec: function(editor) { editor.selectMoreLines(1, true); }, exec: function(editor) { editor.selectMoreLines(1, true); },
bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"}, bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"},
scrollIntoView: "cursor",
readonly: true readonly: true
}, { }, {
name: "selectMoreBefore", name: "selectMoreBefore",
exec: function(editor) { editor.selectMore(-1); }, exec: function(editor) { editor.selectMore(-1); },
bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"}, bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"},
scrollIntoView: "cursor",
readonly: true readonly: true
}, { }, {
name: "selectMoreAfter", name: "selectMoreAfter",
exec: function(editor) { editor.selectMore(1); }, exec: function(editor) { editor.selectMore(1); },
bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"}, bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"},
scrollIntoView: "cursor",
readonly: true readonly: true
}, { }, {
name: "selectNextBefore", name: "selectNextBefore",
exec: function(editor) { editor.selectMore(-1, true); }, exec: function(editor) { editor.selectMore(-1, true); },
bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"}, bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"},
scrollIntoView: "cursor",
readonly: true readonly: true
}, { }, {
name: "selectNextAfter", name: "selectNextAfter",
exec: function(editor) { editor.selectMore(1, true); }, exec: function(editor) { editor.selectMore(1, true); },
bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"}, bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"},
scrollIntoView: "cursor",
readonly: true readonly: true
}, { }, {
name: "splitIntoLines", name: "splitIntoLines",
@ -79,11 +87,13 @@ exports.defaultCommands = [{
}, { }, {
name: "alignCursors", name: "alignCursors",
exec: function(editor) { editor.alignCursors(); }, exec: function(editor) { editor.alignCursors(); },
bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"} bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"},
scrollIntoView: "cursor"
}, { }, {
name: "findAll", name: "findAll",
exec: function(editor) { editor.findAll(); }, exec: function(editor) { editor.findAll(); },
bindKey: {win: "Ctrl-Alt-K", mac: "Ctrl-Alt-G"}, bindKey: {win: "Ctrl-Alt-K", mac: "Ctrl-Alt-G"},
scrollIntoView: "cursor",
readonly: true readonly: true
}]; }];
@ -92,6 +102,7 @@ exports.multiSelectCommands = [{
name: "singleSelection", name: "singleSelection",
bindKey: "esc", bindKey: "esc",
exec: function(editor) { editor.exitMultiSelectMode(); }, exec: function(editor) { editor.exitMultiSelectMode(); },
scrollIntoView: "cursor",
readonly: true, readonly: true,
isAvailable: function(editor) {return editor && editor.inMultiSelectMode} isAvailable: function(editor) {return editor && editor.inMultiSelectMode}
}]; }];

View file

@ -81,10 +81,6 @@ exports.moduleUrl = function(name, component) {
// todo make this configurable or get rid of '-' // todo make this configurable or get rid of '-'
var sep = component == "snippets" ? "/" : "-"; var sep = component == "snippets" ? "/" : "-";
var base = parts[parts.length - 1]; var base = parts[parts.length - 1];
if (sep == "-") {
var re = new RegExp("^" + component + "[\\-_]|[\\-_]" + component + "$", "g");
base = base.replace(re, "");
}
if ((!base || base == component) && parts.length > 1) if ((!base || base == component) && parts.length > 1)
base = parts[parts.length - 2]; base = parts[parts.length - 2];

View file

@ -43,7 +43,7 @@ module.exports = {
"test: path resolution" : function() { "test: path resolution" : function() {
config.set("packaged", "true"); config.set("packaged", "true");
var url = config.moduleUrl("kr_theme", "theme"); var url = config.moduleUrl("kr_theme", "theme");
assert.equal(url, "theme-kr.js"); assert.equal(url, "theme-kr_theme.js");
config.set("basePath", "a/b"); config.set("basePath", "a/b");
url = config.moduleUrl("m/theme", "theme"); url = config.moduleUrl("m/theme", "theme");

View file

@ -155,8 +155,8 @@
} }
.ace_text-input.ace_composition { .ace_text-input.ace_composition {
background: #f8f8f8; background: inherit;
color: #111; color: inherit;
z-index: 1000; z-index: 1000;
opacity: 1; opacity: 1;
text-indent: 0; text-indent: 0;

View file

@ -268,7 +268,7 @@ var EditSession = function(text, mode) {
this.$informUndoManager.schedule(); this.$informUndoManager.schedule();
} }
this.bgTokenizer.$updateOnChange(delta); this.bgTokenizer && this.bgTokenizer.$updateOnChange(delta);
this._signal("change", e); this._signal("change", e);
}; };
@ -276,8 +276,6 @@ var EditSession = function(text, mode) {
* Sets the session text. * Sets the session text.
* @param {String} text The new text to place * @param {String} text The new text to place
* *
*
*
**/ **/
this.setValue = function(text) { this.setValue = function(text) {
this.doc.setValue(text); this.doc.setValue(text);
@ -950,6 +948,9 @@ var EditSession = function(text, mode) {
if (!$isPlaceholder) { if (!$isPlaceholder) {
// experimental method, used by c9 findiniles
if (mode.attachToSession)
mode.attachToSession(this);
this.$options.wrapMethod.set.call(this, this.$wrapMethod); this.$options.wrapMethod.set.call(this, this.$wrapMethod);
this.$setFolding(mode.foldingRules); this.$setFolding(mode.foldingRules);
this.bgTokenizer.start(0); this.bgTokenizer.start(0);
@ -957,12 +958,11 @@ var EditSession = function(text, mode) {
} }
}; };
this.$stopWorker = function() { this.$stopWorker = function() {
if (this.$worker) if (this.$worker) {
this.$worker.terminate(); this.$worker.terminate();
this.$worker = null; this.$worker = null;
}
}; };
this.$startWorker = function() { this.$startWorker = function() {
@ -1731,9 +1731,10 @@ var EditSession = function(text, mode) {
// Inside of the foldLine range. Need to split stuff up. // Inside of the foldLine range. Need to split stuff up.
if (cmp == 0) { if (cmp == 0) {
foldLine = foldLine.split(start.row, start.column); foldLine = foldLine.split(start.row, start.column);
if (foldLine) {
foldLine.shiftRow(len); foldLine.shiftRow(len);
foldLine.addRemoveChars( foldLine.addRemoveChars(lastRow, 0, end.column - start.column);
lastRow, 0, end.column - start.column); }
} else } else
// Infront of the foldLine but same row. Need to shift column. // Infront of the foldLine but same row. Need to shift column.
if (cmp == -1) { if (cmp == -1) {
@ -2400,7 +2401,15 @@ var EditSession = function(text, mode) {
*/ */
this.$setFontMetrics = function(fm) { this.$setFontMetrics = function(fm) {
// todo // todo
};
this.destroy = function() {
if (this.bgTokenizer) {
this.bgTokenizer.setDocument(null);
this.bgTokenizer = null;
} }
this.$stopWorker();
};
// For every keystroke this gets called once per char in the whole doc!! // For every keystroke this gets called once per char in the whole doc!!
// Wouldn't hurt to make it a bit faster for c >= 0x1100 // Wouldn't hurt to make it a bit faster for c >= 0x1100

View file

@ -44,7 +44,7 @@ function FoldLine(foldData, folds) {
folds = this.folds = [ folds ]; folds = this.folds = [ folds ];
} }
var last = folds[folds.length - 1] var last = folds[folds.length - 1];
this.range = new Range(folds[0].start.row, folds[0].start.column, this.range = new Range(folds[0].start.row, folds[0].start.column,
last.end.row, last.end.column); last.end.row, last.end.column);
this.start = this.range.start; this.start = this.range.start;
@ -66,7 +66,7 @@ function FoldLine(foldData, folds) {
fold.start.row += shift; fold.start.row += shift;
fold.end.row += shift; fold.end.row += shift;
}); });
} };
this.addFold = function(fold) { this.addFold = function(fold) {
if (fold.sameRow) { if (fold.sameRow) {
@ -96,17 +96,17 @@ function FoldLine(foldData, folds) {
throw new Error("Trying to add fold to FoldRow that doesn't have a matching row"); throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");
} }
fold.foldLine = this; fold.foldLine = this;
} };
this.containsRow = function(row) { this.containsRow = function(row) {
return row >= this.start.row && row <= this.end.row; return row >= this.start.row && row <= this.end.row;
} };
this.walk = function(callback, endRow, endColumn) { this.walk = function(callback, endRow, endColumn) {
var lastEnd = 0, var lastEnd = 0,
folds = this.folds, folds = this.folds,
fold, fold,
comp, stop, isNewRow = true; cmp, stop, isNewRow = true;
if (endRow == null) { if (endRow == null) {
endRow = this.end.row; endRow = this.end.row;
@ -116,9 +116,9 @@ function FoldLine(foldData, folds) {
for (var i = 0; i < folds.length; i++) { for (var i = 0; i < folds.length; i++) {
fold = folds[i]; fold = folds[i];
comp = fold.range.compareStart(endRow, endColumn); cmp = fold.range.compareStart(endRow, endColumn);
// This fold is after the endRow/Column. // This fold is after the endRow/Column.
if (comp == -1) { if (cmp == -1) {
callback(null, endRow, endColumn, lastEnd, isNewRow); callback(null, endRow, endColumn, lastEnd, isNewRow);
return; return;
} }
@ -127,8 +127,8 @@ function FoldLine(foldData, folds) {
stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd); stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd);
// If the user requested to stop the walk or endRow/endColumn is // If the user requested to stop the walk or endRow/endColumn is
// inside of this fold (comp == 0), then end here. // inside of this fold (cmp == 0), then end here.
if (stop || comp == 0) { if (stop || cmp === 0) {
return; return;
} }
@ -138,7 +138,7 @@ function FoldLine(foldData, folds) {
lastEnd = fold.end.column; lastEnd = fold.end.column;
} }
callback(null, endRow, endColumn, lastEnd, isNewRow); callback(null, endRow, endColumn, lastEnd, isNewRow);
} };
this.getNextFoldTo = function(row, column) { this.getNextFoldTo = function(row, column) {
var fold, cmp; var fold, cmp;
@ -150,15 +150,15 @@ function FoldLine(foldData, folds) {
fold: fold, fold: fold,
kind: "after" kind: "after"
}; };
} else if (cmp == 0) { } else if (cmp === 0) {
return { return {
fold: fold, fold: fold,
kind: "inside" kind: "inside"
} };
} }
} }
return null; return null;
} };
this.addRemoveChars = function(row, column, len) { this.addRemoveChars = function(row, column, len) {
var ret = this.getNextFoldTo(row, column), var ret = this.getNextFoldTo(row, column),
@ -175,7 +175,7 @@ function FoldLine(foldData, folds) {
} else if (fold.start.row == row) { } else if (fold.start.row == row) {
folds = this.folds; folds = this.folds;
var i = folds.indexOf(fold); var i = folds.indexOf(fold);
if (i == 0) { if (i === 0) {
this.start.column += len; this.start.column += len;
} }
for (i; i < folds.length; i++) { for (i; i < folds.length; i++) {
@ -189,16 +189,18 @@ function FoldLine(foldData, folds) {
this.end.column += len; this.end.column += len;
} }
} }
} };
this.split = function(row, column) { this.split = function(row, column) {
var fold = this.getNextFoldTo(row, column).fold; var pos = this.getNextFoldTo(row, column);
if (!pos || pos.kind == "inside")
return null;
var fold = pos.fold;
var folds = this.folds; var folds = this.folds;
var foldData = this.foldData; var foldData = this.foldData;
if (!fold)
return null;
var i = folds.indexOf(fold); var i = folds.indexOf(fold);
var foldBefore = folds[i - 1]; var foldBefore = folds[i - 1];
this.end.row = foldBefore.end.row; this.end.row = foldBefore.end.row;
@ -211,7 +213,7 @@ function FoldLine(foldData, folds) {
var newFoldLine = new FoldLine(foldData, folds); var newFoldLine = new FoldLine(foldData, folds);
foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine); foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);
return newFoldLine; return newFoldLine;
} };
this.merge = function(foldLineNext) { this.merge = function(foldLineNext) {
var folds = foldLineNext.folds; var folds = foldLineNext.folds;
@ -222,7 +224,7 @@ function FoldLine(foldData, folds) {
// it's merged now with foldLineNext. // it's merged now with foldLineNext.
var foldData = this.foldData; var foldData = this.foldData;
foldData.splice(foldData.indexOf(foldLineNext), 1); foldData.splice(foldData.indexOf(foldLineNext), 1);
} };
this.toString = function() { this.toString = function() {
var ret = [this.range.toString() + ": [" ]; var ret = [this.range.toString() + ": [" ];
@ -230,13 +232,12 @@ function FoldLine(foldData, folds) {
this.folds.forEach(function(fold) { this.folds.forEach(function(fold) {
ret.push(" " + fold.toString()); ret.push(" " + fold.toString());
}); });
ret.push("]") ret.push("]");
return ret.join("\n"); return ret.join("\n");
} };
this.idxToPosition = function(idx) { this.idxToPosition = function(idx) {
var lastFoldEndColumn = 0; var lastFoldEndColumn = 0;
var fold;
for (var i = 0; i < this.folds.length; i++) { for (var i = 0; i < this.folds.length; i++) {
var fold = this.folds[i]; var fold = this.folds[i];
@ -261,7 +262,7 @@ function FoldLine(foldData, folds) {
row: this.end.row, row: this.end.row,
column: this.end.column + idx column: this.end.column + idx
}; };
} };
}).call(FoldLine.prototype); }).call(FoldLine.prototype);
exports.FoldLine = FoldLine; exports.FoldLine = FoldLine;

View file

@ -82,7 +82,6 @@ var Editor = function(renderer, session) {
this.$mouseHandler = new MouseHandler(this); this.$mouseHandler = new MouseHandler(this);
new FoldHandler(this); new FoldHandler(this);
this.$blockScrolling = 0;
this.$search = new Search().set({ this.$search = new Search().set({
wrap: true wrap: true
}); });
@ -94,7 +93,8 @@ var Editor = function(renderer, session) {
this._$emitInputEvent = lang.delayedCall(function() { this._$emitInputEvent = lang.delayedCall(function() {
this._signal("input", {}); this._signal("input", {});
this.session.bgTokenizer && this.session.bgTokenizer.scheduleStart(); if (this.session && this.session.bgTokenizer)
this.session.bgTokenizer.scheduleStart();
}.bind(this)); }.bind(this));
this.on("change", function(_, _self) { this.on("change", function(_, _self) {
@ -183,7 +183,6 @@ var Editor = function(renderer, session) {
if (this.curOp) { if (this.curOp) {
var command = this.curOp.command; var command = this.curOp.command;
if (command && command.scrollIntoView) { if (command && command.scrollIntoView) {
this.$blockScrolling--;
switch (command.scrollIntoView) { switch (command.scrollIntoView) {
case "center": case "center":
this.renderer.scrollCursorIntoView(null, 0.5); this.renderer.scrollCursorIntoView(null, 0.5);
@ -371,9 +370,7 @@ var Editor = function(renderer, session) {
this.onChangeMode(); this.onChangeMode();
this.$blockScrolling += 1;
this.onCursorChange(); this.onCursorChange();
this.$blockScrolling -= 1;
this.onScrollTopChange(); this.onScrollTopChange();
this.onScrollLeftChange(); this.onScrollLeftChange();
@ -384,6 +381,9 @@ var Editor = function(renderer, session) {
this.onChangeAnnotation(); this.onChangeAnnotation();
this.session.getUseWrapMode() && this.renderer.adjustWrapLimit(); this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
this.renderer.updateFull(); this.renderer.updateFull();
} else {
this.selection = null;
this.renderer.setSession(session);
} }
this._signal("changeSession", { this._signal("changeSession", {
@ -525,25 +525,23 @@ var Editor = function(renderer, session) {
this.$highlightPending = true; this.$highlightPending = true;
setTimeout(function() { setTimeout(function() {
self.$highlightPending = false; self.$highlightPending = false;
var session = self.session;
var pos = self.session.findMatchingBracket(self.getCursorPosition()); if (!session || !session.bgTokenizer) return;
var pos = session.findMatchingBracket(self.getCursorPosition());
if (pos) { if (pos) {
var range = new Range(pos.row, pos.column, pos.row, pos.column+1); var range = new Range(pos.row, pos.column, pos.row, pos.column + 1);
} else if (self.session.$mode.getMatching) { } else if (session.$mode.getMatching) {
var range = self.session.$mode.getMatching(self.session); var range = session.$mode.getMatching(self.session);
} }
if (range) if (range)
self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket", "text"); session.$bracketHighlight = session.addMarker(range, "ace_bracket", "text");
}, 50); }, 50);
}; };
// todo: move to mode.getMatching // todo: move to mode.getMatching
this.$highlightTags = function() { this.$highlightTags = function() {
var session = this.session; if (this.$highlightTagPending)
if (this.$highlightTagPending) {
return; return;
}
// perform highlight async to not block the browser during navigation // perform highlight async to not block the browser during navigation
var self = this; var self = this;
@ -551,6 +549,9 @@ var Editor = function(renderer, session) {
setTimeout(function() { setTimeout(function() {
self.$highlightTagPending = false; self.$highlightTagPending = false;
var session = self.session;
if (!session || !session.bgTokenizer) return;
var pos = self.getCursorPosition(); var pos = self.getCursorPosition();
var iterator = new TokenIterator(self.session, pos.row, pos.column); var iterator = new TokenIterator(self.session, pos.row, pos.column);
var token = iterator.getCurrentToken(); var token = iterator.getCurrentToken();
@ -572,28 +573,28 @@ var Editor = function(renderer, session) {
token = iterator.stepForward(); token = iterator.stepForward();
if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) { if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
if (prevToken.value==='<'){ if (prevToken.value === '<'){
depth++; depth++;
} else if (prevToken.value==='</'){ } else if (prevToken.value === '</'){
depth--; depth--;
} }
} }
} while (token && depth>=0); } while (token && depth >= 0);
}else{ } else {
//find opening tag //find opening tag
do { do {
token = prevToken; token = prevToken;
prevToken = iterator.stepBackward(); prevToken = iterator.stepBackward();
if(token && token.value === tag && token.type.indexOf('tag-name') !== -1) { if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
if (prevToken.value==='<') { if (prevToken.value === '<') {
depth++; depth++;
} else if( prevToken.value==='</') { } else if (prevToken.value === '</') {
depth--; depth--;
} }
} }
} while (prevToken && depth<=0); } while (prevToken && depth <= 0);
//select tag again //select tag again
iterator.stepForward(); iterator.stepForward();
@ -732,10 +733,6 @@ var Editor = function(renderer, session) {
this.onCursorChange = function() { this.onCursorChange = function() {
this.$cursorChange(); this.$cursorChange();
if (!this.$blockScrolling) {
this.renderer.scrollCursorIntoView();
}
this.$highlightBrackets(); this.$highlightBrackets();
this.$highlightTags(); this.$highlightTags();
this.$updateHighlightActiveLine(); this.$updateHighlightActiveLine();
@ -921,9 +918,28 @@ var Editor = function(renderer, session) {
// todo this should change when paste becomes a command // todo this should change when paste becomes a command
if (this.$readOnly) if (this.$readOnly)
return; return;
var e = {text: text}; var e = {text: text};
this._signal("paste", e); this._signal("paste", e);
this.insert(e.text, true); text = e.text;
if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {
this.insert(text);
} else {
var lines = text.split(/\r\n|\r|\n/);
var ranges = this.selection.rangeList.ranges;
if (lines.length > ranges.length || lines.length < 2 || !lines[1])
return this.commands.exec("insertstring", this, text);
for (var i = ranges.length; i--;) {
var range = ranges[i];
if (!range.isEmpty())
this.session.remove(range);
this.session.insert(range.start, lines[i]);
}
}
this.renderer.scrollCursorIntoView();
}; };
@ -1831,7 +1847,6 @@ var Editor = function(renderer, session) {
var config = this.renderer.layerConfig; var config = this.renderer.layerConfig;
var rows = dir * Math.floor(config.height / config.lineHeight); var rows = dir * Math.floor(config.height / config.lineHeight);
this.$blockScrolling++;
if (select === true) { if (select === true) {
this.selection.$moveSelection(function(){ this.selection.$moveSelection(function(){
this.moveCursorBy(rows, 0); this.moveCursorBy(rows, 0);
@ -1840,7 +1855,6 @@ var Editor = function(renderer, session) {
this.selection.moveCursorBy(rows, 0); this.selection.moveCursorBy(rows, 0);
this.selection.clearSelection(); this.selection.clearSelection();
} }
this.$blockScrolling--;
var scrollTop = renderer.scrollTop; var scrollTop = renderer.scrollTop;
@ -1965,9 +1979,7 @@ var Editor = function(renderer, session) {
* @related Selection.selectAll * @related Selection.selectAll
**/ **/
this.selectAll = function() { this.selectAll = function() {
this.$blockScrolling += 1;
this.selection.selectAll(); this.selection.selectAll();
this.$blockScrolling -= 1;
}; };
/** /**
@ -2005,17 +2017,13 @@ var Editor = function(renderer, session) {
* Moves the cursor's row and column to the next matching bracket or HTML tag. * Moves the cursor's row and column to the next matching bracket or HTML tag.
* *
**/ **/
this.jumpToMatching = function(select) { this.jumpToMatching = function(select, expand) {
var cursor = this.getCursorPosition(); var cursor = this.getCursorPosition();
var iterator = new TokenIterator(this.session, cursor.row, cursor.column); var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
var prevToken = iterator.getCurrentToken(); var prevToken = iterator.getCurrentToken();
var token = prevToken; var token = prevToken || iterator.stepForward();
if (!token) if (!token) return;
token = iterator.stepForward();
if (!token)
return;
//get next closing tag or bracket //get next closing tag or bracket
var matchType; var matchType;
@ -2034,12 +2042,12 @@ var Editor = function(renderer, session) {
do { do {
if (token.value.match(/[{}()\[\]]/g)) { if (token.value.match(/[{}()\[\]]/g)) {
for (; i<token.value.length && !found; i++) { for (; i < token.value.length && !found; i++) {
if (!brackets[token.value[i]]) { if (!brackets[token.value[i]]) {
continue; continue;
} }
bracketType = brackets[token.value[i]]+'.'+token.type.replace("rparen", "lparen"); bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen");
if (isNaN(depth[bracketType])) { if (isNaN(depth[bracketType])) {
depth[bracketType] = 0; depth[bracketType] = 0;
@ -2056,21 +2064,23 @@ var Editor = function(renderer, session) {
case '}': case '}':
depth[bracketType]--; depth[bracketType]--;
if (depth[bracketType]===-1) { if (depth[bracketType] === -1) {
matchType = 'bracket'; matchType = 'bracket';
found = true; found = true;
} }
break; break;
} }
} }
} else if (token && token.type.indexOf('tag-name') !== -1) { }
else if (token && token.type.indexOf('tag-name') !== -1) {
if (isNaN(depth[token.value])) { if (isNaN(depth[token.value])) {
depth[token.value] = 0; depth[token.value] = 0;
} }
if (prevToken.value === '<') { if (prevToken.value === '<') {
depth[token.value]++; depth[token.value]++;
} else if (prevToken.value === '</') { }
else if (prevToken.value === '</') {
depth[token.value]--; depth[token.value]--;
} }
@ -2088,37 +2098,35 @@ var Editor = function(renderer, session) {
} while (token && !found); } while (token && !found);
//no match found //no match found
if (!matchType) { if (!matchType)
return; return;
}
var range; var range, pos;
if (matchType==='bracket') { if (matchType === 'bracket') {
range = this.session.getBracketRange(cursor); range = this.session.getBracketRange(cursor);
if (!range) { if (!range) {
range = new Range( range = new Range(
iterator.getCurrentTokenRow(), iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn()+i-1, iterator.getCurrentTokenColumn() + i - 1,
iterator.getCurrentTokenRow(), iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn()+i-1 iterator.getCurrentTokenColumn() + i - 1
); );
if (!range) pos = range.start;
return; if (expand || pos.row === cursor.row && Math.abs(pos.column - cursor.column) < 2)
var pos = range.start;
if (pos.row === cursor.row && Math.abs(pos.column - cursor.column) < 2)
range = this.session.getBracketRange(pos); range = this.session.getBracketRange(pos);
} }
} else if(matchType==='tag') { }
else if (matchType === 'tag') {
if (token && token.type.indexOf('tag-name') !== -1) if (token && token.type.indexOf('tag-name') !== -1)
var tag = token.value; var tag = token.value;
else else
return; return;
var range = new Range( range = new Range(
iterator.getCurrentTokenRow(), iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn()-2, iterator.getCurrentTokenColumn() - 2,
iterator.getCurrentTokenRow(), iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn()-2 iterator.getCurrentTokenColumn() - 2
); );
//find matching tag //find matching tag
@ -2130,17 +2138,18 @@ var Editor = function(renderer, session) {
if (prevToken) { if (prevToken) {
if (prevToken.type.indexOf('tag-close') !== -1) { if (prevToken.type.indexOf('tag-close') !== -1) {
range.setEnd(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn()+1); range.setEnd(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1);
} }
if (token.value === tag && token.type.indexOf('tag-name') !== -1) { if (token.value === tag && token.type.indexOf('tag-name') !== -1) {
if (prevToken.value === '<') { if (prevToken.value === '<') {
depth[tag]++; depth[tag]++;
} else if ( prevToken.value === '</') { }
else if (prevToken.value === '</') {
depth[tag]--; depth[tag]--;
} }
if (depth[tag]===0) if (depth[tag] === 0)
found = true; found = true;
} }
} }
@ -2149,7 +2158,7 @@ var Editor = function(renderer, session) {
//we found it //we found it
if (token && token.type.indexOf('tag-name')) { if (token && token.type.indexOf('tag-name')) {
var pos = range.start; pos = range.start;
if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2) if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
pos = range.end; pos = range.end;
} }
@ -2158,10 +2167,13 @@ var Editor = function(renderer, session) {
pos = range && range.cursor || pos; pos = range && range.cursor || pos;
if (pos) { if (pos) {
if (select) { if (select) {
if (range && range.isEqual(this.getSelectionRange())) if (range && expand) {
this.selection.setRange(range);
} else if (range && range.isEqual(this.getSelectionRange())) {
this.clearSelection(); this.clearSelection();
else } else {
this.selection.selectTo(pos.row, pos.column); this.selection.selectTo(pos.row, pos.column);
}
} else { } else {
this.selection.moveTo(pos.row, pos.column); this.selection.moveTo(pos.row, pos.column);
} }
@ -2179,11 +2191,9 @@ var Editor = function(renderer, session) {
this.selection.clearSelection(); this.selection.clearSelection();
this.session.unfold({row: lineNumber - 1, column: column || 0}); this.session.unfold({row: lineNumber - 1, column: column || 0});
this.$blockScrolling += 1;
// todo: find a way to automatically exit multiselect mode // todo: find a way to automatically exit multiselect mode
this.exitMultiSelectMode && this.exitMultiSelectMode(); this.exitMultiSelectMode && this.exitMultiSelectMode();
this.moveCursorTo(lineNumber - 1, column || 0); this.moveCursorTo(lineNumber - 1, column || 0);
this.$blockScrolling -= 1;
if (!this.isRowFullyVisible(lineNumber - 1)) if (!this.isRowFullyVisible(lineNumber - 1))
this.scrollToLine(lineNumber - 1, true, animate); this.scrollToLine(lineNumber - 1, true, animate);
@ -2369,7 +2379,6 @@ var Editor = function(renderer, session) {
if (!ranges.length) if (!ranges.length)
return replaced; return replaced;
this.$blockScrolling += 1;
var selection = this.getSelectionRange(); var selection = this.getSelectionRange();
this.selection.moveTo(0, 0); this.selection.moveTo(0, 0);
@ -2381,7 +2390,6 @@ var Editor = function(renderer, session) {
} }
this.selection.setSelectionRange(selection); this.selection.setSelectionRange(selection);
this.$blockScrolling -= 1;
return replaced; return replaced;
}; };
@ -2479,10 +2487,8 @@ var Editor = function(renderer, session) {
}; };
this.revealRange = function(range, animate) { this.revealRange = function(range, animate) {
this.$blockScrolling += 1;
this.session.unfold(range); this.session.unfold(range);
this.selection.setSelectionRange(range); this.selection.setSelectionRange(range);
this.$blockScrolling -= 1;
var scrollTop = this.renderer.scrollTop; var scrollTop = this.renderer.scrollTop;
this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5); this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
@ -2495,9 +2501,7 @@ var Editor = function(renderer, session) {
* @related UndoManager.undo * @related UndoManager.undo
**/ **/
this.undo = function() { this.undo = function() {
this.$blockScrolling++;
this.session.getUndoManager().undo(); this.session.getUndoManager().undo();
this.$blockScrolling--;
this.renderer.scrollCursorIntoView(null, 0.5); this.renderer.scrollCursorIntoView(null, 0.5);
}; };
@ -2506,9 +2510,7 @@ var Editor = function(renderer, session) {
* @related UndoManager.redo * @related UndoManager.redo
**/ **/
this.redo = function() { this.redo = function() {
this.$blockScrolling++;
this.session.getUndoManager().redo(); this.session.getUndoManager().redo();
this.$blockScrolling--;
this.renderer.scrollCursorIntoView(null, 0.5); this.renderer.scrollCursorIntoView(null, 0.5);
}; };
@ -2519,6 +2521,9 @@ var Editor = function(renderer, session) {
this.destroy = function() { this.destroy = function() {
this.renderer.destroy(); this.renderer.destroy();
this._signal("destroy", this); this._signal("destroy", this);
if (this.session) {
this.session.destroy();
}
}; };
/** /**

View file

@ -98,7 +98,6 @@ var highlight = function(el, opts, callback) {
* and `css`. * and `css`.
* @returns {object} An object containing the properties `html` and `css`. * @returns {object} An object containing the properties `html` and `css`.
*/ */
highlight.render = function(input, mode, theme, lineStart, disableGutter, callback) { highlight.render = function(input, mode, theme, lineStart, disableGutter, callback) {
var waiting = 1; var waiting = 1;
var modeCache = EditSession.prototype.$modes; var modeCache = EditSession.prototype.$modes;
@ -112,11 +111,17 @@ highlight.render = function(input, mode, theme, lineStart, disableGutter, callba
--waiting || done(); --waiting || done();
}); });
} }
// allow setting mode options e.h {path: "ace/mode/php", inline:true}
var modeOptions;
if (mode && typeof mode === "object" && !mode.getTokenizer) {
modeOptions = mode;
mode = modeOptions.path;
}
if (typeof mode == "string") { if (typeof mode == "string") {
waiting++; waiting++;
config.loadModule(['mode', mode], function(m) { config.loadModule(['mode', mode], function(m) {
if (!modeCache[mode]) modeCache[mode] = new m.Mode(); if (!modeCache[mode] || modeOptions)
modeCache[mode] = new m.Mode(modeOptions);
mode = modeCache[mode]; mode = modeCache[mode];
--waiting || done(); --waiting || done();
}); });
@ -130,14 +135,13 @@ highlight.render = function(input, mode, theme, lineStart, disableGutter, callba
return --waiting || done(); return --waiting || done();
}; };
/* /**
* Transforms a given input code snippet into HTML using the given mode * Transforms a given input code snippet into HTML using the given mode
* @param {string} input Code snippet * @param {string} input Code snippet
* @param {mode} mode Mode loaded from /ace/mode (use 'ServerSideHiglighter.getMode') * @param {mode} mode Mode loaded from /ace/mode (use 'ServerSideHiglighter.getMode')
* @param {string} r Code snippet * @param {string} r Code snippet
* @returns {object} An object containing: html, css * @returns {object} An object containing: html, css
*/ */
highlight.renderSync = function(input, mode, theme, lineStart, disableGutter) { highlight.renderSync = function(input, mode, theme, lineStart, disableGutter) {
lineStart = parseInt(lineStart || 1, 10); lineStart = parseInt(lineStart || 1, 10);

View file

@ -76,11 +76,14 @@ exports.$detectIndentation = function(lines, fallback) {
var first = {score: 0, length: 0}; var first = {score: 0, length: 0};
var spaceIndents = 0; var spaceIndents = 0;
for (var i = 1; i < 12; i++) { for (var i = 1; i < 12; i++) {
var score = getScore(i);
if (i == 1) { if (i == 1) {
spaceIndents = getScore(i); spaceIndents = score;
var score = stats.length && 1; score = stats[1] ? 0.9 : 0.8;
if (!stats.length)
score = 0
} else } else
var score = getScore(i) / spaceIndents; score /= spaceIndents;
if (changes[i]) if (changes[i])
score += changes[i] / changesTotal; score += changes[i] / changesTotal;

View file

@ -255,7 +255,7 @@ var TextInput = function(parentNode, host) {
} else { } else {
return clipboardData.getData(mime); return clipboardData.getData(mime);
} }
} };
var doCopy = function(e, isCut) { var doCopy = function(e, isCut) {
var data = host.getCopyText(); var data = host.getCopyText();
@ -280,11 +280,11 @@ var TextInput = function(parentNode, host) {
var onCut = function(e) { var onCut = function(e) {
doCopy(e, true); doCopy(e, true);
} };
var onCopy = function(e) { var onCopy = function(e) {
doCopy(e, false); doCopy(e, false);
} };
var onPaste = function(e) { var onPaste = function(e) {
var data = handleClipboardData(e); var data = handleClipboardData(e);
@ -335,7 +335,8 @@ var TextInput = function(parentNode, host) {
// COMPOSITION // COMPOSITION
var onCompositionStart = function(e) { var onCompositionStart = function(e) {
if (inComposition || !host.onCompositionStart) return; if (inComposition || !host.onCompositionStart || host.$readOnly)
return;
// console.log("onCompositionStart", inComposition) // console.log("onCompositionStart", inComposition)
inComposition = {}; inComposition = {};
host.onCompositionStart(); host.onCompositionStart();
@ -351,7 +352,8 @@ var TextInput = function(parentNode, host) {
var onCompositionUpdate = function() { var onCompositionUpdate = function() {
// console.log("onCompositionUpdate", inComposition && JSON.stringify(text.value)) // console.log("onCompositionUpdate", inComposition && JSON.stringify(text.value))
if (!inComposition || !host.onCompositionUpdate) return; if (!inComposition || !host.onCompositionUpdate || host.$readOnly)
return;
var val = text.value.replace(/\x01/g, ""); var val = text.value.replace(/\x01/g, "");
if (inComposition.lastValue === val) return; if (inComposition.lastValue === val) return;
@ -370,7 +372,7 @@ var TextInput = function(parentNode, host) {
}; };
var onCompositionEnd = function(e) { var onCompositionEnd = function(e) {
if (!host.onCompositionEnd) return; if (!host.onCompositionEnd || host.$readOnly) return;
// console.log("onCompositionEnd", inComposition &&inComposition.lastValue) // console.log("onCompositionEnd", inComposition &&inComposition.lastValue)
var c = inComposition; var c = inComposition;
inComposition = false; inComposition = false;
@ -379,7 +381,7 @@ var TextInput = function(parentNode, host) {
var str = text.value.replace(/\x01/g, ""); var str = text.value.replace(/\x01/g, "");
// console.log(str, c.lastValue) // console.log(str, c.lastValue)
if (inComposition) if (inComposition)
return return;
else if (str == c.lastValue) else if (str == c.lastValue)
resetValue(); resetValue();
else if (!c.lastValue && str) { else if (!c.lastValue && str) {
@ -437,13 +439,14 @@ var TextInput = function(parentNode, host) {
if (!tempStyle) if (!tempStyle)
tempStyle = text.style.cssText; tempStyle = text.style.cssText;
text.style.cssText = (bringToFront ? "z-index:100000;" : "") text.style.cssText = (bringToFront ? "z-index:100000;" : "")
+ "height:" + text.style.height + ";"
+ (useragent.isIE ? "opacity:0.1;" : ""); + (useragent.isIE ? "opacity:0.1;" : "");
var rect = host.container.getBoundingClientRect(); var rect = host.container.getBoundingClientRect();
var style = dom.computedStyle(host.container); var style = dom.computedStyle(host.container);
var top = rect.top + (parseInt(style.borderTopWidth) || 0); var top = rect.top + (parseInt(style.borderTopWidth) || 0);
var left = rect.left + (parseInt(rect.borderLeftWidth) || 0); var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
var maxTop = rect.bottom - top - text.clientHeight; var maxTop = rect.bottom - top - text.clientHeight -2;
var move = function(e) { var move = function(e) {
text.style.left = e.clientX - left - 2 + "px"; text.style.left = e.clientX - left - 2 + "px";
text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px"; text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";

View file

@ -514,6 +514,8 @@ var inputBuffer = exports.inputBuffer = {
this.reset(); this.reset();
} }
handleCursorMove(editor); handleCursorMove(editor);
if (editor.curOp && editor.curOp.selectionChanged)
editor.renderer.scrollCursorIntoView();
}, },
isAccepting: function(type) { isAccepting: function(type) {

View file

@ -426,7 +426,7 @@ module.exports = {
var column = util.getRightNthChar(editor, cursor, param, count || 1); var column = util.getRightNthChar(editor, cursor, param, count || 1);
if (isRepeat && column == 0 && !(count > 1)) if (isRepeat && column == 0 && !(count > 1))
var column = util.getRightNthChar(editor, cursor, param, 2); column = util.getRightNthChar(editor, cursor, param, 2);
if (typeof column === "number") { if (typeof column === "number") {
cursor.column += column + (isSel ? 1 : 0); cursor.column += column + (isSel ? 1 : 0);
@ -444,8 +444,8 @@ module.exports = {
var cursor = editor.getCursorPosition(); var cursor = editor.getCursorPosition();
var column = util.getLeftNthChar(editor, cursor, param, count || 1); var column = util.getLeftNthChar(editor, cursor, param, count || 1);
if (isRepeat && column == 0 && !(count > 1)) if (isRepeat && column === 0 && !(count > 1))
var column = util.getLeftNthChar(editor, cursor, param, 2); column = util.getLeftNthChar(editor, cursor, param, 2);
if (typeof column === "number") { if (typeof column === "number") {
cursor.column -= column; cursor.column -= column;
@ -558,7 +558,7 @@ module.exports = {
content += "\n"; content += "\n";
if (content.length) { if (content.length) {
editor.navigateLineEnd() editor.navigateLineEnd();
editor.insert(content); editor.insert(content);
util.insertMode(editor); util.insertMode(editor);
} }
@ -575,7 +575,7 @@ module.exports = {
if (content.length) { if (content.length) {
if(row > 0) { if(row > 0) {
editor.navigateUp(); editor.navigateUp();
editor.navigateLineEnd() editor.navigateLineEnd();
editor.insert(content); editor.insert(content);
} else { } else {
editor.session.insert({row: 0, column: 0}, content); editor.session.insert({row: 0, column: 0}, content);

View file

@ -91,14 +91,12 @@ module.exports = {
count = count || 1; count = count || 1;
switch (param) { switch (param) {
case "c": case "c":
editor.$blockScrolling++;
editor.selection.$moveSelection(function() { editor.selection.$moveSelection(function() {
editor.selection.moveCursorBy(count - 1, 0); editor.selection.moveCursorBy(count - 1, 0);
}); });
var rows = editor.$getSelectedRows(); var rows = editor.$getSelectedRows();
range = new Range(rows.first, 0, rows.last, Infinity); range = new Range(rows.first, 0, rows.last, Infinity);
editor.session.remove(range); editor.session.remove(range);
editor.$blockScrolling--;
util.insertMode(editor); util.insertMode(editor);
break; break;
default: default:

View file

@ -58,6 +58,7 @@ var Gutter = function(parentEl) {
if (this.session) if (this.session)
this.session.removeEventListener("change", this.$updateAnnotations); this.session.removeEventListener("change", this.$updateAnnotations);
this.session = session; this.session = session;
if (session)
session.on("change", this.$updateAnnotations); session.on("change", this.$updateAnnotations);
}; };

View file

@ -95,6 +95,7 @@ var Text = function(parentEl) {
}; };
this.setSession = function(session) { this.setSession = function(session) {
this.session = session; this.session = session;
if (session)
this.$computeTabString(); this.$computeTabString();
}; };

View file

@ -49,7 +49,7 @@ exports.createElement = function(tag, ns) {
}; };
exports.hasCssClass = function(el, name) { exports.hasCssClass = function(el, name) {
var classes = el.className.split(/\s+/g); var classes = (el.className || "").split(/\s+/g);
return classes.indexOf(name) !== -1; return classes.indexOf(name) !== -1;
}; };

File diff suppressed because it is too large Load diff

View file

@ -40,8 +40,11 @@ var Worker = exports.Worker = function(sender) {
Mirror.call(this, sender); Mirror.call(this, sender);
this.setTimeout(400); this.setTimeout(400);
this.ruleset = null; this.ruleset = null;
this.setDisabledRules("ids"); this.setDisabledRules("ids|order-alphabetical");
this.setInfoRules("adjoining-classes|qualified-headings|zero-units|gradients|import|outline-none"); this.setInfoRules(
"adjoining-classes|qualified-headings|zero-units|gradients|" +
"import|outline-none|vendor-prefix"
);
}; };
oop.inherits(Worker, Mirror); oop.inherits(Worker, Mirror);

View file

@ -197,9 +197,7 @@ function DragdropHandler(mouseHandler) {
var vMovement = !prevCursor || cursor.row != prevCursor.row; var vMovement = !prevCursor || cursor.row != prevCursor.row;
var hMovement = !prevCursor || cursor.column != prevCursor.column; var hMovement = !prevCursor || cursor.column != prevCursor.column;
if (!cursorMovedTime || vMovement || hMovement) { if (!cursorMovedTime || vMovement || hMovement) {
editor.$blockScrolling += 1;
editor.moveCursorToPosition(cursor); editor.moveCursorToPosition(cursor);
editor.$blockScrolling -= 1;
cursorMovedTime = now; cursorMovedTime = now;
cursorPointOnCaretMoved = {x: x, y: y}; cursorPointOnCaretMoved = {x: x, y: y};
} else { } else {
@ -273,9 +271,7 @@ function DragdropHandler(mouseHandler) {
clearInterval(timerId); clearInterval(timerId);
editor.session.removeMarker(dragSelectionMarker); editor.session.removeMarker(dragSelectionMarker);
dragSelectionMarker = null; dragSelectionMarker = null;
editor.$blockScrolling += 1;
editor.selection.fromOrientedRange(range); editor.selection.fromOrientedRange(range);
editor.$blockScrolling -= 1;
if (editor.isFocused() && !isInternal) if (editor.isFocused() && !isInternal)
editor.renderer.$cursorLayer.setBlinking(!editor.getReadOnly()); editor.renderer.$cursorLayer.setBlinking(!editor.getReadOnly());
range = null; range = null;

View file

@ -112,7 +112,6 @@ function onMouseDown(e) {
var oldRange = selection.rangeList.rangeAtPoint(pos); var oldRange = selection.rangeList.rangeAtPoint(pos);
editor.$blockScrolling++;
editor.inVirtualSelectionMode = true; editor.inVirtualSelectionMode = true;
if (shift) { if (shift) {
@ -134,7 +133,6 @@ function onMouseDown(e) {
} }
selection.addRange(tmpSel); selection.addRange(tmpSel);
} }
editor.$blockScrolling--;
editor.inVirtualSelectionMode = false; editor.inVirtualSelectionMode = false;
}); });
@ -181,7 +179,6 @@ function onMouseDown(e) {
editor.removeSelectionMarkers(rectSel); editor.removeSelectionMarkers(rectSel);
if (!rectSel.length) if (!rectSel.length)
rectSel = [selection.toOrientedRange()]; rectSel = [selection.toOrientedRange()];
editor.$blockScrolling++;
if (initialRange) { if (initialRange) {
editor.removeSelectionMarker(initialRange); editor.removeSelectionMarker(initialRange);
selection.toSingleRange(initialRange); selection.toSingleRange(initialRange);
@ -190,7 +187,6 @@ function onMouseDown(e) {
selection.addRange(rectSel[i]); selection.addRange(rectSel[i]);
editor.inVirtualSelectionMode = false; editor.inVirtualSelectionMode = false;
editor.$mouseHandler.$clickSelection = null; editor.$mouseHandler.$clickSelection = null;
editor.$blockScrolling--;
}; };
var onSelectionInterval = blockSelect; var onSelectionInterval = blockSelect;

View file

@ -557,33 +557,6 @@ var Editor = require("./editor").Editor;
} }
}; };
// todo this should change when paste becomes a command
this.onPaste = function(text) {
if (this.$readOnly)
return;
var e = {text: text};
this._signal("paste", e);
text = e.text;
if (!this.inMultiSelectMode || this.inVirtualSelectionMode)
return this.insert(text);
var lines = text.split(/\r\n|\r|\n/);
var ranges = this.selection.rangeList.ranges;
if (lines.length > ranges.length || lines.length < 2 || !lines[1])
return this.commands.exec("insertstring", this, text);
for (var i = ranges.length; i--;) {
var range = ranges[i];
if (!range.isEmpty())
this.session.remove(range);
this.session.insert(range.start, lines[i]);
}
};
/** /**
* Finds and selects all the occurences of `needle`. * Finds and selects all the occurences of `needle`.
* @param {String} The text to find * @param {String} The text to find
@ -608,7 +581,6 @@ var Editor = require("./editor").Editor;
if (!ranges.length) if (!ranges.length)
return 0; return 0;
this.$blockScrolling += 1;
var selection = this.multiSelect; var selection = this.multiSelect;
if (!additive) if (!additive)
@ -621,8 +593,6 @@ var Editor = require("./editor").Editor;
if (range && selection.rangeList.rangeAtPoint(range.start)) if (range && selection.rangeList.rangeAtPoint(range.start))
selection.addRange(range, true); selection.addRange(range, true);
this.$blockScrolling -= 1;
return ranges.length; return ranges.length;
}; };
@ -720,7 +690,7 @@ var Editor = require("./editor").Editor;
* @param {Boolean} skip If `true`, removes the active selection range * @param {Boolean} skip If `true`, removes the active selection range
* @method Editor.selectMore * @method Editor.selectMore
**/ **/
this.selectMore = function(dir, skip) { this.selectMore = function(dir, skip, stopAtFirst) {
var session = this.session; var session = this.session;
var sel = session.multiSelect; var sel = session.multiSelect;
@ -729,18 +699,16 @@ var Editor = require("./editor").Editor;
range = session.getWordRange(range.start.row, range.start.column); range = session.getWordRange(range.start.row, range.start.column);
range.cursor = dir == -1 ? range.start : range.end; range.cursor = dir == -1 ? range.start : range.end;
this.multiSelect.addRange(range); this.multiSelect.addRange(range);
// todo add option for sublime like behavior if (stopAtFirst)
// return; return;
} }
var needle = session.getTextRange(range); var needle = session.getTextRange(range);
var newRange = find(session, needle, dir); var newRange = find(session, needle, dir);
if (newRange) { if (newRange) {
newRange.cursor = dir == -1 ? newRange.start : newRange.end; newRange.cursor = dir == -1 ? newRange.start : newRange.end;
this.$blockScrolling += 1;
this.session.unfold(newRange); this.session.unfold(newRange);
this.multiSelect.addRange(newRange); this.multiSelect.addRange(newRange);
this.$blockScrolling -= 1;
this.renderer.scrollCursorIntoView(null, 0.5); this.renderer.scrollCursorIntoView(null, 0.5);
} }
if (skip) if (skip)
@ -890,12 +858,12 @@ function isSamePoint(p1, p2) {
// adds multicursor support to a session // adds multicursor support to a session
exports.onSessionChange = function(e) { exports.onSessionChange = function(e) {
var session = e.session; var session = e.session;
if (!session.multiSelect) { if (session && !session.multiSelect) {
session.$selectionMarkers = []; session.$selectionMarkers = [];
session.selection.$initRangeList(); session.selection.$initRangeList();
session.multiSelect = session.selection; session.multiSelect = session.selection;
} }
this.multiSelect = session.multiSelect; this.multiSelect = session && session.multiSelect;
var oldSession = e.oldSession; var oldSession = e.oldSession;
if (oldSession) { if (oldSession) {
@ -907,16 +875,16 @@ exports.onSessionChange = function(e) {
oldSession.multiSelect.anchor.off("change", this.$checkMultiselectChange); oldSession.multiSelect.anchor.off("change", this.$checkMultiselectChange);
} }
if (session) {
session.multiSelect.on("addRange", this.$onAddRange); session.multiSelect.on("addRange", this.$onAddRange);
session.multiSelect.on("removeRange", this.$onRemoveRange); session.multiSelect.on("removeRange", this.$onRemoveRange);
session.multiSelect.on("multiSelect", this.$onMultiSelect); session.multiSelect.on("multiSelect", this.$onMultiSelect);
session.multiSelect.on("singleSelect", this.$onSingleSelect); session.multiSelect.on("singleSelect", this.$onSingleSelect);
session.multiSelect.lead.on("change", this.$checkMultiselectChange); session.multiSelect.lead.on("change", this.$checkMultiselectChange);
session.multiSelect.anchor.on("change", this.$checkMultiselectChange); session.multiSelect.anchor.on("change", this.$checkMultiselectChange);
}
// this.$onSelectionChange = this.onSelectionChange.bind(this); if (session && this.inMultiSelectMode != session.selection.inMultiSelectMode) {
if (this.inMultiSelectMode != session.selection.inMultiSelectMode) {
if (session.selection.inMultiSelectMode) if (session.selection.inMultiSelectMode)
this.$onMultiSelect(); this.$onMultiSelect();
else else

View file

@ -37,7 +37,6 @@ var oop = require("./lib/oop");
/** /**
* @class PlaceHolder * @class PlaceHolder
* *
*
**/ **/
/** /**
@ -48,7 +47,6 @@ var oop = require("./lib/oop");
* - mainClass (String): * - mainClass (String):
* - othersClass (String): * - othersClass (String):
* *
*
* @constructor * @constructor
**/ **/
@ -94,6 +92,10 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass)
var session = this.session; var session = this.session;
var pos = this.$pos; var pos = this.$pos;
this.selectionBefore = session.selection.toJSON();
if (session.selection.inMultiSelectMode)
session.selection.toSingleRange();
this.pos = doc.createAnchor(pos.row, pos.column); this.pos = doc.createAnchor(pos.row, pos.column);
this.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false); this.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false);
this.pos.on("change", function(event) { this.pos.on("change", function(event) {
@ -218,9 +220,9 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass)
**/ **/
this.onCursorChange = function(event) { this.onCursorChange = function(event) {
if (this.$updating) return; if (this.$updating || !this.session) return;
var pos = this.session.selection.getCursor(); var pos = this.session.selection.getCursor();
if(pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) { if (pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) {
this.showOtherMarkers(); this.showOtherMarkers();
this._emit("cursorEnter", event); this._emit("cursorEnter", event);
} else { } else {
@ -245,6 +247,7 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass)
this.others[i].detach(); this.others[i].detach();
} }
this.session.setUndoSelect(true); this.session.setUndoSelect(true);
this.session = null;
}; };
/** /**
@ -261,6 +264,8 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass)
for (var i = 0; i < undosRequired; i++) { for (var i = 0; i < undosRequired; i++) {
undoManager.undo(true); undoManager.undo(true);
} }
if (this.selectionBefore)
this.session.selection.fromJSON(this.selectionBefore);
}; };
}).call(PlaceHolder.prototype); }).call(PlaceHolder.prototype);

View file

@ -143,7 +143,7 @@ var Selection = function(session) {
**/ **/
this.getSelectionAnchor = function() { this.getSelectionAnchor = function() {
if (this.$isEmpty) if (this.$isEmpty)
return this.getSelectionLead() return this.getSelectionLead();
else else
return this.anchor.getPosition(); return this.anchor.getPosition();
}; };
@ -168,7 +168,7 @@ var Selection = function(session) {
if (this.$isEmpty) { if (this.$isEmpty) {
this.moveCursorTo(this.lead.row, this.lead.column + columns); this.moveCursorTo(this.lead.row, this.lead.column + columns);
return; return;
}; }
var anchor = this.getSelectionAnchor(); var anchor = this.getSelectionAnchor();
var lead = this.getSelectionLead(); var lead = this.getSelectionLead();
@ -474,7 +474,7 @@ var Selection = function(session) {
if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) { if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) {
this.moveCursorTo(fold.start.row, fold.start.column); this.moveCursorTo(fold.start.row, fold.start.column);
} else if (cursor.column == 0) { } else if (cursor.column === 0) {
// cursor is a line (start // cursor is a line (start
if (cursor.row > 0) { if (cursor.row > 0) {
this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length); this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);
@ -639,7 +639,7 @@ var Selection = function(session) {
var str = this.session.getFoldStringAt(row, column, -1); var str = this.session.getFoldStringAt(row, column, -1);
if (str == null) { if (str == null) {
str = this.doc.getLine(row).substring(0, column) str = this.doc.getLine(row).substring(0, column);
} }
var leftOfCursor = lang.stringReverse(str); var leftOfCursor = lang.stringReverse(str);
@ -691,13 +691,13 @@ var Selection = function(session) {
index ++; index ++;
if (whitespaceRe.test(ch)) { if (whitespaceRe.test(ch)) {
if (index > 2) { if (index > 2) {
index-- index--;
break; break;
} else { } else {
while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch)) while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
index ++; index ++;
if (index > 2) if (index > 2)
break break;
} }
} }
} }
@ -722,11 +722,11 @@ var Selection = function(session) {
var l = this.doc.getLength(); var l = this.doc.getLength();
do { do {
row++; row++;
rightOfCursor = this.doc.getLine(row) rightOfCursor = this.doc.getLine(row);
} while (row < l && /^\s*$/.test(rightOfCursor)) } while (row < l && /^\s*$/.test(rightOfCursor));
if (!/^\s+/.test(rightOfCursor)) if (!/^\s+/.test(rightOfCursor))
rightOfCursor = "" rightOfCursor = "";
column = 0; column = 0;
} }
@ -744,15 +744,15 @@ var Selection = function(session) {
return this.moveCursorTo(fold.start.row, fold.start.column); return this.moveCursorTo(fold.start.row, fold.start.column);
var line = this.session.getLine(row).substring(0, column); var line = this.session.getLine(row).substring(0, column);
if (column == 0) { if (column === 0) {
do { do {
row--; row--;
line = this.doc.getLine(row); line = this.doc.getLine(row);
} while (row > 0 && /^\s*$/.test(line)) } while (row > 0 && /^\s*$/.test(line));
column = line.length; column = line.length;
if (!/\s+$/.test(line)) if (!/\s+$/.test(line))
line = "" line = "";
} }
var leftOfCursor = lang.stringReverse(line); var leftOfCursor = lang.stringReverse(line);
@ -859,12 +859,12 @@ var Selection = function(session) {
this.lead.detach(); this.lead.detach();
this.anchor.detach(); this.anchor.detach();
this.session = this.doc = null; this.session = this.doc = null;
} };
this.fromOrientedRange = function(range) { this.fromOrientedRange = function(range) {
this.setSelectionRange(range, range.cursor == range.start); this.setSelectionRange(range, range.cursor == range.start);
this.$desiredColumn = range.desiredColumn || this.$desiredColumn; this.$desiredColumn = range.desiredColumn || this.$desiredColumn;
} };
this.toOrientedRange = function(range) { this.toOrientedRange = function(range) {
var r = this.getRange(); var r = this.getRange();
@ -880,7 +880,7 @@ var Selection = function(session) {
range.cursor = this.isBackwards() ? range.start : range.end; range.cursor = this.isBackwards() ? range.start : range.end;
range.desiredColumn = this.$desiredColumn; range.desiredColumn = this.$desiredColumn;
return range; return range;
} };
/** /**
* Saves the current cursor position and calls `func` that can change the cursor * Saves the current cursor position and calls `func` that can change the cursor
@ -901,7 +901,7 @@ var Selection = function(session) {
} finally { } finally {
this.moveCursorToPosition(start); this.moveCursorToPosition(start);
} }
} };
this.toJSON = function() { this.toJSON = function() {
if (this.rangeCount) { if (this.rangeCount) {
@ -944,10 +944,10 @@ var Selection = function(session) {
for (var i = this.ranges.length; i--; ) { for (var i = this.ranges.length; i--; ) {
if (!this.ranges[i].isEqual(data[i])) if (!this.ranges[i].isEqual(data[i]))
return false return false;
} }
return true; return true;
} };
}).call(Selection.prototype); }).call(Selection.prototype);

View file

@ -497,6 +497,10 @@ var SnippetManager = function() {
var snippetMap = this.snippetMap; var snippetMap = this.snippetMap;
var snippetNameMap = this.snippetNameMap; var snippetNameMap = this.snippetNameMap;
var self = this; var self = this;
if (!snippets)
snippets = [];
function wrapRegexp(src) { function wrapRegexp(src) {
if (src && !/^\^?\(.*\)\$?$|^\\b$/.test(src)) if (src && !/^\^?\(.*\)\$?$|^\\b$/.test(src))
src = "(?:" + src + ")"; src = "(?:" + src + ")";
@ -549,7 +553,7 @@ var SnippetManager = function() {
s.endTriggerRe = new RegExp(s.endTrigger, "", true); s.endTriggerRe = new RegExp(s.endTrigger, "", true);
} }
if (snippets.content) if (snippets && snippets.content)
addSnippet(snippets); addSnippet(snippets);
else if (Array.isArray(snippets)) else if (Array.isArray(snippets))
snippets.forEach(addSnippet); snippets.forEach(addSnippet);

View file

@ -232,10 +232,7 @@ var VirtualRenderer = function(container, theme) {
this.session.doc.off("changeNewLineMode", this.onChangeNewLineMode); this.session.doc.off("changeNewLineMode", this.onChangeNewLineMode);
this.session = session; this.session = session;
if (!session) if (session && this.scrollMargin.top && session.getScrollTop() <= 0)
return;
if (this.scrollMargin.top && session.getScrollTop() <= 0)
session.setScrollTop(-this.scrollMargin.top); session.setScrollTop(-this.scrollMargin.top);
this.$cursorLayer.setSession(session); this.$cursorLayer.setSession(session);
@ -243,6 +240,9 @@ var VirtualRenderer = function(container, theme) {
this.$markerFront.setSession(session); this.$markerFront.setSession(session);
this.$gutterLayer.setSession(session); this.$gutterLayer.setSession(session);
this.$textLayer.setSession(session); this.$textLayer.setSession(session);
if (!session)
return;
this.$loop.schedule(this.CHANGE_FULL); this.$loop.schedule(this.CHANGE_FULL);
this.session.$setFontMetrics(this.$fontMetrics); this.session.$setFontMetrics(this.$fontMetrics);
@ -643,18 +643,17 @@ var VirtualRenderer = function(container, theme) {
var val = this.textarea.value.replace(/^\x01+/, ""); var val = this.textarea.value.replace(/^\x01+/, "");
w *= (this.session.$getStringScreenWidth(val)[0]+2); w *= (this.session.$getStringScreenWidth(val)[0]+2);
h += 2; h += 2;
posTop -= 1;
} }
posLeft -= this.scrollLeft; posLeft -= this.scrollLeft;
if (posLeft > this.$size.scrollerWidth - w) if (posLeft > this.$size.scrollerWidth - w)
posLeft = this.$size.scrollerWidth - w; posLeft = this.$size.scrollerWidth - w;
posLeft -= this.scrollBar.width; posLeft += this.gutterWidth;
this.textarea.style.height = h + "px"; this.textarea.style.height = h + "px";
this.textarea.style.width = w + "px"; this.textarea.style.width = w + "px";
this.textarea.style.right = Math.max(0, this.$size.scrollerWidth - posLeft - w) + "px"; this.textarea.style.left = Math.min(posLeft, this.$size.scrollerWidth - w) + "px";
this.textarea.style.bottom = Math.max(0, this.$size.height - posTop - h) + "px"; this.textarea.style.top = Math.min(posTop, this.$size.height - h) + "px";
}; };
/** /**
@ -915,6 +914,8 @@ var VirtualRenderer = function(container, theme) {
this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight); this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight);
// this.$loop.changes = 0; // this.$loop.changes = 0;
this.desiredHeight = desiredHeight; this.desiredHeight = desiredHeight;
this._signal("autosize");
} }
}; };