Merge pull request #802 from ajaxorg/misc

Misc
This commit is contained in:
Fabian Jakobs 2012-06-11 10:28:07 -07:00
commit df0550bf1d
16 changed files with 1536 additions and 1506 deletions

File diff suppressed because it is too large Load diff

View file

@ -295,10 +295,15 @@ exports.commands = [{
readOnly: true
}, {
name: "jumptomatching",
bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
bindKey: bindKey("Ctrl-P", "Ctrl-P"),
exec: function(editor) { editor.jumpToMatching(); },
multiSelectAction: "forEach",
readOnly: true
}, {
name: "selecttomatching",
bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
exec: function(editor) { editor.jumpToMatching(true); },
readOnly: true
},
// commands disabled in readOnly mode
@ -319,6 +324,11 @@ exports.commands = [{
bindKey: bindKey("Ctrl-D", "Command-D"),
exec: function(editor) { editor.removeLines(); },
multiSelectAction: "forEach"
}, {
name: "duplicateSelection",
bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
exec: function(editor) { editor.duplicateSelection(); },
multiSelectAction: "forEach"
}, {
name: "togglecomment",
bindKey: bindKey("Ctrl-/", "Command-/"),

View file

@ -827,7 +827,8 @@ var EditSession = function(text, mode) {
try {
module = require(mode);
} catch (e) {};
if (module)
// sometimes require returns empty object (this bug is present in requirejs 2 as well)
if (module && module.Mode)
return done(module);
// set mode to text until loading is finished

View file

@ -40,6 +40,7 @@ define(function(require, exports, module) {
"use strict";
var TokenIterator = require("../token_iterator").TokenIterator;
var Range = require("../range").Range;
/**
* class BracketMatch
@ -76,15 +77,56 @@ function BracketMatch() {
if (charBeforeCursor == "") return null;
var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
if (!match) {
if (!match)
return null;
if (match[1])
return this.$findClosingBracket(match[1], position);
else
return this.$findOpeningBracket(match[2], position);
};
this.getBracketRange = function(pos) {
var line = this.getLine(pos.row);
var before = true, range;
var chr = line.charAt(pos.column-1);
var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
if (!match) {
chr = line.charAt(pos.column);
pos.column++;
match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
before = false;
}
if (!match)
return null;
if (match[1]) {
return this.$findClosingBracket(match[1], position);
var bracketPos = this.$findClosingBracket(match[1], pos);
if (!bracketPos)
return null;
range = Range.fromPoints(pos, bracketPos);
if (!before) {
range.end.column++;
range.start.column--;
}
range.cursor = range.end;
} else {
return this.$findOpeningBracket(match[2], position);
var bracketPos = this.$findOpeningBracket(match[2], pos);
if (!bracketPos)
return null;
range = Range.fromPoints(bracketPos, pos);
if (!before) {
range.start.column++;
range.end.column--;
}
range.cursor = range.start;
}
if (!before)
pos.column--;
return range;
};
this.$brackets = {

View file

@ -1348,6 +1348,24 @@ var Editor = function(renderer, session) {
this.clearSelection();
};
this.duplicateSelection = function() {
var sel = this.selection;
var doc = this.session;
var range = sel.getRange();
if (range.isEmpty()) {
var row = range.start.row;
doc.duplicateLines(row, row);
} else {
var reverse = sel.isBackwards()
var point = sel.isBackwards() ? range.start : range.end;
var endPoint = doc.insert(point, doc.getTextRange(range), false);
range.start = point;
range.end = endPoint;
sel.setSelectionRange(range, reverse)
}
};
/** related to: EditSession.moveLinesDown
* Editor.moveLinesDown() -> Number
* + (Number): On success, it returns -1.
@ -1660,8 +1678,11 @@ var Editor = function(renderer, session) {
**/
this.centerSelection = function() {
var range = this.getSelectionRange();
var line = Math.floor(range.start.row + (range.end.row - range.start.row) / 2);
this.renderer.scrollToLine(line, true);
var pos = {
row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
}
this.renderer.alignCursor(pos, 0.5);
};
/** related to: Selection.getCursor
@ -1746,21 +1767,34 @@ var Editor = function(renderer, session) {
* Moves the cursor's row and column to the next matching bracket.
*
**/
this.jumpToMatching = function() {
this.jumpToMatching = function(select) {
var cursor = this.getCursorPosition();
var pos = this.session.findMatchingBracket(cursor);
if (!pos) {
cursor.column += 1;
pos = this.session.findMatchingBracket(cursor);
}
if (!pos) {
cursor.column -= 2;
pos = this.session.findMatchingBracket(cursor);
}
var range = this.session.getBracketRange(cursor);
if (!range) {
range = editor.find({
needle: /[{}()\[\]]/g,
preventScroll:true,
start: {row: cursor.row, column: cursor.column - 1}
});
if (!range)
return;
var pos = range.start;
if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
range = this.session.getBracketRange(pos);
}
pos = range && range.cursor || pos;
if (pos) {
this.clearSelection();
this.moveCursorTo(pos.row, pos.column);
if (select) {
if (range && range.isEqual(editor.getSelectionRange()))
this.clearSelection();
else
this.selection.selectTo(pos.row, pos.column);
} else {
this.clearSelection();
this.moveCursorTo(pos.row, pos.column);
}
}
};

View file

@ -246,7 +246,6 @@ var TextInput = function(parentNode, host) {
});
this.focus = function() {
host.onFocus();
reset();
text.focus();
};
@ -281,10 +280,12 @@ var TextInput = function(parentNode, host) {
if (host.renderer.$keepTextAreaAtCursor)
host.renderer.$keepTextAreaAtCursor = null;
event.capture(host.container, function(e) {
text.style.left = e.clientX - 2 + "px";
text.style.top = e.clientY - 2 + "px";
}, onContextMenuClose);
// on windows context menu is opened after mouseup
if (useragent.isGecko && useragent.isWin)
event.capture(host.container, function(e) {
text.style.left = e.clientX - 2 + "px";
text.style.top = e.clientY - 2 + "px";
}, onContextMenuClose);
};
function onContextMenuClose() {

View file

@ -300,27 +300,27 @@ module.exports = {
case "(":
case "{":
case "[":
var cursor = editor.getCursorPosition()
var end = editor.session.$findClosingBracket(param, cursor, /paren/)
var cursor = editor.getCursorPosition();
var end = editor.session.$findClosingBracket(param, cursor, /paren/);
if (!end)
return;
var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/)
var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/);
if (!start)
return;
start.column ++;
editor.selection.setSelectionRange(Range.fromPoints(start, end))
break
editor.selection.setSelectionRange(Range.fromPoints(start, end));
break;
case "'":
case "\"":
case '"':
case "/":
var end = find(editor, param, 1)
var end = find(editor, param, 1);
if (!end)
return;
var start = find(editor, param, -1)
var start = find(editor, param, -1);
if (!start)
return;
editor.selection.setSelectionRange(Range.fromPoints(start.end, end.start))
break
editor.selection.setSelectionRange(Range.fromPoints(start.end, end.start));
break;
}
}
},

View file

@ -93,7 +93,7 @@ exports.preventDefault = function(e) {
exports.getButton = function(e) {
if (e.type == "dblclick")
return 0;
else if (e.type == "contextmenu")
if (e.type == "contextmenu" || (e.ctrlKey && useragent.isMac))
return 2;
// DOM Event

View file

@ -80,7 +80,7 @@ var MarkdownHighlightRules = function() {
return "markup.heading." + value.length;
},
regex : "^#{1,6}"
}, github_embed("javascript", "js-"),
}, github_embed("(?:javascript|js)", "js-"),
github_embed("xml", "xml-"),
github_embed("html", "html-"),
github_embed("css", "css-"),

View file

@ -90,7 +90,7 @@ function DefaultHandlers(mouseHandler) {
// 2: contextmenu, 1: linux paste
editor.textInput.onContextMenu(ev.domEvent);
return ev.stop();
return; // stopping event here breaks contextmenu on ff mac
}
// if this click caused the editor to be focused should not clear the
@ -109,13 +109,8 @@ function DefaultHandlers(mouseHandler) {
// a selection.
this.startSelect(pos);
} else if (inSelection) {
var e = ev.domEvent;
if ((e.ctrlKey || e.altKey)) {
this.startDrag();
} else {
this.mousedownEvent.time = (new Date()).getTime();
this.setState("dragWait");
}
this.mousedownEvent.time = (new Date()).getTime();
this.setState("dragWait");
}
this.captureMouse(ev);
@ -146,8 +141,9 @@ function DefaultHandlers(mouseHandler) {
} else if (cmp == 1) {
anchor = this.$clickSelection.start;
} else {
cursor = this.$clickSelection.end;
anchor = this.$clickSelection.start;
var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
cursor = orientedRange.cursor;
anchor = orientedRange.anchor;
}
editor.selection.setSelectionAnchor(anchor.row, anchor.column);
}
@ -175,8 +171,9 @@ function DefaultHandlers(mouseHandler) {
cursor = range.end;
anchor = range.start;
} else {
cursor = this.$clickSelection.end;
anchor = this.$clickSelection.start;
var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
cursor = orientedRange.cursor;
anchor = orientedRange.anchor;
}
editor.selection.setSelectionAnchor(anchor.row, anchor.column);
}
@ -221,7 +218,7 @@ function DefaultHandlers(mouseHandler) {
this.startSelect();
};
this.dragWait = function() {
this.dragWait = function(e) {
var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
var time = (new Date()).getTime();
var editor = this.editor;
@ -229,7 +226,7 @@ function DefaultHandlers(mouseHandler) {
if (distance > DRAG_OFFSET) {
this.startSelect();
} else if (time - this.mousedownEvent.time > editor.getDragDelay()) {
this.startDrag()
this.startDrag();
}
};
@ -277,12 +274,21 @@ function DefaultHandlers(mouseHandler) {
this.onDoubleClick = function(ev) {
var pos = ev.getDocumentPosition();
var editor = this.editor;
var session = editor.session
var range = session.getBracketRange(pos);
if (range) {
if (range.isEmpty()) {
range.start.column--;
range.end.column++;
}
this.$clickSelection = range;
this.setState("select");
return;
}
this.$clickSelection = editor.selection.getWordRange(pos.row, pos.column);
this.setState("selectByWords");
editor.moveCursorToPosition(pos);
editor.selection.selectWord();
this.$clickSelection = editor.getSelectionRange();
};
this.onTripleClick = function(ev) {
@ -334,4 +340,16 @@ function calcDistance(ax, ay, bx, by) {
return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
}
function calcRangeOrientation(range, cursor) {
if (range.start.row == range.end.row)
var cmp = 2 * cursor.column - range.start.column - range.end.column;
else
var cmp = 2 * cursor.row - range.start.row - range.end.row;
if (cmp < 0)
return {cursor: range.start, anchor: range.end};
else
return {cursor: range.end, anchor: range.start};
}
});

View file

@ -40,6 +40,7 @@ define(function(require, exports, module) {
"use strict";
var event = require("../lib/event");
var useragent = require("../lib/useragent");
/*
* Custom Ace mouse event
@ -130,9 +131,9 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
return this.domEvent.shiftKey;
};
this.getAccelKey = function() {
return this.domEvent.ctrlKey || this.domEvent.metaKey ;
};
this.getAccelKey = useragent.isMac
? function() { return this.domEvent.metaKey; }
: function() { return this.domEvent.ctrlKey; };
}).call(MouseEvent.prototype);

View file

@ -130,12 +130,12 @@ var MouseHandler = function(editor) {
renderer.$keepTextAreaAtCursor = null;
var self = this;
var onMouseSelection = function(e) {
var onMouseMove = function(e) {
self.x = e.clientX;
self.y = e.clientY;
};
var onMouseSelectionEnd = function(e) {
var onCaptureEnd = function(e) {
clearInterval(timerId);
self[self.state + "End"] && self[self.state + "End"](e);
self.$clickSelection = null;
@ -145,12 +145,12 @@ var MouseHandler = function(editor) {
}
};
var onSelectionInterval = function() {
var onCaptureInterval = function() {
self[self.state] && self[self.state]();
}
event.capture(this.editor.container, onMouseSelection, onMouseSelectionEnd);
var timerId = setInterval(onSelectionInterval, 20);
event.capture(this.editor.container, onMouseMove, onCaptureEnd);
var timerId = setInterval(onCaptureInterval, 20);
};
}).call(MouseHandler.prototype);

View file

@ -53,18 +53,14 @@ function onMouseDown(e) {
var ctrl = e.getAccelKey();
var button = e.getButton();
if (e.editor.inMultiSelectMode && button == 2) {
e.editor.textInput.onContextMenu(e.domEvent);
return;
}
if (!ctrl && !alt) {
if (e.editor.inMultiSelectMode) {
if (button == 0) {
e.editor.exitMultiSelectMode();
} else if (button == 2) {
var editor = e.editor;
var selectionEmpty = editor.selection.isEmpty();
editor.textInput.onContextMenu({x: e.clientX, y: e.clientY}, selectionEmpty);
event.capture(editor.container, function(){}, editor.textInput.onContextMenuClose);
e.stop();
}
}
if (button == 0 && e.editor.inMultiSelectMode)
e.editor.exitMultiSelectMode();
return;
}

View file

@ -90,7 +90,6 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
* [start.row/start.column] -> [end.row/end.column]
*
**/
this.toString = function() {
return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]");
@ -424,7 +423,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
/**
/**
* Range.compareInside(row, column) -> Number
* - row (Number): A row point to compare with
* - column (Number): A column point to compare with
@ -449,7 +448,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
/**
/**
* Range.clipRows(firstRow, lastRow) -> Range
* - firstRow (Number): The starting row
* - lastRow (Number): The ending row
@ -488,7 +487,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
/**
/**
* Range.extend(row, column) -> Range
* - row (Number): A new row to extend to
* - column (Number): A new column to extend to
@ -513,7 +512,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return (this.start.row == this.end.row && this.start.column == this.end.column);
};
/**
/**
* Range.isMultiLine() -> Boolean
*
* Returns true if the range spans across multiple lines.
@ -523,7 +522,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return (this.start.row !== this.end.row);
};
/**
/**
* Range.clone() -> Range
*
* Returns a duplicate of the calling range.
@ -533,7 +532,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(this.start, this.end);
};
/**
/**
* Range.collapseRows() -> Range
*
* Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.
@ -546,7 +545,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return new Range(this.start.row, 0, this.end.row, 0)
};
/**
/**
* Range.toScreenRange(session) -> Range
* - session (EditSession): The `EditSession` to retrieve coordinates from
*

View file

@ -467,14 +467,14 @@ var VirtualRenderer = function(container, theme) {
return;
if (!gutterReady) {
var ch = this.$gutterLayer.element.children
var oldEl = ch[this.$gutterLineHighlight - this.layerConfig.firstRow];
if (oldEl)
dom.removeCssClass(oldEl, "ace_gutter_active_line");
var lineEl, ch = this.$gutterLayer.element.children;
var index = this.$gutterLineHighlight - this.layerConfig.firstRow;
if (index >= 0 && (lineEl = ch[index]))
dom.removeCssClass(lineEl, "ace_gutter_active_line");
var newEl = ch[i - this.layerConfig.firstRow];
if (newEl)
dom.addCssClass(newEl, "ace_gutter_active_line");
index = i - this.layerConfig.firstRow;
if (index >= 0 && (lineEl = ch[index]))
dom.addCssClass(lineEl, "ace_gutter_active_line");
}
this.$gutterLayer.removeGutterDecoration(this.$gutterLineHighlight, "ace_gutter_active_line");

View file

@ -56,14 +56,17 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
} else {
// We are running in RequireJS.
workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
// nameToUrl is renamed to toUrl in requirejs 2
if (require.nameToUrl && !require.toUrl)
require.toUrl = require.nameToUrl;
workerUrl = this.$normalizePath(require.toUrl("ace/worker/worker", null, "_"));
}
this.$worker = new Worker(workerUrl);
var tlns = {};
for (var i=0; i<topLevelNamespaces.length; i++) {
var ns = topLevelNamespaces[i];
var path = this.$normalizePath(require.nameToUrl(ns, null, "_").replace(/.js$/, ""));
var path = this.$normalizePath(require.toUrl(ns, null, "_").replace(/.js$/, ""));
tlns[ns] = path;
}