From 4c4ab098709e24ae7d2a3cbb444561783ea6203e Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 29 Dec 2013 19:56:29 +0400 Subject: [PATCH 01/23] add goToNextError command --- lib/ace/commands/default_commands.js | 38 +++++ lib/ace/ext/error_marker.js | 212 +++++++++++++++++++++++++++ lib/ace/line_widgets.js | 51 ++++--- 3 files changed, 278 insertions(+), 23 deletions(-) create mode 100644 lib/ace/ext/error_marker.js diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index e4a8212e..b3a0c3a0 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -52,6 +52,26 @@ exports.commands = [{ }); }, readOnly: true +}, { + name: "goToNextError", + bindKey: bindKey("Alt-E", "Ctrl-E"), + exec: function(editor) { + config.loadModule("ace/ext/error_marker", function(module) { + module.showErrorMarker(editor, 1); + }); + }, + scrollIntoView: "center", + readOnly: true +}, { + name: "goToPreviousError", + bindKey: bindKey("Alt-Shift-E", "Ctrl-Shift-E"), + exec: function(editor) { + config.loadModule("ace/ext/error_marker", function(module) { + module.showErrorMarker(editor, -1); + }); + }, + scrollIntoView: "center", + readOnly: true }, { name: "selectall", bindKey: bindKey("Ctrl-A", "Command-A"), @@ -165,6 +185,7 @@ exports.commands = [{ exec: function(editor) { editor.getSelection().selectFileStart(); }, multiSelectAction: "forEach", readOnly: true, + scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "gotostart", @@ -172,6 +193,7 @@ exports.commands = [{ exec: function(editor) { editor.navigateFileStart(); }, multiSelectAction: "forEach", readOnly: true, + scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "selectup", @@ -191,6 +213,7 @@ exports.commands = [{ exec: function(editor) { editor.getSelection().selectFileEnd(); }, multiSelectAction: "forEach", readOnly: true, + scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "gotoend", @@ -198,90 +221,105 @@ exports.commands = [{ exec: function(editor) { editor.navigateFileEnd(); }, multiSelectAction: "forEach", readOnly: true, + scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "selectdown", bindKey: bindKey("Shift-Down", "Shift-Down"), exec: function(editor) { editor.getSelection().selectDown(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "golinedown", bindKey: bindKey("Down", "Down|Ctrl-N"), exec: function(editor, args) { editor.navigateDown(args.times); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectwordleft", bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"), exec: function(editor) { editor.getSelection().selectWordLeft(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotowordleft", bindKey: bindKey("Ctrl-Left", "Option-Left"), exec: function(editor) { editor.navigateWordLeft(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selecttolinestart", bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"), exec: function(editor) { editor.getSelection().selectLineStart(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotolinestart", bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"), exec: function(editor) { editor.navigateLineStart(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectleft", bindKey: bindKey("Shift-Left", "Shift-Left"), exec: function(editor) { editor.getSelection().selectLeft(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotoleft", bindKey: bindKey("Left", "Left|Ctrl-B"), exec: function(editor, args) { editor.navigateLeft(args.times); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectwordright", bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"), exec: function(editor) { editor.getSelection().selectWordRight(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotowordright", bindKey: bindKey("Ctrl-Right", "Option-Right"), exec: function(editor) { editor.navigateWordRight(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selecttolineend", bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"), exec: function(editor) { editor.getSelection().selectLineEnd(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotolineend", bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"), exec: function(editor) { editor.navigateLineEnd(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectright", bindKey: bindKey("Shift-Right", "Shift-Right"), exec: function(editor) { editor.getSelection().selectRight(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotoright", bindKey: bindKey("Right", "Right|Ctrl-F"), exec: function(editor, args) { editor.navigateRight(args.times); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectpagedown", diff --git a/lib/ace/ext/error_marker.js b/lib/ace/ext/error_marker.js new file mode 100644 index 00000000..a55e9a25 --- /dev/null +++ b/lib/ace/ext/error_marker.js @@ -0,0 +1,212 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; +var LineWidgets = require("ace/line_widgets").LineWidgets; +var dom = require("ace/lib/dom"); +var Range = require("ace/range").Range; + +function binarySearch(array, needle, comparator) { + var first = 0; + var last = array.length - 1; + + while (first <= last) { + var mid = (first + last) >> 1; + var c = comparator(needle, array[mid]); + if (c > 0) + first = mid + 1; + else if (c < 0) + last = mid - 1; + else + return mid; + } + + // Return the nearest lesser index, "-1" means "0, "-2" means "1", etc. + return -(first + 1); +} + +function findAnnotations(session, row, dir) { + var annotations = session.getAnnotations().sort(Range.comparePoints); + if (!annotations.length) + return; + + var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints); + if (i < 0) + i = -i - 1; + + if (i >= annotations.length - 1) + i = dir > 0 ? 0 : annotations.length - 1; + else if (i === 0 && dir < 0) + i = annotations.length - 1; + + var annotation = annotations[i]; + if (!annotation || !dir) + return; + + if (annotation.row === row) { + do { + annotation = annotations[i += dir]; + } while (annotation && annotation.row === row); + if (!annotation) + return annotations.slice(); + } + + + var matched = []; + row = annotation.row; + do { + matched[dir < 0 ? "unshift" : "push"](annotation); + annotation = annotations[i += dir]; + } while (annotation && annotation.row == row); + return matched.length && matched; +} + +exports.showErrorMarker = function(editor, dir) { + var session = editor.session; + if (!session.widgetManager) { + session.widgetManager = new LineWidgets(session); + session.widgetManager.attach(editor); + } + + var pos = editor.getCursorPosition(); + var row = pos.row; + var oldWidget = session.lineWidgets && session.lineWidgets[row]; + if (oldWidget) { + oldWidget.destroy(); + } else { + row -= dir; + } + var annotations = findAnnotations(session, row, dir); + var gutterAnno; + if (annotations) { + var annotation = annotations[0]; + if (annotation.pos && annotation.column == null) + pos.column = annotation.pos.sc; + pos.row = annotation.row; + gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row]; + } else if (oldWidget) { + return; + } else { + gutterAnno = { + text: ["Looks good!"], + className: "ace_ok" + }; + } + editor.session.unfold(pos.row); + editor.selection.moveCursorToPosition(pos); + editor.selection.clearSelection(); + + var w = { + row: pos.row, + fixedWidth: true, + coverGutter: true, + el: dom.createElement("div") + }; + var el = w.el.appendChild(dom.createElement("div")); + var arrow = w.el.appendChild(dom.createElement("div")); + arrow.className = "error_widget_arrow " + gutterAnno.className; + + var left = editor.renderer.$cursorLayer + .getPixelPosition(pos).left; + arrow.style.left = left + editor.renderer.gutterWidth - 5 + "px"; + + w.el.className = "error_widget_wrapper"; + el.className = "error_widget " + gutterAnno.className; + el.innerHTML = gutterAnno.text.join("
"); + + var kb = { + handleKeyboard:function(_,hashId, keyString) { + if (hashId === 0 && keyString === "esc") { + w.destroy(); + return true; + } + } + }; + + w.destroy = function() { + if (editor.$mouseHandler.isMousePressed) + return; + editor.keyBinding.removeKeyboardHandler(kb); + session.widgetManager.removeLineWidget(w); + editor.off("changeSelection", w.destroy); + editor.off("changeSession", w.destroy); + editor.off("mouseup", w.destroy); + editor.off("change", w.destroy); + }; + + editor.keyBinding.addKeyboardHandler(kb); + editor.on("changeSelection", w.destroy); + editor.on("changeSession", w.destroy); + editor.on("mouseup", w.destroy); + editor.on("change", w.destroy); + + editor.session.widgetManager.addLineWidget(w); + + w.el.onmousedown = editor.focus.bind(editor); +}; + + +dom.importCssString("\ + .error_widget_wrapper {\ + background: inherit;\ + color: inherit;\ + border:none\ + }\ + .error_widget {\ + border-top: solid 2px;\ + border-bottom: solid 2px;\ + margin: 5px 0;\ + padding: 10px 40px;\ + white-space: pre-wrap;\ + }\ + .error_widget.ace_error, .error_widget_arrow.ace_error{\ + border-color: #ff5a5a\ + }\ + .error_widget.ace_warning, .error_widget_arrow.ace_warning{\ + border-color: #F1D817\ + }\ + .error_widget.ace_info, .error_widget_arrow.ace_info{\ + border-color: #5a5a5a\ + }\ + .error_widget.ace_ok, .error_widget_arrow.ace_ok{\ + border-color: #5aaa5a\ + }\ + .error_widget_arrow {\ + position: absolute;\ + border: solid 5px;\ + border-top-color: transparent!important;\ + border-right-color: transparent!important;\ + border-left-color: transparent!important;\ + top: -5px;\ + }\ +", ""); + +}); \ No newline at end of file diff --git a/lib/ace/line_widgets.js b/lib/ace/line_widgets.js index 597b3ca2..94ad9ddf 100644 --- a/lib/ace/line_widgets.js +++ b/lib/ace/line_widgets.js @@ -48,12 +48,13 @@ function LineWidgets(session) { this.detach = this.detach.bind(this); this.session.on("change", this.updateOnChange); -}; +} (function() { this.getRowLength = function(row) { + var h; if (this.lineWidgets) - var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; + h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; else h = 0; if (!this.$useWrapMode || !this.$wrapData[row]) { @@ -104,7 +105,8 @@ function LineWidgets(session) { editor.renderer.off("beforeRender", this.measureWidgets); editor.renderer.off("afterRender", this.renderWidgets); - this.session.lineWidgets.forEach(function(w) { + var lineWidgets = this.session.lineWidgets; + lineWidgets && lineWidgets.forEach(function(w) { if (w && w.el && w.el.parentNode) { w._inDocument = false; w.el.parentNode.removeChild(w.el); @@ -113,8 +115,8 @@ function LineWidgets(session) { }; this.updateOnChange = function(e) { - var cells = this.session.lineWidgets; - if (!cells) return; + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) return; var delta = e.data; var range = delta.range; @@ -124,24 +126,24 @@ function LineWidgets(session) { if (len === 0) { // return } else if (delta.action == "removeText" || delta.action == "removeLines") { - var removed = cells.splice(startRow + 1, len); + var removed = lineWidgets.splice(startRow + 1, len); removed.forEach(function(w) { w && this.removeLineWidget(w); }, this); this.$updateRows(); } else { - var args = Array(len); + var args = new Array(len); args.unshift(startRow, 0); - cells.splice.apply(cells, args); + lineWidgets.splice.apply(lineWidgets, args); this.$updateRows(); } }; this.$updateRows = function() { - var lw = this.session.lineWidgets; - if (!lw) return; + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) return; var noWidgets = true; - lw.forEach(function(w, i) { + lineWidgets.forEach(function(w, i) { if (w) { noWidgets = false; w.row = i; @@ -149,11 +151,11 @@ function LineWidgets(session) { }); if (noWidgets) this.session.lineWidgets = null; - } + }; this.addLineWidget = function(w) { if (!this.session.lineWidgets) - this.session.lineWidgets = Array(this.session.getLength()) + this.session.lineWidgets = new Array(this.session.getLength()); this.session.lineWidgets[w.row] = w; @@ -164,6 +166,8 @@ function LineWidgets(session) { } if (w.el) { dom.addCssClass(w.el, "ace_lineWidgetContainer"); + w.el.style.position = "absolute"; + w.el.style.zIndex = 5; renderer.container.appendChild(w.el); w._inDocument = true; } @@ -191,7 +195,8 @@ function LineWidgets(session) { if (w.editor && w.editor.destroy) try { w.editor.destroy(); } catch(e){} - this.session.lineWidgets[w.row] = undefined; + if (this.session.lineWidgets) + this.session.lineWidgets[w.row] = undefined; this.session._emit("changeFold", {data:{start:{row: w.row}}}); this.$updateRows(); }; @@ -202,13 +207,13 @@ function LineWidgets(session) { }; this.measureWidgets = function(e, renderer) { - var ws = this.session._changedWidgets; + var changedWidgets = this.session._changedWidgets; var config = renderer.layerConfig; - if (!ws || !ws.length) return; + if (!changedWidgets || !changedWidgets.length) return; var min = Infinity; - for (var i = 0; i < ws.length; i++) { - var w = ws[i].lineWidget; + for (var i = 0; i < changedWidgets.length; i++) { + var w = changedWidgets[i]; if (!w._inDocument) { w._inDocument = true; renderer.container.appendChild(w.el); @@ -242,13 +247,13 @@ function LineWidgets(session) { this.renderWidgets = function(e, renderer) { var config = renderer.layerConfig; - var ws = this.session.lineWidgets; - if (!ws) + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) return; var first = Math.min(this.firstRow, config.firstRow); - var last = Math.max(this.lastRow, config.lastRow, ws.length); + var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length); - while (first > 0 && !ws[first]) + while (first > 0 && !lineWidgets[first]) first--; this.firstRow = config.firstRow; @@ -256,7 +261,7 @@ function LineWidgets(session) { renderer.$cursorLayer.config = config; for (var i = first; i <= last; i++) { - var w = ws[i]; + var w = lineWidgets[i]; if (!w || !w.el) continue; if (!w._inDocument) { From 6e254f25a1a129b5ee3900b7a854375d732f3ac9 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 29 Dec 2013 19:57:00 +0400 Subject: [PATCH 02/23] fix wrap option getter --- lib/ace/edit_session.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index a63ceeef..5b2eb747 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -2478,7 +2478,14 @@ config.defineOptions(EditSession.prototype, "session", { this.$wrap = value; }, get: function() { - return this.getUseWrapMode() ? this.getWrapLimitRange().min || "free" : "off"; + if (this.getUseWrapMode()) { + if (this.$wrap == -1) + return "printMargin"; + if (!this.getWrapLimitRange().min) + return "free"; + return this.$wrap; + } + return "off"; }, handlesSet: true }, From 3f7f3257770bf0556052cc6b62bf6bdd43b910fa Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 29 Dec 2013 19:57:49 +0400 Subject: [PATCH 03/23] return removed folds from removeFolds --- lib/ace/edit_session/folding.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/ace/edit_session/folding.js b/lib/ace/edit_session/folding.js index 474818b2..09d67b95 100644 --- a/lib/ace/edit_session/folding.js +++ b/lib/ace/edit_session/folding.js @@ -454,13 +454,16 @@ function Folding() { if (expandInner) { this.removeFolds(folds); } else { - // TODO: might need to remove and add folds in one go instead of using + var subFolds = folds; + // TODO: might be better to remove and add folds in one go instead of using // expandFolds several times. - while (folds.length) { - this.expandFolds(folds); - folds = this.getFoldsInRangeList(range); + while (subFolds.length) { + this.expandFolds(subFolds); + subFolds = this.getFoldsInRangeList(range); } } + if (folds.length) + return folds; }; /* From 5b151a3db4e65b544629091ee40508f79a8a8e5f Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 29 Dec 2013 19:59:16 +0400 Subject: [PATCH 04/23] fix scrolling speed on firefox ux --- lib/ace/lib/event.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/ace/lib/event.js b/lib/ace/lib/event.js index 4d407dfc..36250d2f 100644 --- a/lib/ace/lib/event.js +++ b/lib/ace/lib/event.js @@ -118,8 +118,8 @@ exports.capture = function(el, eventHandler, releaseCaptureHandler) { exports.addMouseWheelListener = function(el, callback) { if ("onmousewheel" in el) { - var factor = 8; exports.addListener(el, "mousewheel", function(e) { + var factor = 8; if (e.wheelDeltaX !== undefined) { e.wheelX = -e.wheelDeltaX / factor; e.wheelY = -e.wheelDeltaY / factor; @@ -131,8 +131,19 @@ exports.addMouseWheelListener = function(el, callback) { }); } else if ("onwheel" in el) { exports.addListener(el, "wheel", function(e) { - e.wheelX = (e.deltaX || 0) * 5; - e.wheelY = (e.deltaY || 0) * 5; + var factor = 0.35; + switch (e.deltaMode) { + case e.DOM_DELTA_PIXEL: + e.wheelX = e.deltaX * factor || 0; + e.wheelY = e.deltaY * factor || 0; + break; + case e.DOM_DELTA_LINE: + case e.DOM_DELTA_PAGE: + e.wheelX = (e.deltaX || 0) * 5; + e.wheelY = (e.deltaY || 0) * 5; + break; + } + callback(e); }); } else { From b6a4a34fd2da988047890b2605f86809d472e6c4 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 29 Dec 2013 20:02:14 +0400 Subject: [PATCH 05/23] togglecomment should not scroll if part of the selection is visible --- lib/ace/editor.js | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 6486a881..dfca96b8 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -133,7 +133,6 @@ var Editor = function(renderer, session) { if (command.aceCommandGroup == "fileJump") { if (this.lastFileJumpPos && !this.curOp.selectionChanged) { this.selection.fromJSON(this.lastFileJumpPos); - return; } } this.endOperation(e); @@ -168,7 +167,8 @@ var Editor = function(renderer, session) { this.$opResetTimer.schedule(); this.curOp = { command: commadEvent.command || {}, - args: commadEvent.args + args: commadEvent.args, + scrollTop: this.renderer.scrollTop }; var command = this.curOp.command; @@ -187,16 +187,24 @@ var Editor = function(renderer, session) { case "center": this.renderer.scrollCursorIntoView(null, 0.5); break; + case "animate": case "cursor": this.renderer.scrollCursorIntoView(); break; case "selectionPart": - this.renderer.scrollCursorIntoView(); + var range = this.selection.getRange(); + var config = this.renderer.layerConfig; + if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) { + this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead); + } break; default: break; } + if (command.scrollIntoView == "animate") + this.renderer.animateScrolling(this.curOp.scrollTop); } + this.prevOp = this.curOp; this.curOp = null; } @@ -243,7 +251,6 @@ var Editor = function(renderer, session) { * Sets a new key handler, such as "vim" or "windows". * @param {String} keyboardHandler The new key handler * - * **/ this.setKeyboardHandler = function(keyboardHandler) { if (!keyboardHandler) { @@ -277,7 +284,6 @@ var Editor = function(renderer, session) { * @event changeSession * @param {Object} e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s. * - * **/ /** * Sets a new editsession to use. This method also emits the `'changeSession'` event. @@ -875,7 +881,7 @@ var Editor = function(renderer, session) { } if (text == "\n" || text == "\r\n") { - var line = session.getLine(cursor.row) + var line = session.getLine(cursor.row); if (cursor.column > line.search(/\S|$/)) { var d = line.substr(cursor.column).search(/\S|$/); session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d); @@ -1202,7 +1208,7 @@ var Editor = function(renderer, session) { var state = session.getState(range.start.row); var new_range = session.getMode().transformAction(state, 'deletion', this, session, range); - if (range.end.column == 0) { + if (range.end.column === 0) { var text = session.getTextRange(range); if (text[text.length - 1] == "\n") { var line = session.getLine(range.end.row); @@ -1361,7 +1367,7 @@ var Editor = function(renderer, session) { } } - var line = session.getLine(range.start.row) + var line = session.getLine(range.start.row); var position = range.start; var size = session.getTabSize(); var column = session.documentToScreenColumn(position.row, position.column); @@ -1632,7 +1638,7 @@ var Editor = function(renderer, session) { var last = rows.end.row; var first = rows.start.row; while (i--) { - var rows = ranges[i].collapseRows(); + rows = ranges[i].collapseRows(); if (first - rows.end.row <= 1) first = rows.end.row; else @@ -1736,11 +1742,11 @@ var Editor = function(renderer, session) { var rows = dir * Math.floor(config.height / config.lineHeight); this.$blockScrolling++; - if (select == true) { + if (select === true) { this.selection.$moveSelection(function(){ this.moveCursorBy(rows, 0); }); - } else if (select == false) { + } else if (select === false) { this.selection.moveCursorBy(rows, 0); this.selection.clearSelection(); } @@ -2069,10 +2075,8 @@ var Editor = function(renderer, session) { * Moves the cursor to the end of the current file. Note that this does de-select the current selection. **/ this.navigateFileEnd = function() { - var scrollTop = this.renderer.scrollTop; this.selection.moveCursorFileEnd(); this.clearSelection(); - this.renderer.animateScrolling(scrollTop); }; /** @@ -2080,10 +2084,8 @@ var Editor = function(renderer, session) { * Moves the cursor to the start of the current file. Note that this does de-select the current selection. **/ this.navigateFileStart = function() { - var scrollTop = this.renderer.scrollTop; this.selection.moveCursorFileStart(); this.clearSelection(); - this.renderer.animateScrolling(scrollTop); }; /** @@ -2266,7 +2268,7 @@ var Editor = function(renderer, session) { var scrollTop = this.renderer.scrollTop; this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5); - if (animate != false) + if (animate !== false) this.renderer.animateScrolling(scrollTop); }; From 37b3dc1efd944abed228195cf7f0b6b00b177f7b Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 29 Dec 2013 20:03:08 +0400 Subject: [PATCH 06/23] tweak modes --- lib/ace/mode/c9search_highlight_rules.js | 4 +++- lib/ace/mode/css_highlight_rules.js | 2 +- lib/ace/mode/javascript/jshint.js | 3 ++- lib/ace/mode/javascript_highlight_rules.js | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/ace/mode/c9search_highlight_rules.js b/lib/ace/mode/c9search_highlight_rules.js index ce11bf5d..3e9af29d 100644 --- a/lib/ace/mode/c9search_highlight_rules.js +++ b/lib/ace/mode/c9search_highlight_rules.js @@ -75,6 +75,8 @@ var C9SearchHighlightRules = function() { tokens.push({type: types[2], value: skipped}); if (m[0]) tokens.push({type: types[3], value: m[0]}); + else if (!skipped) + break; } } if (last < str.length) @@ -99,7 +101,7 @@ var C9SearchHighlightRules = function() { search = lang.escapeRegExp(search); if (/whole/.test(options)) search = "\\b" + search + "\\b"; - var regex = safeCreateRegexp( + var regex = search && safeCreateRegexp( "(" + search + ")", / sensitive/.test(options) ? "g" : "ig" ); diff --git a/lib/ace/mode/css_highlight_rules.js b/lib/ace/mode/css_highlight_rules.js index 12b3d8fa..b9c20423 100644 --- a/lib/ace/mode/css_highlight_rules.js +++ b/lib/ace/mode/css_highlight_rules.js @@ -37,7 +37,7 @@ var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; /* All exports are for Stylus highlighter */ -var supportType = exports.supportType = "animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index"; +var supportType = exports.supportType = "animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index"; var supportFunction = exports.supportFunction = "rgb|rgba|url|attr|counter|counters"; var supportConstant = exports.supportConstant = "absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero"; var supportConstantColor = exports.supportConstantColor = "aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow"; diff --git a/lib/ace/mode/javascript/jshint.js b/lib/ace/mode/javascript/jshint.js index 04f36539..84254ffa 100644 --- a/lib/ace/mode/javascript/jshint.js +++ b/lib/ace/mode/javascript/jshint.js @@ -3228,7 +3228,8 @@ var JSHINT = (function () { if (this.id === "++" || this.id === "--") { if (state.option.plusplus) { warning("W016", this, this.id); - } else if ((!this.right.identifier || isReserved(this.right)) && + } else if (this.right && + (!this.right.identifier || isReserved(this.right)) && this.right.id !== "." && this.right.id !== "[") { warning("W017", this); } diff --git a/lib/ace/mode/javascript_highlight_rules.js b/lib/ace/mode/javascript_highlight_rules.js index f950da89..98247565 100644 --- a/lib/ace/mode/javascript_highlight_rules.js +++ b/lib/ace/mode/javascript_highlight_rules.js @@ -242,7 +242,7 @@ var JavaScriptHighlightRules = function() { }, { // flag token: "string.regexp", - regex: "/\\w*", + regex: "/[sxngimy]*", next: "no_regex" }, { // invalid operators @@ -251,7 +251,7 @@ var JavaScriptHighlightRules = function() { }, { // operators token : "constant.language.escape", - regex: /\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?]/ + regex: /\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/ }, { token : "constant.language.delimiter", regex: /\|/ From 90b2a6cd772bb9a2997a639c06caa55503613057 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 29 Dec 2013 20:05:23 +0400 Subject: [PATCH 07/23] fix multiselect mouse interaction issues --- lib/ace/mouse/dragdrop_handler.js | 4 +++- lib/ace/mouse/multi_select_handler.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/ace/mouse/dragdrop_handler.js b/lib/ace/mouse/dragdrop_handler.js index 3a4bc188..b3b10608 100644 --- a/lib/ace/mouse/dragdrop_handler.js +++ b/lib/ace/mouse/dragdrop_handler.js @@ -384,6 +384,8 @@ function DragdropHandler(mouseHandler) { var button = e.getButton(); var clickCount = e.domEvent.detail || 1; if (clickCount === 1 && button === 0 && inSelection) { + if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey())) + return; this.mousedownEvent.time = Date.now(); var eventTarget = e.domEvent.target || e.domEvent.srcElement; if ("unselectable" in eventTarget) @@ -391,7 +393,7 @@ function DragdropHandler(mouseHandler) { if (editor.getDragDelay()) { // https://code.google.com/p/chromium/issues/detail?id=286700 if (useragent.isWebKit) { - self.cancelDrag = true; + this.cancelDrag = true; var mouseTarget = editor.container; mouseTarget.draggable = true; } diff --git a/lib/ace/mouse/multi_select_handler.js b/lib/ace/mouse/multi_select_handler.js index 2e0cda7b..dc01bd6c 100644 --- a/lib/ace/mouse/multi_select_handler.js +++ b/lib/ace/mouse/multi_select_handler.js @@ -105,7 +105,8 @@ function onMouseDown(e) { } var oldRange = selection.rangeList.rangeAtPoint(pos); - + + editor.$blockScrolling++; editor.once("mouseup", function() { var tmpSel = selection.toOrientedRange(); @@ -118,6 +119,7 @@ function onMouseDown(e) { } selection.addRange(tmpSel); } + editor.$blockScrolling--; }); } else if (alt && button == 0) { From 714e1a592c0d78c91ac05e9ff2e96a73db25d7ae Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 29 Dec 2013 20:07:08 +0400 Subject: [PATCH 08/23] fix resize issues --- lib/ace/renderloop.js | 2 +- lib/ace/virtual_renderer.js | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/ace/renderloop.js b/lib/ace/renderloop.js index ccbe98e1..6d31bd13 100644 --- a/lib/ace/renderloop.js +++ b/lib/ace/renderloop.js @@ -55,7 +55,7 @@ var RenderLoop = function(onRender, win) { //this.onRender(change); //return; this.changes = this.changes | change; - if (!this.pending) { + if (!this.pending && this.changes) { this.pending = true; var _self = this; event.nextFrame(function() { diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index dbf02aee..02d17d64 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -127,7 +127,7 @@ var VirtualRenderer = function(container, theme) { this.$textLayer.addEventListener("changeCharacterSize", function() { _self.updateCharacterSize(); - _self.onResize(true); + _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height); _self._signal("changeCharacterSize"); }); @@ -1272,10 +1272,11 @@ var VirtualRenderer = function(container, theme) { clearInterval(this.$timer); _self.session.setScrollTop(steps.shift()); + // trick session to think it's already scrolled to not loose toValue + _self.session.$scrollTop = toValue; this.$timer = setInterval(function() { if (steps.length) { _self.session.setScrollTop(steps.shift()); - // trick session to think it's already scrolled to not loose toValue _self.session.$scrollTop = toValue; } else if (toValue != null) { _self.session.$scrollTop = -1; @@ -1534,7 +1535,7 @@ var VirtualRenderer = function(container, theme) { * **/ this.setStyle = function(style, include) { - dom.setCssClass(this.container, style, include != false); + dom.setCssClass(this.container, style, include !== false); }; /** @@ -1545,6 +1546,11 @@ var VirtualRenderer = function(container, theme) { this.unsetStyle = function(style) { dom.removeCssClass(this.container, style); }; + + this.setCursorStyle = function(style) { + if (this.content.style.cursor != style) + this.content.style.cursor = style; + }; /** * @param {String} cursorStyle A css cursor style From edee507fd92f0732d45d33363b80cebdf395d0ee Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 29 Dec 2013 15:00:14 +0400 Subject: [PATCH 09/23] update site --- index.html | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 59504235..f82b72da 100644 --- a/index.html +++ b/index.html @@ -952,7 +952,7 @@ if (match) { Decor
  • - Divshot
  • @@ -1050,14 +1050,13 @@ if (match) { RunPHPCode
  • - + InstaEDU
  • - CloudCmd + Cloud Commander
  • md browserify-markdown-editor
  • +
  • + + Siteleaf +
  • +
  • +
    + ColorSublime +
  • +
  • + + iMDone +
  • BakeMyCss @@ -1153,7 +1168,7 @@ if (match) {
  • +

    - Your Site Here + Your Site Here
  • From 9a5bd3cd659b7e83bbc9a522292d389f410b90d3 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 30 Dec 2013 01:42:12 +0400 Subject: [PATCH 10/23] include error_marker addon in the build --- lib/ace/ace.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ace/ace.js b/lib/ace/ace.js index 773f2279..a2261355 100644 --- a/lib/ace/ace.js +++ b/lib/ace/ace.js @@ -54,6 +54,7 @@ require("./keyboard/hash_handler"); require("./placeholder"); require("./mode/folding/fold_mode"); require("./theme/textmate"); +require("./ext/error_marker"); exports.config = require("./config"); From 3cc3043951059c73f12b3756d2073dfeb84ab634 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 30 Dec 2013 01:56:58 +0400 Subject: [PATCH 11/23] update js highlighter test --- lib/ace/mode/_test/text_javascript.txt | 2 +- lib/ace/mode/_test/tokens_javascript.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/ace/mode/_test/text_javascript.txt b/lib/ace/mode/_test/text_javascript.txt index 6e180795..48d4af7d 100644 --- a/lib/ace/mode/_test/text_javascript.txt +++ b/lib/ace/mode/_test/text_javascript.txt @@ -10,7 +10,7 @@ a/=b/c //test tokenize reg exps a=/b/g a+/b/g -a = 1 + /2 + 1/b +a = 1 + /2 + 1/gimyxk a=/a/ / /a/ case /a/.test(c) //test tokenize multi-line comment containing a single line comment diff --git a/lib/ace/mode/_test/tokens_javascript.json b/lib/ace/mode/_test/tokens_javascript.json index 5044f21e..f527aa98 100644 --- a/lib/ace/mode/_test/tokens_javascript.json +++ b/lib/ace/mode/_test/tokens_javascript.json @@ -96,7 +96,8 @@ ["text"," "], ["string.regexp","/2 "], ["constant.language.escape","+"], - ["string.regexp"," 1/b"] + ["string.regexp"," 1/gimyx"], + ["identifier","k"] ],[ "no_regex", ["identifier","a"], From 425404ff297e14be1b67d023946f04e7dd9387c4 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 30 Dec 2013 02:05:57 +0400 Subject: [PATCH 12/23] fix #1737 reset padding only if previous theme had custom padding --- lib/ace/virtual_renderer.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 02d17d64..ae85c4f0 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -1495,6 +1495,11 @@ var VirtualRenderer = function(container, theme) { if (_self.theme) dom.removeCssClass(_self.container, _self.theme.cssClass); + var padding = "padding" in module ? module.padding + : "padding" in (_self.theme || {}) ? 4 : _self.$padding; + if (_self.$padding && padding != _self.$padding) + _self.setPadding(padding); + // this is kept only for backwards compatibility _self.$theme = module.cssClass; @@ -1502,10 +1507,6 @@ var VirtualRenderer = function(container, theme) { dom.addCssClass(_self.container, module.cssClass); dom.setCssClass(_self.container, "ace_dark", module.isDark); - var padding = "padding" in module ? module.padding : 4; - if (_self.$padding && padding != _self.$padding) - _self.setPadding(padding); - // force re-measure of the gutter width if (_self.$size) { _self.$size.width = 0; From 0b1630d6fac3d95ad0dc979864393fd47056baba Mon Sep 17 00:00:00 2001 From: DanyaPostfactum Date: Mon, 30 Dec 2013 20:13:00 +1000 Subject: [PATCH 13/23] Refactor tooltip to separate class. --- demo/kitchen-sink/token_tooltip.js | 85 +++++---------- lib/ace/css/editor.css | 11 +- lib/ace/mouse/default_gutter_handler.js | 58 ++++++---- lib/ace/tooltip.js | 138 ++++++++++++++++++++++++ 4 files changed, 208 insertions(+), 84 deletions(-) create mode 100644 lib/ace/tooltip.js diff --git a/demo/kitchen-sink/token_tooltip.js b/demo/kitchen-sink/token_tooltip.js index f182824a..9e607f69 100644 --- a/demo/kitchen-sink/token_tooltip.js +++ b/demo/kitchen-sink/token_tooltip.js @@ -32,25 +32,26 @@ define(function(require, exports, module) { "use strict"; var dom = require("ace/lib/dom"); +var oop = require("ace/lib/oop"); var event = require("ace/lib/event"); var Range = require("ace/range").Range; +var Tooltip = require("ace/tooltip").Tooltip; -var tooltipNode; - -var TokenTooltip = function(editor) { +function TokenTooltip (editor) { if (editor.tokenTooltip) return; - editor.tokenTooltip = this; + Tooltip.call(this, editor.container); + editor.tokenTooltip = this; this.editor = editor; - - editor.tooltip = tooltipNode || this.$init(); this.update = this.update.bind(this); this.onMouseMove = this.onMouseMove.bind(this); this.onMouseOut = this.onMouseOut.bind(this); event.addListener(editor.renderer.scroller, "mousemove", this.onMouseMove); event.addListener(editor.renderer.content, "mouseout", this.onMouseOut); -}; +} + +oop.inherits(TokenTooltip, Tooltip); (function(){ this.token = {}; @@ -86,15 +87,10 @@ var TokenTooltip = function(editor) { } if (!token) { session.removeMarker(this.marker); - tooltipNode.style.display = "none"; - this.isOpen = false; + this.hide(); return; } - if (!this.isOpen) { - tooltipNode.style.display = ""; - this.isOpen = true; - } - + var tokenText = token.type; if (token.state) tokenText += "|" + token.state; @@ -102,15 +98,15 @@ var TokenTooltip = function(editor) { tokenText += "\n merge"; if (token.stateTransitions) tokenText += "\n " + token.stateTransitions.join("\n "); - + if (this.tokenText != tokenText) { - tooltipNode.textContent = tokenText; - this.tooltipWidth = tooltipNode.offsetWidth; - this.tooltipHeight = tooltipNode.offsetHeight; + this.setText(tokenText); + this.width = this.getWidth(); + this.height = this.getHeight(); this.tokenText = tokenText; } - - this.updateTooltipPosition(this.x, this.y); + + this.show(null, this.x, this.y); this.token = token; session.removeMarker(this.marker); @@ -123,56 +119,34 @@ var TokenTooltip = function(editor) { this.y = e.clientY; if (this.isOpen) { this.lastT = e.timeStamp; - this.updateTooltipPosition(this.x, this.y); + this.setPosition(this.x, this.y); } if (!this.$timer) this.$timer = setTimeout(this.update, 100); }; - + this.onMouseOut = function(e) { - var t = e && e.relatedTarget; - var ct = e && e.currentTarget; - while(t && (t = t.parentNode)) { - if (t == ct) - return; - } - tooltipNode.style.display = "none"; + if (e && e.currentTarget.contains(e.relatedTarget)) + return; + this.hide(); this.editor.session.removeMarker(this.marker); this.$timer = clearTimeout(this.$timer); - this.isOpen = false; - }; - - this.updateTooltipPosition = function(x, y) { - var st = tooltipNode.style; - if (x + 10 + this.tooltipWidth > this.maxWidth) - x = window.innerWidth - this.tooltipWidth - 10; - if (y > window.innerHeight * 0.75 || y + 20 + this.tooltipHeight > this.maxHeight) - y = y - this.tooltipHeight - 30; - - st.left = x + 10 + "px"; - st.top = y + 20 + "px"; }; - this.$init = function() { - tooltipNode = document.documentElement.appendChild(dom.createElement("div")); - var st = tooltipNode.style; - st.position = "fixed"; - st.display = "none"; - st.background = "lightyellow"; - st.borderRadius = ""; - st.border = "1px solid gray"; - st.padding = "1px"; - st.zIndex = 1000; - st.fontFamily = "monospace"; - st.whiteSpace = "pre-line"; - return tooltipNode; + this.setPosition = function(x, y) { + if (x + 10 + this.width > this.maxWidth) + x = window.innerWidth - this.width - 10; + if (y > window.innerHeight * 0.75 || y + 20 + this.height > this.maxHeight) + y = y - this.height - 30; + + Tooltip.prototype.setPosition.call(this, x + 10, y + 20); }; this.destroy = function() { this.onMouseOut(); event.removeListener(this.editor.renderer.scroller, "mousemove", this.onMouseMove); event.removeListener(this.editor.renderer.content, "mouseout", this.onMouseOut); - delete this.editor.tokenTooltip; + delete this.editor.tokenTooltip; }; }).call(TokenTooltip.prototype); @@ -180,4 +154,3 @@ var TokenTooltip = function(editor) { exports.TokenTooltip = TokenTooltip; }); - diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css index c27acfd6..b3a137f3 100644 --- a/lib/ace/css/editor.css +++ b/lib/ace/css/editor.css @@ -301,7 +301,7 @@ background-position: center center, top left; } -.ace_gutter-tooltip { +.ace_tooltip { background-color: #FFF; background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1)); background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1)); @@ -309,21 +309,22 @@ border-radius: 1px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); color: black; - display: inline-block; - max-width: 500px; - padding: 4px; + display: block; + max-width: 100%; + padding: 3px 4px; position: fixed; z-index: 999999; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; cursor: default; - white-space: pre-line; + white-space: pre; word-wrap: break-word; line-height: normal; font-style: normal; font-weight: normal; letter-spacing: normal; + pointer-events: none; } .ace_folding-enabled > .ace_gutter-cell { diff --git a/lib/ace/mouse/default_gutter_handler.js b/lib/ace/mouse/default_gutter_handler.js index 1ad8119c..42fbb02a 100644 --- a/lib/ace/mouse/default_gutter_handler.js +++ b/lib/ace/mouse/default_gutter_handler.js @@ -31,11 +31,14 @@ define(function(require, exports, module) { "use strict"; var dom = require("../lib/dom"); +var oop = require("../lib/oop"); var event = require("../lib/event"); +var Tooltip = require("../tooltip").Tooltip; function GutterHandler(mouseHandler) { var editor = mouseHandler.editor; var gutter = editor.renderer.$gutterLayer; + var tooltip = new GutterTooltip(editor.container); mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) { if (!editor.isFocused() || e.getButton() != 0) @@ -63,18 +66,9 @@ function GutterHandler(mouseHandler) { }); - var tooltipTimeout, mouseEvent, tooltip, tooltipAnnotation; - function createTooltip() { - tooltip = dom.createElement("div"); - tooltip.className = "ace_gutter-tooltip"; - tooltip.style.display = "none"; - editor.container.appendChild(tooltip); - } + var tooltipTimeout, mouseEvent, tooltipAnnotation; function showTooltip() { - if (!tooltip) { - createTooltip(); - } var row = mouseEvent.getDocumentPosition().row; var annotation = gutter.$annotations[row]; if (!annotation) @@ -92,8 +86,8 @@ function GutterHandler(mouseHandler) { return; tooltipAnnotation = annotation.text.join("
    "); - tooltip.style.display = "block"; - tooltip.innerHTML = tooltipAnnotation; + tooltip.setHtml(tooltipAnnotation); + tooltip.show(); editor.on("mousewheel", hideTooltip); moveTooltip(mouseEvent); @@ -103,23 +97,14 @@ function GutterHandler(mouseHandler) { if (tooltipTimeout) tooltipTimeout = clearTimeout(tooltipTimeout); if (tooltipAnnotation) { - tooltip.style.display = "none"; + tooltip.hide(); tooltipAnnotation = null; editor.removeEventListener("mousewheel", hideTooltip); } } function moveTooltip(e) { - var rect = editor.renderer.$gutter.getBoundingClientRect(); - tooltip.style.left = e.x + 15 + "px"; - if (e.y + 3 * editor.renderer.lineHeight + 15 < rect.bottom) { - tooltip.style.bottom = ""; - tooltip.style.top = e.y + 15 + "px"; - } else { - tooltip.style.top = ""; - var innerHeight = window.innerHeight || document.documentElement.clientHeight; - tooltip.style.bottom = innerHeight - e.y + 5 + "px"; - } + tooltip.setPosition(e.x, e.y); } mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) { @@ -156,6 +141,33 @@ function GutterHandler(mouseHandler) { editor.on("changeSession", hideTooltip); } +function GutterTooltip(parentNode) { + Tooltip.call(this, parentNode); +} + +oop.inherits(GutterTooltip, Tooltip); + +(function(){ + this.setPosition = function(x, y) { + var windowWidth = window.innerWidth || document.documentElement.clientWidth; + var windowHeight = window.innerHeight || document.documentElement.clientHeight; + var width = this.getWidth(); + var height = this.getHeight(); + x += 15; + y += 15; + if (x + width > windowWidth) { + x -= (x + width) - windowWidth; + } + if (y + height > windowHeight) { + y -= 20 + height; + } + Tooltip.prototype.setPosition.call(this, x, y); + }; + +}).call(GutterTooltip.prototype); + + + exports.GutterHandler = GutterHandler; }); diff --git a/lib/ace/tooltip.js b/lib/ace/tooltip.js new file mode 100644 index 00000000..1f5502d6 --- /dev/null +++ b/lib/ace/tooltip.js @@ -0,0 +1,138 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var dom = require("./lib/dom"); + +/** + * @class Tooltip + **/ + +/** + * @param {Element} parentNode + * + * @constructor + **/ +function Tooltip (parentNode) { + this.isOpen = false; + this.$element = null; + this.$parentNode = parentNode; +} + +(function() { + this.$init = function() { + this.$element = dom.createElement("div"); + this.$element.className = "ace_tooltip"; + this.$element.style.display = "none"; + this.$parentNode.appendChild(this.$element); + return this.$element; + }; + + /** + * @returns {Element} + **/ + this.getElement = function() { + return this.$element || this.$init(); + }; + + /** + * @param {String} text + **/ + this.setText = function(text) { + dom.setInnerText(this.getElement(), text); + }; + + /** + * @param {String} html + **/ + this.setHtml = function(html) { + this.getElement().innerHTML = html; + }; + + /** + * @param {Number} x + * @param {Number} y + **/ + this.setPosition = function(x, y) { + this.getElement().style.left = x + "px"; + this.getElement().style.top = y + "px"; + }; + + /** + * @param {String} className + **/ + this.setClassName = function(className) { + dom.addCssClass(this.getElement(), className); + }; + + /** + * @param {String} text + * @param {Number} x + * @param {Number} y + **/ + this.show = function(text, x, y) { + if (text != null) + this.setText(text); + if (x != null && y != null) + this.setPosition(x, y); + if (!this.isOpen) { + this.getElement().style.display = "block"; + this.isOpen = true; + } + }; + + this.hide = function() { + if (this.isOpen) { + this.getElement().style.display = "none"; + this.isOpen = false; + } + }; + + /** + * @returns {Number} + **/ + this.getHeight = function() { + return this.getElement().offsetHeight; + }; + + /** + * @returns {Number} + **/ + this.getWidth = function() { + return this.getElement().offsetWidth; + }; + +}).call(Tooltip.prototype); + +exports.Tooltip = Tooltip; +}); From ccc7d6dda884d3e260f601231a13ebcec72f03a7 Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 31 Dec 2013 16:17:01 +0400 Subject: [PATCH 14/23] add more sites --- index.html | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index f82b72da..9c1b03c9 100644 --- a/index.html +++ b/index.html @@ -938,11 +938,10 @@ if (match) { Debuggex
  • -
    S
    + -webkit-font-smoothing: antialiased; text-align: center; position: absolute;">S Slim Text
  • @@ -1117,6 +1116,17 @@ if (match) { BakeMyCss
  • +
  • + + Code Combat +
  • +
  • +
    + Spark Core +
  • Sky Edit
  • From 8f109ea371c6c735ef9109e7856dafd6035723e7 Mon Sep 17 00:00:00 2001 From: Derk-Jan Hartman Date: Thu, 2 Jan 2014 13:04:24 +0100 Subject: [PATCH 15/23] Repair label of themes in themelist. This was broken after c563f15e93e5a30533f0ef54504649d30b59f034 --- lib/ace/ext/menu_tools/add_editor_menu_options.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ace/ext/menu_tools/add_editor_menu_options.js b/lib/ace/ext/menu_tools/add_editor_menu_options.js index fd56859b..0c95e790 100644 --- a/lib/ace/ext/menu_tools/add_editor_menu_options.js +++ b/lib/ace/ext/menu_tools/add_editor_menu_options.js @@ -86,7 +86,7 @@ module.exports.addEditorMenuOptions = function addEditorMenuOptions (editor) { editor.menuOptions.setTheme = themelist.themes.map(function(theme) { return { - 'textContent' : theme.desc, + 'textContent' : theme.caption, 'value' : theme.theme }; }); @@ -100,4 +100,4 @@ module.exports.addEditorMenuOptions = function addEditorMenuOptions (editor) { }; -}); \ No newline at end of file +}); From c40bf3b172d86cc8baa0537f7128bbd43439e997 Mon Sep 17 00:00:00 2001 From: rmsmith Date: Fri, 3 Jan 2014 21:04:23 +0200 Subject: [PATCH 16/23] dart_highlight_rules : add 'with' to `keywordDeclaration` 'with' clauses are used for mixin application in Dart, e.g: `class ToggleButton extends Button with Toggleable { ... }` --- lib/ace/mode/dart_highlight_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/mode/dart_highlight_rules.js b/lib/ace/mode/dart_highlight_rules.js index 08055502..ea49ca70 100644 --- a/lib/ace/mode/dart_highlight_rules.js +++ b/lib/ace/mode/dart_highlight_rules.js @@ -13,7 +13,7 @@ var DartHighlightRules = function() { var constantLanguage = "true|false|null"; var variableLanguage = "this|super"; var keywordControl = "try|catch|finally|throw|break|case|continue|default|do|else|for|if|in|return|switch|while|new"; - var keywordDeclaration = "abstract|class|extends|external|factory|implements|get|native|operator|set|typedef"; + var keywordDeclaration = "abstract|class|extends|external|factory|implements|get|native|operator|set|typedef|with"; var storageModifier = "static|final|const"; var storageType = "void|bool|num|int|double|dynamic|var|String"; From b79cb61861fcd21ecdc7f13dba1497b042caed62 Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Tue, 7 Jan 2014 17:54:33 +0100 Subject: [PATCH 17/23] Update LogiQL highlighting: add alias_all storage type --- lib/ace/mode/logiql_highlight_rules.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ace/mode/logiql_highlight_rules.js b/lib/ace/mode/logiql_highlight_rules.js index f4e505d8..5f2fecba 100644 --- a/lib/ace/mode/logiql_highlight_rules.js +++ b/lib/ace/mode/logiql_highlight_rules.js @@ -98,7 +98,7 @@ var LogiQLHighlightRules = function() { //All the lang system predicates }, { token: [ 'storage.type', 'text' ], - regex: '(export|sealed|clauses|block|alias)(\\s*\\()(?=`)', + regex: '(export|sealed|clauses|block|alias|alias_all)(\\s*\\()(?=`)', //Module keywords }, { token: 'entity.name', @@ -116,4 +116,4 @@ var LogiQLHighlightRules = function() { oop.inherits(LogiQLHighlightRules, TextHighlightRules); exports.LogiQLHighlightRules = LogiQLHighlightRules; -}); \ No newline at end of file +}); From 30a4d12eb7c0ed43134fc8c4356e226ca832601a Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 7 Jan 2014 22:39:07 +0400 Subject: [PATCH 18/23] fix ascii filter in builder --- Makefile.dryice.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Makefile.dryice.js b/Makefile.dryice.js index 48e90961..549f3665 100755 --- a/Makefile.dryice.js +++ b/Makefile.dryice.js @@ -297,8 +297,19 @@ function getWriteFilters(options, projectType) { if (options.compress) filters.push(copy.filter.uglifyjs); - copy.filter.uglifyjs.options.ascii = true; - + // copy.filter.uglifyjs.options.ascii = true; doesn't work with some uglify.js versions + filters.push(function(text) { + var t1 = text.replace(/[\x80-\uffff]/g, function(c) { + c = c.charCodeAt(0).toString(16); + if (c.length == 2) + return "\\x" + c; + if (c.length == 3) + c = "0" + c; + return "\\u" + c; + }); + return text; + }); + if (options.exportModule && projectType == "main") { if (options.noconflict) filters.push(exportAce(options.ns, options.exportModule, options.ns)); From 142761d86fe994f5b44075a3ac4a4ef02af0300a Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 7 Jan 2014 23:03:32 +0400 Subject: [PATCH 19/23] fix regression in { pairing --- lib/ace/mode/behaviour/cstyle.js | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js index 2c831667..5bdd997c 100644 --- a/lib/ace/mode/behaviour/cstyle.js +++ b/lib/ace/mode/behaviour/cstyle.js @@ -132,7 +132,7 @@ var CstyleBehaviour = function () { selection: false }; } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { - if (/[\]\}\)]/.test(line[cursor.column])) { + if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) { CstyleBehaviour.recordAutoInsert(editor, session, "}"); return { text: '{}', @@ -165,19 +165,24 @@ var CstyleBehaviour = function () { CstyleBehaviour.clearMaybeInsertedClosing(); } var rightChar = line.substring(cursor.column, cursor.column + 1); - if (rightChar == '}' || closing !== "") { + if (rightChar === '}') { var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}'); if (!openBracePos) return null; - - var indent = this.getNextLineIndent(state, line.substring(0, cursor.column), session.getTabString()); + var next_indent = this.$getIndent(session.getLine(openBracePos.row)); + } else if (closing) { var next_indent = this.$getIndent(line); - - return { - text: '\n' + indent + '\n' + next_indent + closing, - selection: [1, indent.length, 1, indent.length] - }; + } else { + return; } + var indent = next_indent + session.getTabString(); + + return { + text: '\n' + indent + '\n' + next_indent + closing, + selection: [1, indent.length, 1, indent.length] + }; + } else { + CstyleBehaviour.clearMaybeInsertedClosing(); } }); From ce329df39bf9b8a8c44b58f5055808292fd0176d Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 8 Jan 2014 03:14:35 +0400 Subject: [PATCH 20/23] update the site --- ChangeLog.txt | 6 +++--- build | 2 +- doc/site/js/main.js | 19 +++++++------------ index.html | 16 +++++++--------- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 81168b8f..4b48f911 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,4 +1,5 @@ - +2013.12.02 Version 1.1.2 + * New Features - Accessibility Theme for Ace (Peter Xiao) - use snipetManager for expanding emmet snippets @@ -21,9 +22,8 @@ - Protobuf (Zef Hemel) - Soy - Handlebars - - -2013.06.04 Version 1.1.01 +2013.06.04 Version 1.1.1 - Improved emacs keybindings (Robert Krahn) - Added markClean, isClean methods to UndoManager (Joonsoo Jeon) diff --git a/build b/build index 45d3068a..b2f8bf1e 160000 --- a/build +++ b/build @@ -1 +1 @@ -Subproject commit 45d3068aa7190f08396bcfe134e505fe144c1ccb +Subproject commit b2f8bf1e745250596afea5b39c70b94421af906d diff --git a/doc/site/js/main.js b/doc/site/js/main.js index 4762bab6..db3c1bcd 100644 --- a/doc/site/js/main.js +++ b/doc/site/js/main.js @@ -6,23 +6,21 @@ $(function() { editor.container.style.opacity = ""; embedded_editor = ace.edit("embedded_ace_code"); embedded_editor.container.style.opacity = ""; - editor.session.setMode("ace/mode/javascript"); embedded_editor.session.setMode("ace/mode/html"); + embedded_editor.setAutoScrollEditorIntoView(true); + embedded_editor.setOption("maxLines", 40); editor.setOptions({ - maxLines: 30 - }) + maxLines: 30, + mode: "ace/mode/javascript", + autoScrollEditorIntoView: true + }); ace.config.loadModule("ace/ext/emmet", function() { ace.require("ace/lib/net").loadScript("http://nightwing.github.io/emmet-core/emmet.js", function() { embedded_editor.setOption("enableEmmet", true); editor.setOption("enableEmmet", true); }); - - embedded_editor.setOptions({ - enableSnippets: true, - enableBasicAutocompletion: true - }); }); ace.config.loadModule("ace/ext/language_tools", function() { @@ -34,10 +32,7 @@ $(function() { enableSnippets: true, enableBasicAutocompletion: true }); - }); - - embedded_editor.setAutoScrollEditorIntoView(true); - editor.setAutoScrollEditorIntoView(true); + }); $("ul.menu-list li").click(function(e) { if (e.target.tagName === "LI") { diff --git a/index.html b/index.html index 9c1b03c9..cd18d94f 100644 --- a/index.html +++ b/index.html @@ -173,16 +173,14 @@ console.log(addResult); common operations, such as setting a different language mode or getting the contents from the editor.

    -

    Loading Ace from a Local URL

    -

    The above code is all you need to embed Ace in your site (including setting language modes - and themes). Plus it's super fast because it's on Amazon's distributed content network. -

    -

    But, if you want to clone host Ace locally you can +

    Loading Ace from a Local URL

    +

    If you want to clone and host Ace locally you can use one of the pre-packaged versions. Just copy one of src* subdirectories somewhere into your project, or use RequireJS to load the - contents of lib/ace as ace: + contents of lib/ace folder as ace: +

    +

    The packaged version can also be loaded from CDN's such as jsDelivr or cdnjs.

    -
    var ace = require("lib/ace");

    Working with Ace

    @@ -1117,7 +1115,7 @@ if (match) { BakeMyCss
  • - + Code Combat
  • @@ -1178,7 +1176,7 @@ if (match) {
  • +

    - Your Site Here + Your Site Here
  • From d226ea067bead150022532d1c265b63b60e3256f Mon Sep 17 00:00:00 2001 From: nightwing Date: Fri, 10 Jan 2014 00:11:00 +0400 Subject: [PATCH 21/23] update site --- doc/site/images/KERA-med-web.png | Bin 2852 -> 0 bytes doc/site/js/main.js | 19 +++++---- index.html | 68 +++++++++++++++++++------------ 3 files changed, 53 insertions(+), 34 deletions(-) delete mode 100644 doc/site/images/KERA-med-web.png diff --git a/doc/site/images/KERA-med-web.png b/doc/site/images/KERA-med-web.png deleted file mode 100644 index de004afc8c21a9bd984ebe83ae2063ac2f35215e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2852 zcmaJ@X;_kJ7Y56HDYeC{6mcsz784Y41s77xwMdx~0fh`9K!ws4l3Xe?$I{FiEj3GX zmoghNz%k2l$tA~fG^??`N?a;UEkA6k`F>2_`(E$+obz1weV_B3bACMOfdM|+8ipDG z06-h(iw#z+EX8N4rlR=!&t>WQ$zL#gp&8ilAS1EH&+mvhf)YIs9X|=$JiUkLGfI`UvyClduba227Q5W zV_m?1Cq=*qf-p=r735$CwIxFlP!IxU2eaRTL?UfKa3~B4fx;m$xGfBcvWKIfP|(*0 ztcb>@M5BVS-d|%WJQpyH%VnV;ki^79yF`0CCOZZKb8>Q8(tyKl6$o1nKaNY{*~W29 zzbRm;95S2E;?kLMpe0386f>Ud0#;=D_YoMZ@3L{6uVqpc48kL^ATT@V(viLa@%aA_ zWiY;@Iox3CKl%QvFejAHqC$eH9A-S5tY}=c=~5^b3d5$7xJ-5^leza>6$5EZE|WuJ zvOt&+2N0e_rpGP$U+{Q53Kz%WlH$lz9M%P_P_U!ZDJZNX9Enl9P=qH82J?bDDhyA1 z1Qw3*gu=WWwtVAandEo|HIDm@OZkVpMEQ5_(kL)kipW?ho1Q?Wc(a)d(3c~l=s(WI z;fH!(xs)I0g7_g9qDTg^)Y$)N^tUa=^ema*$5!EdAAD+@V%ph?u?~1Uga80k^Ke*? zP~PB^2+gc*VFqqZ2vVZC*V#*{U}~52GCJDqlqY^utaayUqf1wDkZgD;MtI-UUzqKE zHC>zUpj(ofZxl)?wJ_Xk+w{C|=J!vZt}GUaIiJU#99WEf#QY1nIK+{=%=|f>Ja*s$ z$3EX?E)4icZ@nH;7g;`0=JCd(9W3^H66173qedB)%0oZ@1W!{<8`eE;GdAgxuUo!z zJYFmLjNXi1qW)sgs}?6&UAno9Iib~YPr?LF(xZ$fRYzH)*Rmw%z2A7Xn~5y{Jek^a z8eic1CZNJF=&)+~>-3q(k@#Neue1CByh$@=rJ<(Wa@11RFzXzrW%|Lizty=~a>{az z^Bwf>%{uRzykp07^7Ri*@(hgfN@SVg^W4!3l8^Rj7_w28XZvT<@OgODBehQ!Dv9vP zy1a|;b=CY@QRvvKewJuI6^*xzvh`@AQsroOpQi?$F*tPP6YxFjWvacA50A@& zQc64{-md}{WIj$2G13Z#;j(p3B;`D)cFf9Q(@ar86R?Bdfa2FkgPU2v&VG^SeC%xU zFSAX79#(4B&C4cm(?#kQNkZB5YXg;6G^aI%^a^4~j&({>y}@bLsGKQ$eQaQ%!j^W^ zAiTSU-I1GiEhEaX_!iD^Om9PVHe=NmTXGcW`o_~nE6A%eKs{`EfzW~fZnz- zeL;7veoL2m$v&G@PG9XnXAs<54PS_!Z>A?>qQ&hIsE2xxXRSf zC9fCp2dEiUCi6c9b@a(;O%T9UB2xd5>E2KN#eap_vpKE#m8Y+(7p$17%@gZA{H--b zTqFon-FP1Msl-;}a%7aWLvn&`QIAPm)#wZRJ&X2OP^^25To*!o5Lep_Te(| zq1t1%rray3LvP5T9H8_h&7Goj&{*G}jDI0MXsHg}`0{wDCELgmXT8jvyjOW;VP#>H z*7g`mn%F5E;@iV{w5?LZYo|N4ZYo=2dwKj5-#1qUVJ9+_5SMS~KMaqR0}kze+5HHM z$&k2mt9;!0&Jd4M>s&3b0amxufD5TQe+JiRyz=q7yC36h{fhlU)P3Ca-D}|ox3nDx z=0fZ?EtCm{9`A=rKUX{M*?bc7xk+oa(A%W_UX8v@v*&UoDjZz0wL$x+bRk!}^{-U5 zV_Ws@@tC72>rRqa+}}gPk)IAoeSL_=x1IE;!@WmM$-B;sO!ar_PIq*1P-num)7 zawu2ph*$RZu0$zVc=x>3K+AQxhoO7H>Qn%~AB|1&x%Z3^!jpEeTE&iyZ&yt@p`=Oi zA>FPWJ9Vxbn{9|aF6PhAuX&#CG;#jAP2=;!YK<^?Z-n&;&EdMAO3nEnaMv1DZgsIL z?qtnS%HF+cuN0y;TMLoXeV=B8`L!ico zOpau(Pw(}vD&31*ZiA@a#<(IF8WWF9J`>Dz!QW-z!|Afn z*-M7YdsY~_s#1-6GJuc5Rj*AvK($5wJX4{8*onK_O;HFs%zrscn zde)h|J>WBsRx($m)^UH(-t?8`PolRDSyfoCC>XcO%B^fUa1A-(BUqEJWZBL4t+ju; u=Yz+-?ZqCfHd;oWU`Hy?d9?qKvH>74Jnth?_Ofm1-iq@Iz*c%j3jPZMLB~n} diff --git a/doc/site/js/main.js b/doc/site/js/main.js index db3c1bcd..78595c6a 100644 --- a/doc/site/js/main.js +++ b/doc/site/js/main.js @@ -34,14 +34,19 @@ $(function() { }); }); - $("ul.menu-list li").click(function(e) { - if (e.target.tagName === "LI") { - console.log($(this).find("a")); - window.location = $(this).find("a").attr("href"); + $("ul.menu-list").mousedown(function(e) { + if (e.button === 1) { + e.preventDefault(); } - else if (e.target.tagName === "P" || e.target.tagName === "IMG") { - var anchor = $(e.target).siblings(); - window.location = anchor.attr("href"); + }); + + $("ul.menu-list li").click(function(e) { + if (e.target.tagName !== "A") { + var href = $(this).find("a").attr("href"); + if (e.button == 1) + window.open(href, "_blank"); + else + window.location = href; } }); diff --git a/index.html b/index.html index cd18d94f..7f381bf0 100644 --- a/index.html +++ b/index.html @@ -793,9 +793,8 @@ if (match) { Plunker
  • - - Kera.io + + Zed
  • Inkling Habitat
  • -
  • - - Weecod +
  • + + Code Combat
  • -
  • +
  • - - ProcessWire + + Repl.it
  • Stypi
  • - - Repl.it + + Weecod +
  • +
  • + + ProcessWire
  • - PHP Assist + PHP Assist
  • @@ -937,7 +940,7 @@ if (match) {
  • S
    Slim Text @@ -1114,10 +1117,6 @@ if (match) { BakeMyCss
  • -
  • - - Code Combat -
  • Spark Core
  • +
  • + + ownCloud +
  • +
  • + + JQM Designer +
  • +
  • + + pracZone +
  • Sky Edit
  • @@ -1135,6 +1146,8 @@ if (match) { Play My Code
  • + Qooxdoo playground
  • @@ -1150,17 +1163,18 @@ if (match) { ShareJS
  • +
  • + + Neutron IDE +
  • Akshell
  • beanstalk
  • -
  • - - Neutron IDE -
  • +
  • tmpltr @@ -1176,7 +1190,7 @@ if (match) {
  • +

    - Your Site Here + Your Site Here
  • From fb233da532cf6c95c18c1878521c62246f60463e Mon Sep 17 00:00:00 2001 From: Adam Jimenez Date: Mon, 13 Jan 2014 09:46:53 +0000 Subject: [PATCH 22/23] shift+mousewheel to horiz scroll Converts shift+mousewheel to horizontal scroll. This is in accordance with Chrome which supports this shortcut on webpages and textareas. --- lib/ace/mouse/default_handlers.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/ace/mouse/default_handlers.js b/lib/ace/mouse/default_handlers.js index 4e28d9d3..7e895f30 100644 --- a/lib/ace/mouse/default_handlers.js +++ b/lib/ace/mouse/default_handlers.js @@ -235,8 +235,15 @@ function DefaultHandlers(mouseHandler) { }; this.onMouseWheel = function(ev) { - if (ev.getShiftKey() || ev.getAccelKey()) + if (ev.getAccelKey()) return; + + //shift wheel to horiz scroll + if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) { + ev.wheelX = ev.wheelY; + ev.wheelY = 0; + } + var t = ev.domEvent.timeStamp; var dt = t - (this.$lastScrollTime||0); From 0ab65745214825f907a35ce6843ff94da342cfa3 Mon Sep 17 00:00:00 2001 From: Roger Gallion Date: Mon, 13 Jan 2014 06:25:26 -0600 Subject: [PATCH 23/23] Add Vim keybinding unit test [Issue 1762] --- lib/ace/keyboard/vim_test.js | 532 +++++++++++++++++++++++++++++++++++ lib/ace/test/all_browser.js | 1 + 2 files changed, 533 insertions(+) create mode 100644 lib/ace/keyboard/vim_test.js diff --git a/lib/ace/keyboard/vim_test.js b/lib/ace/keyboard/vim_test.js new file mode 100644 index 00000000..15aeb568 --- /dev/null +++ b/lib/ace/keyboard/vim_test.js @@ -0,0 +1,532 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2014, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +function repeat(str, times) { + return new Array(times + 1).join(str); +} + +var EditSession = require("./../edit_session").EditSession, + Editor = require("./../editor").Editor, + UndoManager = require("./../undomanager").UndoManager, + MockRenderer = require("./../test/mockrenderer").MockRenderer, + assert = require("./../test/assertions"), + keys = require("./../lib/keys"), + vim = require("./vim"), + editor, + keyCodeByFuncKey = {}, + tests = {}; + +//Helper functions + +function initKeyCodeByFuncKey() { + for (var keyCode in keys.FUNCTION_KEYS) { + var funcKey = keys.FUNCTION_KEYS[keyCode]; + keyCodeByFuncKey[funcKey] = keyCode; + } +} + +function initEditor(docString) { + var session = new EditSession(docString.split("\n")); + var undoManager = new UndoManager(); + session.setUndoManager(undoManager); + editor = new Editor(new MockRenderer(), session); + editor.setKeyboardHandler(vim.handler); +} + +function sendKeys() { + //Vim handler needs to be sent a key at a time for undo to work + //Handle any mix of command keys and text input arguments + for (var argInt=0; argInt" + title + ""; + } + tests[testName] = testFunction; +} + +//Define the tests + +initKeyCodeByFuncKey(); + +addTest("Insert text", "02", "2", function() { + var text = "A very intelligent turtle\nFound programming UNIX a hurdle"; + initEditor(""); + sendKeys("i", text, "Esc"); + assertContent(text); + sendKeys("Esc", "Esc"); + assertContent(text); +}); + +addTest("Moving around", "02", "3", function() { + initEditor(" k \nh l\n j "); + sendKeys("hjj"); + assertPosition(2, 0); + sendKeys("jll"); + assertPosition(2, 2); + sendKeys("lkk"); + assertPosition(0, 2); + sendKeys("khh"); + assertPosition(0, 0); +}); + +addTest("Deleting characters", "02", "4", function() { + var text = "A very intelligent turtle\nFound programming UNIX a hurdle"; + initEditor(text); + sendKeys("xxxxxxx"); + assertContent(text.substring(7)); + sendKeys("iA young ", "Esc"); + assertContent("A young intelligent turtle\nFound programming UNIX a hurdle"); + sendKeys("dd"); + assertContent("Found programming UNIX a hurdle"); + sendKeys("ddiA young intelligent\nturtle", "Esc", "kJ"); + assertContent("A young intelligent turtle"); +}); + +addTest("Undo and Redo [PARTIAL]", "02", "5", function() { + var text = "A young intelligent turtle"; + initEditor(text); + sendKeys("ddu"); + assertContent(text); + sendKeys("0xxxxxxx"); + assertContent(text.substring(7)); + for (var i=6; i>=0; i--) { + sendKeys("u"); + assertContent(text.substring(i)); + } + sendKeys("ctrl-r", "ctrl-r"); + assertContent(text.substring(2)); + text = "A very intelligent turtle"; + sendKeys("ddi", text, "Esc"); + sendKeys("0wxxxxxwwxxxxxx"); + assertContent("A intelligent "); +/* "U" fails + sendKeys("U"); + assertContent(text); + sendKeys("u"); + assertContent("A intelligent "); +*/ +}); + +addTest("Other editing commands [PARTIAL]", "02", "6", function() { + var text = "and that's not saying much for the turtle."; + initEditor(text); + sendKeys("$xa!!!", "Esc"); + assertContent(text.slice(0, -1) + "!!!"); + var text1 = "A very intelligent turtle"; + var text2 = "Found programming UNIX a hurdle"; + sendKeys("ddi", text1 + "\n" + text2, "Esc"); + var text3 = "That liked using Vim"; + sendKeys("ko", text3, "Esc"); + assertContent([text1, text3, text2].join("\n")); + sendKeys("O", "Esc"); + assertContent([text1, "", text3, text2].join("\n")); +/* "3a!" fails + sendKeys("3a!", "Esc"); +*/ + sendKeys("a!!!", "Esc"); + assertContent([text1, "!!!", text3, text2].join("\n")); + sendKeys("hhh3x"); + assertContent([text1, "", text3, text2].join("\n")); +}); + +addTest("Getting out [PARTIAL]", "02", "7", function() { + initEditor(""); + sendKeys("ZZ"); + /* + sendKeys("aSome text", "Esc"); + sendKeys(":q", "Return"); + sendKeys(":q!", "Return"); + + sendKeys(":e!", "Return"); + */ +}); + +addTest("Finding help [PARTIAL]", "02", "8", function() { + initEditor(""); + sendKeys(":help", "Return"); + sendKeys("F1"); +}); + +addTest("Word movement [PARTIAL]", "03", "1", function() { + var text = "This is a line with example text"; + initEditor(text); + sendKeys("www3w"); + assertPosition(0, 28); + sendKeys("b2b"); + assertPosition(0, 10); + sendKeys("3le"); + assertPosition(0, 18); +/* "ge" fails + sendKeys("2ge"); + assertPosition(0, 8); + TODO: What iskeyword behavior is assumed for Ace? + Need to test "b,w,ge,e,gE, B, W, E" behaviors + sendKeys("ddaThis is-a line, with special/separated/words (and some more).", "Esc"); + sendKeys("$4b"); + assertPosition(0, 21); +*/ +}); + +addTest("Moving to the start or end of a line [PARTIAL]", "03", "2", function() { + var text = " This is a line with example text"; + var textLength = text.length; + initEditor(text); + sendKeys("$"); + assertPosition(0, 36); + sendKeys("0"); + assertPosition(0, 0); +/* "End" and "Home" fails + sendKeys("End"); + assertPosition(0, 36); + sendKeys("Home"); + assertPosition(0, 0); +*/ + sendKeys("^"); + assertPosition(0, 5); + sendKeys("$^"); + assertPosition(0, 5); + sendKeys("ddaA young intelligent turtle\nFound programming UNIX a hurdle", "Esc", "k0"); + assertPosition(0, 0); +/* $ fails + sendKeys("2$"); + assertPosition(1, 30); +*/ +}); + +addTest("Moving to a character [PARTIAL]", "03", "3", function() { + var text = "To err is human. To really foul up you need a computer."; + initEditor(repeat(text, 2)); + sendKeys("fh"); + assertPosition(0, 10); + sendKeys("3fl"); + assertPosition(0, 31); + sendKeys("Fh"); + assertPosition(0, 10); + sendKeys("Fh"); + assertPosition(0, 10); + sendKeys("2tn"); + assertPosition(0, 39); + sendKeys("Th"); + assertPosition(0, 11); + sendKeys("tn"); + assertPosition(0, 13); + sendKeys(";"); + assertPosition(0, 39); +/* Problem with mockrenderer? + sendKeys(";"); + assertPosition(0, 39); +*/ + sendKeys(","); + assertPosition(0, 15); + sendKeys("0f", "Esc", "w"); + assertPosition(0, 3); +}); + +addTest("Matching a parenthesis", "03", "4", function() { + var text = "if (a == (b * c) / d)\nif [a == [b * c] / d]\nif {a == {b * c} / d}"; + initEditor(text); + sendKeys("%"); + assertPosition(0, 20); + sendKeys("%"); + assertPosition(0, 3); + sendKeys("0j%"); + assertPosition(1, 20); + sendKeys("%"); + assertPosition(1, 3); + sendKeys("0j%"); + assertPosition(2, 20); + sendKeys("%"); + assertPosition(2, 3); +}); + +addTest("Moving to a specific line [PARTIAL]", "03", "5", function() { + var text = "first line of a file\n" + repeat("text text text text\n", 8) + "last line of a file"; + initEditor(text); + sendKeys("7G"); + assertPosition(6, 0); + sendKeys("gg"); + assertPosition(0, 0); + sendKeys("G"); + assertPosition(9, 0); +/* % motion fails + sendKeys("50%"); + assertPosition(4, 0); + sendKeys("90%"); + assertPosition(8, 0); +"H, M, L" motion supported, but mockrenderer.js has no 'getScrollBottomRow', etc. + sendKeys("L"); + assertPosition(9, 0); + sendKeys("M"); + assertPosition(4, 0); + sendKeys("H"); + assertPosition(0, 0); +*/ +}); + +addTest("Telling where you are [PARTIAL]", "03", "6", function() { + // Ctrl-G, :set commands not implemented? +}); + +addTest("Scrolling around [PARTIAL]", "03", "7", function() { + /* Ctrl-D, Ctrl-U, Ctrl-E, Ctrl-Y, zz, zt, zb cannot be tested with mockrenderer + var text = repeat("some text\n", 4) + "\n123456\n7890\n" + repeat("\nexample", 4); + initEditor(text); + sendKeys("Ctrl-D"); + */ +}); + +addTest("Simple searches [PARTIAL]", "03", "8", function() { + var text = repeat("To find the word #include\n", 10); + initEditor(text); +/* Search fails, (is a command line really necessary for this to work? + sendKeys("/include", "Return"); + assertPosition(0, 18); + sendKeys("/#include", "Return"); + assertPosition(1, 17); + sendKeys("nnn"); + assertPosition(4, 17); + sendKeys("3n"); + assertPosition(7, 17); + sendKeys("?word", "Return"); + assertPosition(7, 12); + sendKeys("N"); + assertPosition(8, 12); + sendKeys("/#include", "Return"); + assertPosition(8, 17); + sendKeys("N"); + assertPosition(7, 17); + //Skipping ':set ignorecase' and ':set noignorecase' + //Skipping search history + //TODO additional search tests +*" and "#" searches fail, no getPixelPosition in mockrenderer + sendKeys("gg*"); + assertPosition(1, 5); +*/ +}); + +addTest("Simple search patterns [PARTIAL]", "03", "9", function() { +}); + +addTest("Using marks [PARTIAL]", "03", "10", function() { +/* '', ``, Ctrl-O, Ctrl-I fail + var text1 = "example text\n" + var text2 = "line 33 text\n" + var text3 = "There you are\n" + var text = repeat(text1, 32) + text2 + repeat(text1, 2) + text3 + text1; + initEditor(text); + sendKeys("G"); + sendKeys("``"); + assertPosition(0, 0); + sendKeys("``"); + assertPosition(37, 0); + sendKeys("10k``"); + assertPosition(0, 0); + sendKeys("33G"); + assertPosition(33, 0); + sendKeys("/^The"); + assertPosition((36, 0); + sendKeys("Ctrl-O"); + assertPosition(33, 0); + sendKeys("Ctrl-O"); + assertPosition(0, 0); + sendKeys("Ctrl-I"); + assertPosition(33, 0); + sendKeys("Ctrl-I"); + assertPosition(36, 0); + sendKeys(":0$msG$me's"); + assertPosition(0, 0); + sendKeys("`s"); + assertPosition(0, 11); + sendKeys("'e"); + assertPosition(36, 0); + sendKeys("`e"): + assertPosition(36, 11); +*/ +}); + +addTest("Operators and motions [PARTIAL]", "04", "1", function() { + initEditor("To err is human. To really foul up you need a computer."); + sendKeys("5wd4w"); + assertContent("To err is human. you need a computer."); +/* "de" fails + sendKeys("d2e"); + assertContent("To err is human. a computer."); + + sendKeys("2hd$"); + assertContent("To err is human"); +*/ +}); + +addTest("Changing text [PARTIAL]", "04", "2", function() { + initEditor("To err is human"); +/* +// "cw" fails +// sendKeys("wc2wbe", "Esc"); +// assertContent("To be human"); + sendKeys("uccabc def", "Esc"); + assertContent("abc def"); + sendKeys("0c$123", "Esc"); + assertContent("123"); + sendKeys("hx"); + assertContent("13"); + sendKeys("X"); + assertContent("3"); + sendKeys("a 2 1", "Esc", "0wD"); + assertContent("3 "); + sendKeys("a2 1", "Esc", "0wC4 5", "Esc"); + assertContent("3 4 5"); + sendKeys("0ws6", "Esc"); + assertContent("3 6 5"); + sendKeys("S1 3 2", "Esc"); + assertContent("1 3 2"); + sendKeys("$a4 6 5", "Esc", "03d2w"); + assertContent(""); + sendKeys("athere is somerhing grong here", "Esc", "0rTww4lrtwrw"); + assertContent("There is something wrong here"); + sendKeys("03w5rx"); + assertContent("There is something xxxxx here"); +// "r" fails - also replaces trailing space + sendKeys("r", "Return"); + assertContent("There is something xxxx\n here"); + //TODO - 4r +*/ +}); + +addTest("Repeating a change [PARTIAL]", "04", "3", function() { +/* + initEditor("To generate a table of contents"); + sendKeys("ff<.f<."); //strangeness after this + assertContent("To generate a table of contents");; + sendKeys("dd"); + assertContent(""); +sendKeys("Esc", "Esc"); + sendKeys("afind"); + var text = "find the first \"four\"\n" + + "change the word to \"five\"\n" + + "find the next \"four\"\n" + + "repeat the change to \"five\"\n" + + "find the next \"four\"\n" + + "repeat the change\n" + + "etc."; + sendKeys(text); +assertContent(text); + sendKeys("Esc"); + sendKeys("0"); +// search doesn't work with mockrenderer + sendKeys("/four", "", "cwfive", "Esc", "n.n."); + text.replace(/four/g, "five"); + assertContent(text); +*/ +}); + +addTest("Visual mode [PARTIAL]", "04", "4", function() { +}); + +addTest("Moving text [PARTIAL]", "04", "5", function() { +}); + +addTest("Copying text [PARTIAL]", "04", "6", function() { +}); + +addTest("Using the clipboard [PARTIAL]", "04", "7", function() { +}); + +addTest("Text objects [PARTIAL]", "04", "8", function() { +}); + +addTest("Replace mode [PARTIAL]", "04", "9", function() { +}); + +tests.name = "vim_test.js"; + +module.exports = tests; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec(); +} diff --git a/lib/ace/test/all_browser.js b/lib/ace/test/all_browser.js index 72e66de5..db56517c 100644 --- a/lib/ace/test/all_browser.js +++ b/lib/ace/test/all_browser.js @@ -24,6 +24,7 @@ var testNames = [ "ace/incremental_search_test", "ace/keyboard/emacs_test", "ace/keyboard/keybinding_test", + "ace/keyboard/vim_test", "ace/layer/text_test", "ace/lib/event_emitter_test", "ace/mode/coffee/parser_test",