diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index b3a0c3a0..1ced6916 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -60,7 +60,7 @@ exports.commands = [{ module.showErrorMarker(editor, 1); }); }, - scrollIntoView: "center", + scrollIntoView: "animate", readOnly: true }, { name: "goToPreviousError", @@ -70,7 +70,7 @@ exports.commands = [{ module.showErrorMarker(editor, -1); }); }, - scrollIntoView: "center", + scrollIntoView: "animate", readOnly: true }, { name: "selectall", @@ -366,12 +366,14 @@ exports.commands = [{ bindKey: "Shift-Home", exec: function(editor) { editor.getSelection().selectLineStart(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectlineend", bindKey: "Shift-End", exec: function(editor) { editor.getSelection().selectLineEnd(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "togglerecording", @@ -409,21 +411,25 @@ exports.commands = [{ editor.clearSelection(); } }, + scrollIntoView: "cursor", multiSelectAction: "forEach" }, { name: "removeline", bindKey: bindKey("Ctrl-D", "Command-D"), exec: function(editor) { editor.removeLines(); }, + scrollIntoView: "cursor", multiSelectAction: "forEachLine" }, { name: "duplicateSelection", bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"), exec: function(editor) { editor.duplicateSelection(); }, + scrollIntoView: "cursor", multiSelectAction: "forEach" }, { name: "sortlines", bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"), exec: function(editor) { editor.sortLines(); }, + scrollIntoView: "selection", multiSelectAction: "forEachLine" }, { name: "togglecomment", @@ -435,7 +441,8 @@ exports.commands = [{ name: "toggleBlockComment", bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"), exec: function(editor) { editor.toggleBlockComment(); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "selectionPart" }, { name: "modifyNumberUp", bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"), @@ -463,24 +470,29 @@ exports.commands = [{ }, { name: "copylinesup", bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"), - exec: function(editor) { editor.copyLinesUp(); } + exec: function(editor) { editor.copyLinesUp(); }, + scrollIntoView: "cursor" }, { name: "movelinesup", bindKey: bindKey("Alt-Up", "Option-Up"), - exec: function(editor) { editor.moveLinesUp(); } + exec: function(editor) { editor.moveLinesUp(); }, + scrollIntoView: "cursor" }, { name: "copylinesdown", bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"), - exec: function(editor) { editor.copyLinesDown(); } + exec: function(editor) { editor.copyLinesDown(); }, + scrollIntoView: "cursor" }, { name: "movelinesdown", bindKey: bindKey("Alt-Down", "Option-Down"), - exec: function(editor) { editor.moveLinesDown(); } + exec: function(editor) { editor.moveLinesDown(); }, + scrollIntoView: "cursor" }, { name: "del", bindKey: bindKey("Delete", "Delete|Ctrl-D|Shift-Delete"), exec: function(editor) { editor.remove("right"); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "backspace", bindKey: bindKey( @@ -488,7 +500,8 @@ exports.commands = [{ "Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H" ), exec: function(editor) { editor.remove("left"); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "cut_or_delete", bindKey: bindKey("Shift-Delete", null), @@ -499,27 +512,32 @@ exports.commands = [{ return false; } }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "removetolinestart", bindKey: bindKey("Alt-Backspace", "Command-Backspace"), exec: function(editor) { editor.removeToLineStart(); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "removetolineend", bindKey: bindKey("Alt-Delete", "Ctrl-K"), exec: function(editor) { editor.removeToLineEnd(); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "removewordleft", bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"), exec: function(editor) { editor.removeWordLeft(); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "removewordright", bindKey: bindKey("Ctrl-Delete", "Alt-Delete"), exec: function(editor) { editor.removeWordRight(); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "outdent", bindKey: bindKey("Shift-Tab", "Shift-Tab"), @@ -554,27 +572,32 @@ exports.commands = [{ exec: function(editor, args) { editor.insert(lang.stringRepeat(args.text || "", args.times || 1)); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "splitline", bindKey: bindKey(null, "Ctrl-O"), exec: function(editor) { editor.splitLine(); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "transposeletters", bindKey: bindKey("Ctrl-T", "Ctrl-T"), exec: function(editor) { editor.transposeLetters(); }, - multiSelectAction: function(editor) {editor.transposeSelections(1); } + multiSelectAction: function(editor) {editor.transposeSelections(1); }, + scrollIntoView: "cursor" }, { name: "touppercase", bindKey: bindKey("Ctrl-U", "Ctrl-U"), exec: function(editor) { editor.toUpperCase(); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "tolowercase", bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"), exec: function(editor) { editor.toLowerCase(); }, - multiSelectAction: "forEach" + multiSelectAction: "forEach", + scrollIntoView: "cursor" }]; }); diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css index db8b897e..d4f6bb67 100644 --- a/lib/ace/css/editor.css +++ b/lib/ace/css/editor.css @@ -4,7 +4,6 @@ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace; font-size: 12px; line-height: normal; - color: black; } .ace_editor .ace_line { @@ -64,6 +63,10 @@ left: 0; cursor: default; z-index: 4; + -ms-user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + user-select: none; } .ace_gutter-active-line { @@ -228,10 +231,6 @@ transition: opacity 0.18s; } -.ace_cursor[style*="opacity: 0"]{ - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; -} - .ace_editor.ace_multiselect .ace_cursor { border-left-width: 1px; } diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 2426247d..4ecab579 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -832,8 +832,9 @@ var Editor = function(renderer, session) { // todo this should change when paste becomes a command if (this.$readOnly) return; - this._emit("paste", text); - this.insert(text); + var e = {text: text}; + this._signal("paste", e); + this.insert(e.text, true); }; @@ -2309,7 +2310,7 @@ var Editor = function(renderer, session) { * @param {Boolean} enable default true **/ this.setAutoScrollEditorIntoView = function(enable) { - if (enable === false) + if (!enable) return; var rect; var self = this; @@ -2351,7 +2352,7 @@ var Editor = function(renderer, session) { } }); this.setAutoScrollEditorIntoView = function(enable) { - if (enable === true) + if (enable) return; delete this.setAutoScrollEditorIntoView; this.removeEventListener("changeSelection", onChangeSelection); @@ -2408,6 +2409,9 @@ config.defineOptions(Editor.prototype, "editor", { }, behavioursEnabled: {initialValue: true}, wrapBehavioursEnabled: {initialValue: true}, + autoScrollEditorIntoView: { + set: function(val) {this.setAutoScrollEditorIntoView(val)} + }, hScrollBarAlwaysVisible: "renderer", vScrollBarAlwaysVisible: "renderer", @@ -2419,6 +2423,7 @@ config.defineOptions(Editor.prototype, "editor", { printMargin: "renderer", fadeFoldWidgets: "renderer", showFoldWidgets: "renderer", + showLineNumbers: "renderer", showGutter: "renderer", displayIndentGuides: "renderer", fontSize: "renderer", diff --git a/lib/ace/ext/error_marker.js b/lib/ace/ext/error_marker.js index a55e9a25..28663c6d 100644 --- a/lib/ace/ext/error_marker.js +++ b/lib/ace/ext/error_marker.js @@ -171,6 +171,8 @@ exports.showErrorMarker = function(editor, dir) { editor.session.widgetManager.addLineWidget(w); w.el.onmousedown = editor.focus.bind(editor); + + editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight}); }; diff --git a/lib/ace/ext/themelist.js b/lib/ace/ext/themelist.js index 2bb39b3c..9eb4b71e 100644 --- a/lib/ace/ext/themelist.js +++ b/lib/ace/ext/themelist.js @@ -30,8 +30,6 @@ * * ***** END LICENSE BLOCK ***** */ -/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ -/*global define, require */ /** * Generates a list of themes available when ace was built. @@ -77,7 +75,7 @@ var themeData = [ ["Tomorrow Night 80s" ,"tomorrow_night_eighties" , "dark"], ["Twilight" ,"twilight" , "dark"], ["Vibrant Ink" ,"vibrant_ink" , "dark"] -] +]; exports.themesByName = {}; @@ -88,10 +86,10 @@ exports.themesByName = {}; exports.themes = themeData.map(function(data) { var name = data[1] || data[0].replace(/ /g, "_").toLowerCase(); var theme = { - caption: data[0], - theme: "ace/theme/" + name, - isDark: data[2] == "dark", - name: name + caption: data[0], + theme: "ace/theme/" + name, + isDark: data[2] == "dark", + name: name }; exports.themesByName[name] = theme; return theme; diff --git a/lib/ace/ext/whitespace.js b/lib/ace/ext/whitespace.js index 83486fb0..cbbdbb43 100644 --- a/lib/ace/ext/whitespace.js +++ b/lib/ace/ext/whitespace.js @@ -64,6 +64,9 @@ exports.$detectIndentation = function(lines, fallback) { while (line[line.length - 1] == "\\") line = lines[i++]; } + + if (!stats.length) + return; function getScore(indent) { var score = 0; diff --git a/lib/ace/keyboard/emacs.js b/lib/ace/keyboard/emacs.js index 166c6857..7e855959 100644 --- a/lib/ace/keyboard/emacs.js +++ b/lib/ace/keyboard/emacs.js @@ -100,30 +100,30 @@ exports.handler.attach = function(editor) { editor.emacsMark = function() { return this.session.$emacsMark; - } + }; editor.setEmacsMark = function(p) { // to deactivate pass in a falsy value this.session.$emacsMark = p; - } + }; editor.pushEmacsMark = function(p, activate) { var prevMark = this.session.$emacsMark; if (prevMark) this.session.$emacsMarkRing.push(prevMark); - if (!p || activate) this.setEmacsMark(p) + if (!p || activate) this.setEmacsMark(p); else this.session.$emacsMarkRing.push(p); - } + }; editor.popEmacsMark = function() { var mark = this.emacsMark(); if (mark) { this.setEmacsMark(null); return mark; } return this.session.$emacsMarkRing.pop(); - } + }; editor.getLastEmacsMark = function(p) { return this.session.$emacsMark || this.session.$emacsMarkRing.slice(-1)[0]; - } + }; editor.on("click", $resetMarkMode); editor.on("changeSession", $kbSessionChange); @@ -163,15 +163,15 @@ var $kbSessionChange = function(e) { e.session.$emacsMark = null; if (!e.session.hasOwnProperty('$emacsMarkRing')) e.session.$emacsMarkRing = []; -} +}; var $resetMarkMode = function(e) { e.editor.session.$emacsMark = null; -} +}; -var keys = require("../lib/keys").KEY_MODS, - eMods = {C: "ctrl", S: "shift", M: "alt", CMD: "command"}, - combinations = ["C-S-M-CMD", +var keys = require("../lib/keys").KEY_MODS; +var eMods = {C: "ctrl", S: "shift", M: "alt", CMD: "command"}; +var combinations = ["C-S-M-CMD", "S-M-CMD", "C-M-CMD", "C-S-CMD", "C-S-M", "M-CMD", "S-CMD", "S-M", "C-CMD", "C-M", "C-S", "CMD", "M", "S", "C"]; @@ -188,11 +188,11 @@ exports.handler.onCopy = function(e, editor) { editor.$handlesEmacsOnCopy = true; exports.handler.commands.killRingSave.exec(editor); delete editor.$handlesEmacsOnCopy; -} +}; exports.handler.onPaste = function(e, editor) { editor.pushEmacsMark(editor.getCursorPosition()); -} +}; exports.handler.bindKey = function(key, command) { if (!key) @@ -216,7 +216,7 @@ exports.handler.bindKey = function(key, command) { if (!ckb[keyPart]) ckb[keyPart] = "null"; }); }, this); -} +}; exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { var editor = data.editor; @@ -224,7 +224,7 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { if (hashId == -1) { editor.pushEmacsMark(); if (data.count) { - var str = Array(data.count + 1).join(key); + var str = new Array(data.count + 1).join(key); data.count = null; return {command: "insertstring", args: str}; } @@ -313,7 +313,7 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { } }; } else { - if (!args) args = {} + if (!args) args = {}; if (typeof args === 'object') args.count = count; } } @@ -508,8 +508,8 @@ exports.handler.addCommands({ killLine: function(editor) { editor.pushEmacsMark(null); var pos = editor.getCursorPosition(); - if (pos.column == 0 && - editor.session.doc.getLine(pos.row).length == 0) { + if (pos.column === 0 && + editor.session.doc.getLine(pos.row).length === 0) { // If an already empty line is killed, remove // the line entirely editor.selection.selectLine(); diff --git a/lib/ace/keyboard/keybinding.js b/lib/ace/keyboard/keybinding.js index 2a1a2230..d5edd4f8 100644 --- a/lib/ace/keyboard/keybinding.js +++ b/lib/ace/keyboard/keybinding.js @@ -36,7 +36,7 @@ var event = require("../lib/event"); var KeyBinding = function(editor) { this.$editor = editor; - this.$data = { }; + this.$data = {}; this.$handlers = []; this.setDefaultHandler(editor.commands); }; @@ -63,6 +63,8 @@ var KeyBinding = function(editor) { this.addKeyboardHandler = function(kb, pos) { if (!kb) return; + if (typeof kb == "function" && !kb.handleKeyboard) + kb.handleKeyboard = kb; var i = this.$handlers.indexOf(kb); if (i != -1) this.$handlers.splice(i, 1); diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index 36f89985..eb27026a 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -355,7 +355,7 @@ var TextInput = function(parentNode, host) { // COMPOSITION var onCompositionStart = function(e) { - if (inComposition) return; + if (inComposition || !host.onCompositionStart) return; // console.log("onCompositionStart", inComposition) inComposition = {}; host.onCompositionStart(); @@ -371,7 +371,7 @@ var TextInput = function(parentNode, host) { var onCompositionUpdate = function() { // console.log("onCompositionUpdate", inComposition && JSON.stringify(text.value)) - if (!inComposition) return; + if (!inComposition || !host.onCompositionUpdate) return; var val = text.value.replace(/\x01/g, ""); if (inComposition.lastValue === val) return; @@ -390,6 +390,7 @@ var TextInput = function(parentNode, host) { }; var onCompositionEnd = function(e) { + if (!host.onCompositionEnd) return; // console.log("onCompositionEnd", inComposition &&inComposition.lastValue) var c = inComposition; inComposition = false; diff --git a/lib/ace/keyboard/vim.js b/lib/ace/keyboard/vim.js index 7af83b05..fdd88117 100644 --- a/lib/ace/keyboard/vim.js +++ b/lib/ace/keyboard/vim.js @@ -96,7 +96,7 @@ exports.handler = { if (util.currentMode === "insert") { this.onCompositionStartOrig(text); } - } + }; if (enable) { if (!editor.onCompositionUpdateOrig) { editor.onCompositionUpdateOrig = editor.onCompositionUpdate; @@ -116,7 +116,7 @@ exports.handler = { handleKeyboard: function(data, hashId, key, keyCode, e) { // ignore command keys (shift, ctrl etc.) - if (hashId != 0 && (key == "" || key == "\x00")) + if (hashId !== 0 && (!key || keyCode == -1)) return null; var editor = data.editor; @@ -134,7 +134,7 @@ exports.handler = { return {command: "null", passEvent: true}; } return {command: coreCommands.stop}; - } else if ((key == "esc" && hashId == 0) || key == "ctrl-[") { + } else if ((key == "esc" && hashId === 0) || key == "ctrl-[") { return {command: coreCommands.stop}; } else if (data.state == "start") { if (useragent.isMac && this.handleMacRepeat(data, hashId, key)) { @@ -142,15 +142,15 @@ exports.handler = { key = data.inputChar; } - if (hashId == -1 || hashId == 1 || hashId == 0 && key.length > 1) { + if (hashId == -1 || hashId == 1 || hashId === 0 && key.length > 1) { if (cmds.inputBuffer.idle && startCommands[key]) return startCommands[key]; cmds.inputBuffer.push(editor, key); return {command: "null", passEvent: false}; } // if no modifier || shift: wait for input. - else if (key.length == 1 && (hashId == 0 || hashId == 4)) { + else if (key.length == 1 && (hashId === 0 || hashId == 4)) { return {command: "null", passEvent: true}; - } else if (key == "esc" && hashId == 0) { + } else if (key == "esc" && hashId === 0) { return {command: coreCommands.stop}; } } else { diff --git a/lib/ace/layer/cursor.js b/lib/ace/layer/cursor.js index 26ade52b..aaf3ffec 100644 --- a/lib/ace/layer/cursor.js +++ b/lib/ace/layer/cursor.js @@ -32,11 +32,15 @@ define(function(require, exports, module) { "use strict"; var dom = require("../lib/dom"); +var IE8; var Cursor = function(parentEl) { this.element = dom.createElement("div"); this.element.className = "ace_layer ace_cursor-layer"; parentEl.appendChild(this.element); + + if (IE8 === undefined) + IE8 = "opacity" in this.element; this.isVisible = false; this.isBlinking = true; @@ -46,9 +50,22 @@ var Cursor = function(parentEl) { this.cursors = []; this.cursor = this.addCursor(); dom.addCssClass(this.element, "ace_hidden-cursors"); + this.$updateCursors = this.$updateVisibility.bind(this); }; (function() { + + this.$updateVisibility = function(val) { + var cursors = this.cursors; + for (var i = cursors.length; i--; ) + cursors[i].style.visibility = val ? "" : "hidden"; + }; + this.$updateOpacity = function(val) { + var cursors = this.cursors; + for (var i = cursors.length; i--; ) + cursors[i].style.opacity = val ? "" : "0"; + }; + this.$padding = 0; this.setPadding = function(padding) { @@ -74,12 +91,13 @@ var Cursor = function(parentEl) { }; this.setSmoothBlinking = function(smoothBlinking) { - if (smoothBlinking != this.smoothBlinking) { + if (smoothBlinking != this.smoothBlinking && !IE8) { this.smoothBlinking = smoothBlinking; - if (smoothBlinking) - dom.addCssClass(this.element, "ace_smooth-blinking"); - else - dom.removeCssClass(this.element, "ace_smooth-blinking"); + dom.setCssClass(this.element, "ace_smooth-blinking", smoothBlinking); + this.$updateCursors(true); + this.$updateCursors = (smoothBlinking + ? this.$updateOpacity + : this.$updateVisibility).bind(this); this.restartTimer(); } }; @@ -113,35 +131,34 @@ var Cursor = function(parentEl) { }; this.restartTimer = function() { + var update = this.$updateCursors; clearInterval(this.intervalId); clearTimeout(this.timeoutId); - if (this.smoothBlinking) + if (this.smoothBlinking) { dom.removeCssClass(this.element, "ace_smooth-blinking"); - for (var i = this.cursors.length; i--; ) - this.cursors[i].style.opacity = ""; + } + + update(true); if (!this.isBlinking || !this.blinkInterval || !this.isVisible) return; - if (this.smoothBlinking) + if (this.smoothBlinking) { setTimeout(function(){ dom.addCssClass(this.element, "ace_smooth-blinking"); }.bind(this)); - + } + var blink = function(){ this.timeoutId = setTimeout(function() { - for (var i = this.cursors.length; i--; ) { - this.cursors[i].style.opacity = 0; - } - }.bind(this), 0.6 * this.blinkInterval); + update(false); + }, 0.6 * this.blinkInterval); }.bind(this); this.intervalId = setInterval(function() { - for (var i = this.cursors.length; i--; ) { - this.cursors[i].style.opacity = ""; - } + update(true); blink(); - }.bind(this), this.blinkInterval); + }, this.blinkInterval); blink(); }; diff --git a/lib/ace/layer/gutter.js b/lib/ace/layer/gutter.js index 5a535094..620a2690 100644 --- a/lib/ace/layer/gutter.js +++ b/lib/ace/layer/gutter.js @@ -118,9 +118,9 @@ var Gutter = function(parentEl) { }; this.update = function(config) { - var firstRow = config.firstRow; - var lastRow = config.lastRow; var session = this.session; + var firstRow = config.firstRow; + var lastRow = Math.min(config.lastRow + 1, session.getLength() - 1); // needed to compensate var fold = session.getNextFoldLine(firstRow); var foldStart = fold ? fold.start.row : Infinity; var foldWidgets = this.$showFoldWidgets && session.foldWidgets; @@ -129,7 +129,7 @@ var Gutter = function(parentEl) { var firstLineNumber = session.$firstLineNumber; var lastLineNumber = 0; - var gutterRenderer = session.gutterRenderer; + var gutterRenderer = session.gutterRenderer || this.$renderer; var cell = null; var index = -1; @@ -231,6 +231,19 @@ var Gutter = function(parentEl) { this.$fixedWidth = false; + this.$showLineNumbers = true; + this.$renderer = ""; + this.setShowLineNumbers = function(show) { + this.$renderer = !show && { + getWidth: function() {return ""}, + getText: function() {return ""} + }; + }; + + this.getShowLineNumbers = function() { + return this.$showLineNumbers; + }; + this.$showFoldWidgets = true; this.setShowFoldWidgets = function(show) { if (show) diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index 52940dcf..4290233d 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -364,9 +364,8 @@ var Text = function(parentEl) { container.style.height = config.lineHeight * this.session.getRowLength(row) + "px"; } else { - var lines = container.childNodes - while(lines.length) - fragment.appendChild(lines[0]); + while(container.firstChild) + fragment.appendChild(container.firstChild); } row++; diff --git a/lib/ace/lib/event.js b/lib/ace/lib/event.js index 36250d2f..6721b19c 100644 --- a/lib/ace/lib/event.js +++ b/lib/ace/lib/event.js @@ -258,11 +258,11 @@ function normalizeCommandKeys(callback, e, keyCode) { hashId = 8; break; } - keyCode = 0; + keyCode = -1; } if (hashId & 8 && (keyCode === 91 || keyCode === 93)) { - keyCode = 0; + keyCode = -1; } if (!hashId && keyCode === 13) { diff --git a/lib/ace/lib/keys.js b/lib/ace/lib/keys.js index 42d427b1..916d9f00 100644 --- a/lib/ace/lib/keys.js +++ b/lib/ace/lib/keys.js @@ -46,8 +46,8 @@ var Keys = (function() { }, KEY_MODS: { - "ctrl": 1, "alt": 2, "option" : 2, - "shift": 4, "meta": 8, "command": 8, "cmd": 8 + "ctrl": 1, "alt": 2, "option" : 2, "shift": 4, + "super": 8, "meta": 8, "command": 8, "cmd": 8 }, FUNCTION_KEYS : { @@ -108,8 +108,15 @@ var Keys = (function() { }; // A reverse map of FUNCTION_KEYS - for (var i in ret.FUNCTION_KEYS) { - var name = ret.FUNCTION_KEYS[i].toLowerCase(); + var name, i; + for (i in ret.FUNCTION_KEYS) { + name = ret.FUNCTION_KEYS[i].toLowerCase(); + ret[name] = parseInt(i, 10); + } + + // A reverse map of PRINTABLE_KEYS + for (i in ret.PRINTABLE_KEYS) { + name = ret.PRINTABLE_KEYS[i].toLowerCase(); ret[name] = parseInt(i, 10); } diff --git a/lib/ace/lib/lang.js b/lib/ace/lib/lang.js index 4405b5c2..d6a98149 100644 --- a/lib/ace/lib/lang.js +++ b/lib/ace/lib/lang.js @@ -31,6 +31,10 @@ define(function(require, exports, module) { "use strict"; +exports.last = function(a) { + return a[a.length - 1]; +}; + exports.stringReverse = function(string) { return string.split("").reverse().join(""); }; diff --git a/lib/ace/mode/_test/tokens_ejs.json b/lib/ace/mode/_test/tokens_ejs.json index 9bf88a78..ee0be491 100644 --- a/lib/ace/mode/_test/tokens_ejs.json +++ b/lib/ace/mode/_test/tokens_ejs.json @@ -179,7 +179,7 @@ ["meta.tag.name.table","td"], ["meta.tag.punctuation.end",">"] ],[ - ["start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff"], + "start", ["text"," "], ["meta.tag.punctuation.begin","<"], ["meta.tag.name","span"], @@ -204,12 +204,13 @@ ["text"," "], ["string","'file'"], ["markup.list.meta.tag","%>"], - ["text","\">"], + ["string","\""], + ["meta.tag.punctuation.end",">"], ["meta.tag.punctuation.begin",""] ],[ - ["start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff","start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff"], + "start", ["text"," "], ["meta.tag.punctuation.begin","<"], ["meta.tag.name.anchor","a"], @@ -224,7 +225,8 @@ ["identifier","name"], ["text"," "], ["markup.list.meta.tag","%>"], - ["text","\">"], + ["string","\""], + ["meta.tag.punctuation.end",">"], ["markup.list.meta.tag","<%="], ["text"," "], ["identifier","entry"], @@ -236,13 +238,13 @@ ["meta.tag.name.anchor","a"], ["meta.tag.punctuation.end",">"] ],[ - ["start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff","start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff"], + "start", ["text"," "], ["meta.tag.punctuation.begin",""] ],[ - ["start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff","start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff"], + "start", ["text"," "], ["meta.tag.punctuation.begin","<"], ["meta.tag.name.table","td"], @@ -258,13 +260,13 @@ ["meta.tag.name.table","td"], ["meta.tag.punctuation.end",">"] ],[ - ["start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff","start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff"], + "start", ["text"," "], ["meta.tag.punctuation.begin",""] ],[ - ["start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff","start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff"], + "start", ["text"," "], ["markup.list.meta.tag","<%"], ["text"," "], @@ -272,22 +274,22 @@ ["text"," "], ["markup.list.meta.tag","%>"] ],[ - ["start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff","start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff"], + "start", ["text"," "], ["meta.tag.punctuation.begin",""] ],[ - ["start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff","start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff"], + "start", ["text"," "] ],[ - ["start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff","start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff"], + "start", ["text"," "], ["meta.tag.punctuation.begin",""] ],[ - ["start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff","start","ejs-start","qqstring_inner","qqstring_inner","start_tag_stuff"], + "start", ["meta.tag.punctuation.begin",""] diff --git a/lib/ace/mode/c9search_highlight_rules.js b/lib/ace/mode/c9search_highlight_rules.js index 3e9af29d..43ec4bf8 100644 --- a/lib/ace/mode/c9search_highlight_rules.js +++ b/lib/ace/mode/c9search_highlight_rules.js @@ -66,7 +66,7 @@ var C9SearchHighlightRules = function() { var m; var last = 0; - if (regex) { + if (regex && regex.exec) { regex.lastIndex = 0; while (m = regex.exec(str)) { var skipped = str.substring(last, m.index); @@ -92,42 +92,26 @@ var C9SearchHighlightRules = function() { regex : "Searching for .*$", onMatch: function(val, state, stack) { var parts = val.split("\x01"); - var search = parts[1]; if (parts.length < 3) return "text"; - var options = parts[2] == " in" ? parts[5] : parts[6]; - if (!/regex/.test(options)) - search = lang.escapeRegExp(search); - if (/whole/.test(options)) - search = "\\b" + search + "\\b"; - var regex = search && safeCreateRegexp( - "(" + search + ")", - / sensitive/.test(options) ? "g" : "ig" - ); - if (regex) { - stack[0] = state; - stack[1] = regex; - } + var options, search, replace; var i = 0; - var tokens = [ - { - value: parts[i++] + "'", - type: "text" - }, - { - value: parts[i++], - type: "text" // "c9searchresults.keyword" - }, - { - value: "'" + parts[i++], - type: "text" - } - ]; + var tokens = [{ + value: parts[i++] + "'", + type: "text" + }, { + value: search = parts[i++], + type: "text" // "c9searchresults.keyword" + }, { + value: "'" + parts[i++], + type: "text" + }]; // replaced if (parts[2] !== " in") { + replace = parts[i]; tokens.push({ value: "'" + parts[i++] + "'", type: "text" @@ -143,6 +127,7 @@ var C9SearchHighlightRules = function() { }); // options if (parts[i+1]) { + options = parts[i+1]; tokens.push({ value: "(" + parts[i+1] + ")", type: "text" @@ -151,11 +136,33 @@ var C9SearchHighlightRules = function() { } else { i -= 1; } - while (i++ < parts.length) + while (i++ < parts.length) { parts[i] && tokens.push({ value: parts[i], type: "text" }); + } + + if (replace) { + search = replace; + options = ""; + } + + if (search) { + if (!/regex/.test(options)) + search = lang.escapeRegExp(search); + if (/whole/.test(options)) + search = "\\b" + search + "\\b"; + } + + var regex = search && safeCreateRegexp( + "(" + search + ")", + / sensitive/.test(options) ? "g" : "ig" + ); + if (regex) { + stack[0] = state; + stack[1] = regex; + } return tokens; } diff --git a/lib/ace/mode/c_cpp_highlight_rules.js b/lib/ace/mode/c_cpp_highlight_rules.js index d1de84af..00fdac84 100644 --- a/lib/ace/mode/c_cpp_highlight_rules.js +++ b/lib/ace/mode/c_cpp_highlight_rules.js @@ -6,7 +6,7 @@ var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocComme var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; // used by objective-c -var cFunctions = exports.cFunctions = "\\s*\\bhypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len)))\\b" +var cFunctions = exports.cFunctions = "\\b(?:hypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len))))\\b" var c_cppHighlightRules = function() { diff --git a/lib/ace/mode/folding/c9search.js b/lib/ace/mode/folding/c9search.js index dd6a0b4f..a342d8a4 100644 --- a/lib/ace/mode/folding/c9search.js +++ b/lib/ace/mode/folding/c9search.js @@ -50,24 +50,30 @@ oop.inherits(FoldMode, BaseFoldMode); var level1 = /^(Found.*|Searching for.*)$/; var level2 = /^(\S.*\:|\s*)$/; var re = level1.test(line) ? level1 : level2; + + var startRow = row; + var endRow = row; if (this.foldingStartMarker.test(line)) { for (var i = row + 1, l = session.getLength(); i < l; i++) { if (re.test(lines[i])) break; } - - return new Range(row, line.length, i, 0); + endRow = i; } - - if (this.foldingStopMarker.test(line)) { + else if (this.foldingStopMarker.test(line)) { for (var i = row - 1; i >= 0; i--) { line = lines[i]; if (re.test(line)) break; } - - return new Range(i, line.length, row, 0); + startRow = i; + } + if (startRow != endRow) { + var col = line.length; + if (re === level1) + col = line.search(/\(Found[^)]+\)$|$/); + return new Range(startRow, col, endRow, 0); } }; diff --git a/lib/ace/mode/text.js b/lib/ace/mode/text.js index d04fed78..34a2a511 100644 --- a/lib/ace/mode/text.js +++ b/lib/ace/mode/text.js @@ -57,7 +57,7 @@ var Mode = function() { + unicode.packages.L + unicode.packages.Mn + unicode.packages.Mc + unicode.packages.Nd - + unicode.packages.Pc + "\\$_]|\s])+", "g" + + unicode.packages.Pc + "\\$_]|\\s])+", "g" ); this.getTokenizer = function() { @@ -217,10 +217,10 @@ var Mode = function() { var row = iterator.getCurrentTokenRow(); var column = iterator.getCurrentTokenColumn() + i; startRange = new Range(row, column, row, column + comment.start.length); - break + break; } token = iterator.stepBackward(); - }; + } var iterator = new TokenIterator(session, cursor.row, cursor.column); var token = iterator.getCurrentToken(); @@ -239,10 +239,10 @@ var Mode = function() { if (startRange) { session.remove(startRange); startRow = startRange.start.row; - colDiff = -comment.start.length + colDiff = -comment.start.length; } } else { - colDiff = comment.start.length + colDiff = comment.start.length; startRow = range.start.row; session.insert(range.end, comment.end); session.insert(range.start, comment.start); @@ -284,7 +284,8 @@ var Mode = function() { } } - var delegations = ['toggleCommentLines', 'getNextLineIndent', 'checkOutdent', 'autoOutdent', 'transformAction', 'getCompletions']; + var delegations = ['toggleBlockComment', 'toggleCommentLines', 'getNextLineIndent', + 'checkOutdent', 'autoOutdent', 'transformAction', 'getCompletions']; for (var i = 0; i < delegations.length; i++) { (function(scope) { @@ -292,7 +293,7 @@ var Mode = function() { var defaultHandler = scope[functionName]; scope[delegations[i]] = function() { return this.$delegator(functionName, arguments, defaultHandler); - } + }; } (this)); } }; @@ -364,7 +365,7 @@ var Mode = function() { if (!this.$highlightRules) this.getTokenizer(); return this.$keywordList = this.$highlightRules.$keywordList || []; - } + }; this.getCompletions = function(state, session, pos, prefix) { var keywords = this.$keywordList || this.$createKeywordList(); diff --git a/lib/ace/mode/text_highlight_rules.js b/lib/ace/mode/text_highlight_rules.js index 48e016b0..416e8182 100644 --- a/lib/ace/mode/text_highlight_rules.js +++ b/lib/ace/mode/text_highlight_rules.js @@ -108,15 +108,14 @@ var TextHighlightRules = function() { }; var pushState = function(currentState, stack) { - if (currentState != "start") + if (currentState != "start" || stack.length) stack.unshift(this.nextState, currentState); return this.nextState; }; var popState = function(currentState, stack) { - if (stack[0] !== currentState) - return "start"; + // if (stack[0] === currentState) stack.shift(); - return stack.shift(); + return stack.shift() || "start"; }; this.normalizeRules = function() { diff --git a/lib/ace/mouse/default_handlers.js b/lib/ace/mouse/default_handlers.js index 7e895f30..84e0ac48 100644 --- a/lib/ace/mouse/default_handlers.js +++ b/lib/ace/mouse/default_handlers.js @@ -238,7 +238,7 @@ function DefaultHandlers(mouseHandler) { if (ev.getAccelKey()) return; - //shift wheel to horiz scroll + //shift wheel to horiz scroll if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) { ev.wheelX = ev.wheelY; ev.wheelY = 0; diff --git a/lib/ace/multi_select.js b/lib/ace/multi_select.js index 7f4c5355..051d7c8f 100644 --- a/lib/ace/multi_select.js +++ b/lib/ace/multi_select.js @@ -542,7 +542,10 @@ var Editor = require("./editor").Editor; if (this.$readOnly) return; - this._signal("paste", text); + + var e = {text: text}; + this._signal("paste", e); + text = e.text; if (!this.inMultiSelectMode || this.inVirtualSelectionMode) return this.insert(text); diff --git a/lib/ace/search.js b/lib/ace/search.js index 48cd88fb..325ce00f 100644 --- a/lib/ace/search.js +++ b/lib/ace/search.js @@ -143,20 +143,27 @@ var Search = function() { if (options.$isMultiLine) { var len = re.length; var maxRow = lines.length - len; - for (var row = re.offset || 0; row <= maxRow; row++) { + var prevRange; + outer: for (var row = re.offset || 0; row <= maxRow; row++) { for (var j = 0; j < len; j++) if (lines[row + j].search(re[j]) == -1) - break; + continue outer; var startLine = lines[row]; var line = lines[row + len - 1]; - var startIndex = startLine.match(re[0])[0].length; + var startIndex = startLine.length - startLine.match(re[0])[0].length; var endIndex = line.match(re[len - 1])[0].length; - - ranges.push(new Range( - row, startLine.length - startIndex, - row + len - 1, endIndex + + if (prevRange && prevRange.end.row === row && + prevRange.end.column > startIndex + ) { + continue; + } + ranges.push(prevRange = new Range( + row, startIndex, row + len - 1, endIndex )); + if (len > 2) + row = row + len - 2; } } else { for (var i = 0; i < lines.length; i++) { diff --git a/lib/ace/theme/chrome.css b/lib/ace/theme/chrome.css index 5130817d..c91e802a 100644 --- a/lib/ace/theme/chrome.css +++ b/lib/ace/theme/chrome.css @@ -11,6 +11,7 @@ .ace-chrome { background-color: #FFFFFF; + color: black; } .ace-chrome .ace_cursor { diff --git a/lib/ace/theme/dreamweaver.css b/lib/ace/theme/dreamweaver.css index 595927b2..6709498c 100644 --- a/lib/ace/theme/dreamweaver.css +++ b/lib/ace/theme/dreamweaver.css @@ -10,6 +10,7 @@ .ace-dreamweaver { background-color: #FFFFFF; + color: black; } .ace-dreamweaver .ace_fold { diff --git a/lib/ace/theme/eclipse.css b/lib/ace/theme/eclipse.css index 6deec44b..6615db3a 100644 --- a/lib/ace/theme/eclipse.css +++ b/lib/ace/theme/eclipse.css @@ -11,6 +11,7 @@ .ace-eclipse { background-color: #FFFFFF; + color: black; } .ace-eclipse .ace_fold { diff --git a/lib/ace/theme/textmate.css b/lib/ace/theme/textmate.css index 13c4e848..6cb159ba 100644 --- a/lib/ace/theme/textmate.css +++ b/lib/ace/theme/textmate.css @@ -14,6 +14,7 @@ .ace-tm { background-color: #FFFFFF; + color: black; } .ace-tm .ace_cursor { diff --git a/lib/ace/theme/xcode.css b/lib/ace/theme/xcode.css index ae58ef21..56eb9a89 100644 --- a/lib/ace/theme/xcode.css +++ b/lib/ace/theme/xcode.css @@ -1,4 +1,3 @@ -.ace-xcode .ace_gutter, /* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: EE3AD170-2B7F-4DE1-B724-C75F13FE0085) */ .ace-xcode .ace_gutter { diff --git a/lib/ace/undomanager.js b/lib/ace/undomanager.js index 304dac23..4411ae8b 100644 --- a/lib/ace/undomanager.js +++ b/lib/ace/undomanager.js @@ -64,6 +64,7 @@ var UndoManager = function() { var deltas = options.args[0]; this.$doc = options.args[1]; if (options.merge && this.hasUndo()){ + this.dirtyCounter--; deltas = this.$undoStack.pop().concat(deltas); } this.$undoStack.push(deltas); diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index ae85c4f0..f1757d92 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -369,7 +369,7 @@ var VirtualRenderer = function(container, theme) { }; if (height && (force || size.height != height)) { size.height = height; - changes = this.CHANGE_SIZE; + changes |= this.CHANGE_SIZE; size.scrollerHeight = size.height; if (this.$horizScroll) @@ -378,14 +378,11 @@ var VirtualRenderer = function(container, theme) { // this.scrollBarV.setHeight(size.scrollerHeight); this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + "px"; - if (this.session) { - //this.session.setScrollTop(this.getScrollTop()); - changes = changes | this.CHANGE_SCROLL; - } + changes = changes | this.CHANGE_SCROLL; } if (width && (force || size.width != width)) { - changes = this.CHANGE_SIZE; + changes |= this.CHANGE_SIZE; size.width = width; if (gutterWidth == null) @@ -404,7 +401,7 @@ var VirtualRenderer = function(container, theme) { // this.scrollBarH.element.style.setWidth(size.scrollerWidth); if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force) - changes = changes | this.CHANGE_FULL; + changes |= this.CHANGE_FULL; } size.$dirty = !width || !height; @@ -897,18 +894,19 @@ var VirtualRenderer = function(container, theme) { this.$autosize(); var session = this.session; + var size = this.$size; - var hideScrollbars = this.$size.height <= 2 * this.lineHeight; + var hideScrollbars = size.height <= 2 * this.lineHeight; var screenLines = this.session.getScreenLength(); var maxHeight = screenLines * this.lineHeight; var offset = this.scrollTop % this.lineHeight; - var minHeight = this.$size.scrollerHeight + this.lineHeight; + var minHeight = size.scrollerHeight + this.lineHeight; var longestLine = this.$getLongestLine(); var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible || - this.$size.scrollerWidth - longestLine - 2 * this.$padding < 0); + size.scrollerWidth - longestLine - 2 * this.$padding < 0); var hScrollChanged = this.$horizScroll !== horizScroll; if (hScrollChanged) { @@ -917,15 +915,15 @@ var VirtualRenderer = function(container, theme) { } if (!this.$maxLines && this.$scrollPastEnd) { - if (this.scrollTop > maxHeight - this.$size.scrollerHeight) + if (this.scrollTop > maxHeight - size.scrollerHeight) maxHeight += Math.min( - (this.$size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd, - this.scrollTop - maxHeight + this.$size.scrollerHeight + (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd, + this.scrollTop - maxHeight + size.scrollerHeight ); } var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible || - this.$size.scrollerHeight - maxHeight < 0); + size.scrollerHeight - maxHeight < 0); var vScrollChanged = this.$vScroll !== vScroll; if (vScrollChanged) { this.$vScroll = vScroll; @@ -933,10 +931,10 @@ var VirtualRenderer = function(container, theme) { } this.session.setScrollTop(Math.max(-this.scrollMargin.top, - Math.min(this.scrollTop, maxHeight - this.$size.scrollerHeight + this.scrollMargin.v))); + Math.min(this.scrollTop, maxHeight - size.scrollerHeight + this.scrollMargin.bottom))); this.session.setScrollLeft(Math.max(-this.scrollMargin.left, Math.min(this.scrollLeft, - longestLine + 2 * this.$padding - this.$size.scrollerWidth + this.scrollMargin.h))); + longestLine + 2 * this.$padding - size.scrollerWidth + this.scrollMargin.right))); var lineCount = Math.ceil(minHeight / this.lineHeight) - 1; var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight)); @@ -958,16 +956,18 @@ var VirtualRenderer = function(container, theme) { firstRowHeight = session.getRowLength(firstRow) * lineHeight; lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1); - minHeight = this.$size.scrollerHeight + session.getRowLength(lastRow) * lineHeight + + minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight + firstRowHeight; offset = this.scrollTop - firstRowScreen * lineHeight; var changes = 0; + if (this.layerConfig.width != longestLine) + changes = this.CHANGE_H_SCROLL; // Horizontal scrollbar visibility may have changed, which changes // the client height of the scroller if (hScrollChanged || vScrollChanged) { - changes = this.$updateCachedSize(true, this.gutterWidth, this.$size.width, this.$size.height); + changes = this.$updateCachedSize(true, this.gutterWidth, size.width, size.height); this._signal("scrollbarVisibilityChanged"); if (vScrollChanged) longestLine = this.$getLongestLine(); @@ -984,6 +984,7 @@ var VirtualRenderer = function(container, theme) { minHeight : minHeight, maxHeight : maxHeight, offset : offset, + gutterOffset : Math.ceil((offset + size.height - size.scrollerHeight) / lineHeight), height : this.$size.scrollerHeight }; @@ -1113,7 +1114,7 @@ var VirtualRenderer = function(container, theme) { * * Scrolls the cursor into the first visibile area of the editor **/ - this.scrollCursorIntoView = function(cursor, offset) { + this.scrollCursorIntoView = function(cursor, offset, $viewMargin) { // the editor is not visible if (this.$size.scrollerHeight === 0) return; @@ -1123,17 +1124,18 @@ var VirtualRenderer = function(container, theme) { var left = pos.left; var top = pos.top; + var topMargin = $viewMargin && $viewMargin.top || 0; + var bottomMargin = $viewMargin && $viewMargin.bottom || 0; + var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop; - - if (scrollTop > top) { + + if (scrollTop + topMargin > top) { if (offset) top -= offset * this.$size.scrollerHeight; - if (top == 0) - top = - this.scrollMargin.top; - else if (top == 0) - top = + this.scrollMargin.bottom; + if (top === 0) + top = -this.scrollMargin.top; this.session.setScrollTop(top); - } else if (scrollTop + this.$size.scrollerHeight < top + this.lineHeight) { + } else if (scrollTop + this.$size.scrollerHeight - bottomMargin < top + this.lineHeight) { if (offset) top += offset * this.$size.scrollerHeight; this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight); @@ -1617,6 +1619,13 @@ config.defineOptions(VirtualRenderer.prototype, "renderer", { set: function(show) {this.$gutterLayer.setShowFoldWidgets(show)}, initialValue: true }, + showLineNumbers: { + set: function(show) { + this.$gutterLayer.setShowLineNumbers(show); + this.$loop.schedule(this.CHANGE_GUTTER); + }, + initialValue: true + }, displayIndentGuides: { set: function(show) { if (this.$textLayer.setDisplayIndentGuides(show)) diff --git a/lib/ace/worker/worker.js b/lib/ace/worker/worker.js index 04296156..b1b83ba9 100644 --- a/lib/ace/worker/worker.js +++ b/lib/ace/worker/worker.js @@ -17,7 +17,7 @@ window.window = window; window.ace = window; window.onerror = function(message, file, line, col, err) { - console.error("Worker " + err.stack); + console.error("Worker " + (err ? err.stack : message)); }; window.normalizeModule = function(parentId, moduleName) {