You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2013/10/30 14:43:37 UTC

[43/52] [partial] Remove unneeded ace files and codemirror

http://git-wip-us.apache.org/repos/asf/couchdb/blob/5b8fb9c3/src/fauxton/assets/js/libs/ace/editor.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/editor.js b/src/fauxton/assets/js/libs/ace/editor.js
deleted file mode 100644
index 4ff568c..0000000
--- a/src/fauxton/assets/js/libs/ace/editor.js
+++ /dev/null
@@ -1,2423 +0,0 @@
-/* ***** 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";
-
-require("./lib/fixoldbrowsers");
-
-var oop = require("./lib/oop");
-var dom = require("./lib/dom");
-var lang = require("./lib/lang");
-var useragent = require("./lib/useragent");
-var TextInput = require("./keyboard/textinput").TextInput;
-var MouseHandler = require("./mouse/mouse_handler").MouseHandler;
-var FoldHandler = require("./mouse/fold_handler").FoldHandler;
-var KeyBinding = require("./keyboard/keybinding").KeyBinding;
-var EditSession = require("./edit_session").EditSession;
-var Search = require("./search").Search;
-var Range = require("./range").Range;
-var EventEmitter = require("./lib/event_emitter").EventEmitter;
-var CommandManager = require("./commands/command_manager").CommandManager;
-var defaultCommands = require("./commands/default_commands").commands;
-var config = require("./config");
-
-/**
- * The main entry point into the Ace functionality.
- *
- * The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.
- *
- * Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.
- * @class Editor
- **/
-
-/**
- * Creates a new `Editor` object.
- *
- * @param {VirtualRenderer} renderer Associated `VirtualRenderer` that draws everything
- * @param {EditSession} session The `EditSession` to refer to
- *
- *
- * @constructor
- **/
-var Editor = function(renderer, session) {
-    var container = renderer.getContainerElement();
-    this.container = container;
-    this.renderer = renderer;
-
-    this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
-    this.textInput  = new TextInput(renderer.getTextAreaContainer(), this);
-    this.renderer.textarea = this.textInput.getElement();
-    this.keyBinding = new KeyBinding(this);
-
-    // TODO detect touch event support
-    this.$mouseHandler = new MouseHandler(this);
-    new FoldHandler(this);
-
-    this.$blockScrolling = 0;
-    this.$search = new Search().set({
-        wrap: true
-    });
-
-    this.$historyTracker = this.$historyTracker.bind(this);
-    this.commands.on("exec", this.$historyTracker);
-
-    this.$initOperationListeners();
-    
-    this._$emitInputEvent = lang.delayedCall(function() {
-        this._signal("input", {});
-        this.session.bgTokenizer && this.session.bgTokenizer.scheduleStart();
-    }.bind(this));
-    
-    this.on("change", function(_, _self) {
-        _self._$emitInputEvent.schedule(31);
-    });
-
-    this.setSession(session || new EditSession(""));
-    config.resetOptions(this);
-    config._emit("editor", this);
-};
-
-(function(){
-
-    oop.implement(this, EventEmitter);
-
-    this.$initOperationListeners = function() {
-        function last(a) {return a[a.length - 1]};
-
-        this.selections = [];
-        this.commands.on("exec", function(e) {
-            this.startOperation(e);
-
-            var command = e.command;
-            if (command.group == "fileJump") {
-                var prev = this.prevOp;
-                if (!prev || prev.command.group != "fileJump") {
-                    this.lastFileJumpPos = last(this.selections)
-                }
-            } else {
-                this.lastFileJumpPos = null;
-            }
-        }.bind(this), true);
-
-        this.commands.on("afterExec", function(e) {
-            var command = e.command;
-
-            if (command.group == "fileJump") {
-                if (this.lastFileJumpPos && !this.curOp.selectionChanged) {
-                    this.selection.fromJSON(this.lastFileJumpPos);
-                    return
-                }
-            }
-            this.endOperation(e);
-        }.bind(this), true);
-
-        this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this));
-
-        this.on("change", function() {
-            this.curOp || this.startOperation();
-            this.curOp.docChanged = true;
-        }.bind(this), true);
-
-        this.on("changeSelection", function() {
-            this.curOp || this.startOperation();
-            this.curOp.selectionChanged = true;
-        }.bind(this), true);
-    }
-
-    this.curOp = null;
-    this.prevOp = {};
-    this.startOperation = function(commadEvent) {
-        if (this.curOp) {
-            if (!commadEvent || this.curOp.command)
-                return;
-            this.prevOp = this.curOp;
-        }
-        if (!commadEvent) {
-            this.previousCommand = null;
-            commadEvent = {};
-        }
-
-        this.$opResetTimer.schedule();
-        this.curOp = {
-            command: commadEvent.command || {},
-            args: commadEvent.args
-        };
-
-        this.selections.push(this.selection.toJSON());
-    };
-
-    this.endOperation = function() {
-        if (this.curOp) {
-            this.prevOp = this.curOp;
-            this.curOp = null;
-        }
-    };
-
-    this.$historyTracker = function(e) {
-        if (!this.$mergeUndoDeltas)
-            return;
-
-
-        var prev = this.prevOp;
-        var mergeableCommands = ["backspace", "del", "insertstring"];
-        // previous command was the same
-        var shouldMerge = prev.command && (e.command.name == prev.command.name);
-        if (e.command.name == "insertstring") {
-            var text = e.args;
-            if (this.mergeNextCommand === undefined)
-                this.mergeNextCommand = true;
-
-            shouldMerge = shouldMerge
-                && this.mergeNextCommand // previous command allows to coalesce with
-                && (!/\s/.test(text) || /\s/.test(prev.args)) // previous insertion was of same type
-
-            this.mergeNextCommand = true;
-        } else {
-            shouldMerge = shouldMerge
-                && mergeableCommands.indexOf(e.command.name) !== -1// the command is mergeable
-        }
-
-        if (
-            this.$mergeUndoDeltas != "always"
-            && Date.now() - this.sequenceStartTime > 2000
-        ) {
-            shouldMerge = false; // the sequence is too long
-        }
-
-        if (shouldMerge)
-            this.session.mergeUndoDeltas = true;
-        else if (mergeableCommands.indexOf(e.command.name) !== -1)
-            this.sequenceStartTime = Date.now();
-    };
-
-    /**
-     * Sets a new key handler, such as "vim" or "windows".
-     * @param {String} keyboardHandler The new key handler
-     *
-     *
-     **/
-    this.setKeyboardHandler = function(keyboardHandler) {
-        if (!keyboardHandler) {
-            this.keyBinding.setKeyboardHandler(null);
-        } else if (typeof keyboardHandler == "string") {
-            this.$keybindingId = keyboardHandler;
-            var _self = this;
-            config.loadModule(["keybinding", keyboardHandler], function(module) {
-                if (_self.$keybindingId == keyboardHandler)
-                    _self.keyBinding.setKeyboardHandler(module && module.handler);
-            });
-        } else {
-            this.$keybindingId = null;
-            this.keyBinding.setKeyboardHandler(keyboardHandler);
-        }
-    };
-
-    /**
-     * Returns the keyboard handler, such as "vim" or "windows".
-     *
-     * @returns {String}
-     *
-     **/
-    this.getKeyboardHandler = function() {
-        return this.keyBinding.getKeyboardHandler();
-    };
-
-
-    /**
-     * Emitted whenever the [[EditSession]] changes.
-     * @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.
-     * @param {EditSession} session The new session to use
-     *
-     *
-     **/
-    this.setSession = function(session) {
-        if (this.session == session)
-            return;
-
-        if (this.session) {
-            var oldSession = this.session;
-            this.session.removeEventListener("change", this.$onDocumentChange);
-            this.session.removeEventListener("changeMode", this.$onChangeMode);
-            this.session.removeEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
-            this.session.removeEventListener("changeTabSize", this.$onChangeTabSize);
-            this.session.removeEventListener("changeWrapLimit", this.$onChangeWrapLimit);
-            this.session.removeEventListener("changeWrapMode", this.$onChangeWrapMode);
-            this.session.removeEventListener("onChangeFold", this.$onChangeFold);
-            this.session.removeEventListener("changeFrontMarker", this.$onChangeFrontMarker);
-            this.session.removeEventListener("changeBackMarker", this.$onChangeBackMarker);
-            this.session.removeEventListener("changeBreakpoint", this.$onChangeBreakpoint);
-            this.session.removeEventListener("changeAnnotation", this.$onChangeAnnotation);
-            this.session.removeEventListener("changeOverwrite", this.$onCursorChange);
-            this.session.removeEventListener("changeScrollTop", this.$onScrollTopChange);
-            this.session.removeEventListener("changeScrollLeft", this.$onScrollLeftChange);
-
-            var selection = this.session.getSelection();
-            selection.removeEventListener("changeCursor", this.$onCursorChange);
-            selection.removeEventListener("changeSelection", this.$onSelectionChange);
-        }
-
-        this.session = session;
-
-        this.$onDocumentChange = this.onDocumentChange.bind(this);
-        session.addEventListener("change", this.$onDocumentChange);
-        this.renderer.setSession(session);
-
-        this.$onChangeMode = this.onChangeMode.bind(this);
-        session.addEventListener("changeMode", this.$onChangeMode);
-
-        this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
-        session.addEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
-
-        this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
-        session.addEventListener("changeTabSize", this.$onChangeTabSize);
-
-        this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
-        session.addEventListener("changeWrapLimit", this.$onChangeWrapLimit);
-
-        this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
-        session.addEventListener("changeWrapMode", this.$onChangeWrapMode);
-
-        this.$onChangeFold = this.onChangeFold.bind(this);
-        session.addEventListener("changeFold", this.$onChangeFold);
-
-        this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
-        this.session.addEventListener("changeFrontMarker", this.$onChangeFrontMarker);
-
-        this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
-        this.session.addEventListener("changeBackMarker", this.$onChangeBackMarker);
-
-        this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
-        this.session.addEventListener("changeBreakpoint", this.$onChangeBreakpoint);
-
-        this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
-        this.session.addEventListener("changeAnnotation", this.$onChangeAnnotation);
-
-        this.$onCursorChange = this.onCursorChange.bind(this);
-        this.session.addEventListener("changeOverwrite", this.$onCursorChange);
-
-        this.$onScrollTopChange = this.onScrollTopChange.bind(this);
-        this.session.addEventListener("changeScrollTop", this.$onScrollTopChange);
-
-        this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
-        this.session.addEventListener("changeScrollLeft", this.$onScrollLeftChange);
-
-        this.selection = session.getSelection();
-        this.selection.addEventListener("changeCursor", this.$onCursorChange);
-
-        this.$onSelectionChange = this.onSelectionChange.bind(this);
-        this.selection.addEventListener("changeSelection", this.$onSelectionChange);
-
-        this.onChangeMode();
-
-        this.$blockScrolling += 1;
-        this.onCursorChange();
-        this.$blockScrolling -= 1;
-
-        this.onScrollTopChange();
-        this.onScrollLeftChange();
-        this.onSelectionChange();
-        this.onChangeFrontMarker();
-        this.onChangeBackMarker();
-        this.onChangeBreakpoint();
-        this.onChangeAnnotation();
-        this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
-        this.renderer.updateFull();
-
-        this._emit("changeSession", {
-            session: session,
-            oldSession: oldSession
-        });
-    };
-
-    /**
-     * Returns the current session being used.
-     * @returns {EditSession}
-     **/
-    this.getSession = function() {
-        return this.session;
-    };
-
-    /**
-     * Sets the current document to `val`.
-     * @param {String} val The new value to set for the document
-     * @param {Number} cursorPos Where to set the new value. `undefined` or 0 is selectAll, -1 is at the document start, and 1 is at the end
-     *
-     * @returns {String} The current document value
-     * @related Document.setValue
-     **/
-    this.setValue = function(val, cursorPos) {
-        this.session.doc.setValue(val);
-
-        if (!cursorPos)
-            this.selectAll();
-        else if (cursorPos == 1)
-            this.navigateFileEnd();
-        else if (cursorPos == -1)
-            this.navigateFileStart();
-
-        return val;
-    };
-
-    /**
-     * Returns the current session's content.
-     *
-     * @returns {String}
-     * @related EditSession.getValue
-     **/
-    this.getValue = function() {
-        return this.session.getValue();
-    };
-
-    /**
-     *
-     * Returns the currently highlighted selection.
-     * @returns {String} The highlighted selection
-     **/
-    this.getSelection = function() {
-        return this.selection;
-    };
-
-    /**
-     * {:VirtualRenderer.onResize}
-     * @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed
-     *
-     *
-     * @related VirtualRenderer.onResize
-     **/
-    this.resize = function(force) {
-        this.renderer.onResize(force);
-    };
-
-    /**
-     * {:VirtualRenderer.setTheme}
-     * @param {String} theme The path to a theme
-     *
-     *
-     **/
-    this.setTheme = function(theme) {
-        this.renderer.setTheme(theme);
-    };
-
-    /**
-     * {:VirtualRenderer.getTheme}
-     *
-     * @returns {String} The set theme
-     * @related VirtualRenderer.getTheme
-     **/
-    this.getTheme = function() {
-        return this.renderer.getTheme();
-    };
-
-    /**
-     * {:VirtualRenderer.setStyle}
-     * @param {String} style A class name
-     *
-     *
-     * @related VirtualRenderer.setStyle
-     **/
-    this.setStyle = function(style) {
-        this.renderer.setStyle(style);
-    };
-
-    /**
-     * {:VirtualRenderer.unsetStyle}
-     * @related VirtualRenderer.unsetStyle
-     **/
-    this.unsetStyle = function(style) {
-        this.renderer.unsetStyle(style);
-    };
-
-    /**
-     * Gets the current font size of the editor text.
-     */
-    this.getFontSize = function () {
-        return this.getOption("fontSize") ||
-           dom.computedStyle(this.container, "fontSize");
-    };
-
-    /**
-     * Set a new font size (in pixels) for the editor text.
-     * @param {String} size A font size ( _e.g._ "12px")
-     *
-     *
-     **/
-    this.setFontSize = function(size) {
-        this.setOption("fontSize", size);
-    };
-
-    this.$highlightBrackets = function() {
-        if (this.session.$bracketHighlight) {
-            this.session.removeMarker(this.session.$bracketHighlight);
-            this.session.$bracketHighlight = null;
-        }
-
-        if (this.$highlightPending) {
-            return;
-        }
-
-        // perform highlight async to not block the browser during navigation
-        var self = this;
-        this.$highlightPending = true;
-        setTimeout(function() {
-            self.$highlightPending = false;
-
-            var pos = self.session.findMatchingBracket(self.getCursorPosition());
-            if (pos) {
-                var range = new Range(pos.row, pos.column, pos.row, pos.column+1);
-            } else if (self.session.$mode.getMatching) {
-                var range = self.session.$mode.getMatching(self.session);
-            }
-            if (range)
-                self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket", "text");
-        }, 50);
-    };
-
-    /**
-     *
-     * Brings the current `textInput` into focus.
-     **/
-    this.focus = function() {
-        // Safari needs the timeout
-        // iOS and Firefox need it called immediately
-        // to be on the save side we do both
-        var _self = this;
-        setTimeout(function() {
-            _self.textInput.focus();
-        });
-        this.textInput.focus();
-    };
-
-    /**
-     * Returns `true` if the current `textInput` is in focus.
-     * @return {Boolean}
-     **/
-    this.isFocused = function() {
-        return this.textInput.isFocused();
-    };
-
-    /**
-     *
-     * Blurs the current `textInput`.
-     **/
-    this.blur = function() {
-        this.textInput.blur();
-    };
-
-    /**
-     * Emitted once the editor comes into focus.
-     * @event focus
-     *
-     *
-     **/
-    this.onFocus = function() {
-        if (this.$isFocused)
-            return;
-        this.$isFocused = true;
-        this.renderer.showCursor();
-        this.renderer.visualizeFocus();
-        this._emit("focus");
-    };
-
-    /**
-     * Emitted once the editor has been blurred.
-     * @event blur
-     *
-     *
-     **/
-    this.onBlur = function() {
-        if (!this.$isFocused)
-            return;
-        this.$isFocused = false;
-        this.renderer.hideCursor();
-        this.renderer.visualizeBlur();
-        this._emit("blur");
-    };
-
-    this.$cursorChange = function() {
-        this.renderer.updateCursor();
-    };
-
-    /**
-     * Emitted whenever the document is changed.
-     * @event change
-     * @param {Object} e Contains a single property, `data`, which has the delta of changes
-     *
-     *
-     *
-     **/
-    this.onDocumentChange = function(e) {
-        var delta = e.data;
-        var range = delta.range;
-        var lastRow;
-
-        if (range.start.row == range.end.row && delta.action != "insertLines" && delta.action != "removeLines")
-            lastRow = range.end.row;
-        else
-            lastRow = Infinity;
-        this.renderer.updateLines(range.start.row, lastRow);
-
-        this._emit("change", e);
-
-        // update cursor because tab characters can influence the cursor position
-        this.$cursorChange();
-    };
-
-    this.onTokenizerUpdate = function(e) {
-        var rows = e.data;
-        this.renderer.updateLines(rows.first, rows.last);
-    };
-
-
-    this.onScrollTopChange = function() {
-        this.renderer.scrollToY(this.session.getScrollTop());
-    };
-
-    this.onScrollLeftChange = function() {
-        this.renderer.scrollToX(this.session.getScrollLeft());
-    };
-
-    /**
-     * Emitted when the selection changes.
-     *
-     **/
-    this.onCursorChange = function() {
-        this.$cursorChange();
-
-        if (!this.$blockScrolling) {
-            this.renderer.scrollCursorIntoView();
-        }
-
-        this.$highlightBrackets();
-        this.$updateHighlightActiveLine();
-        this._emit("changeSelection");
-    };
-
-    this.$updateHighlightActiveLine = function() {
-        var session = this.getSession();
-
-        var highlight;
-        if (this.$highlightActiveLine) {
-            if ((this.$selectionStyle != "line" || !this.selection.isMultiLine()))
-                highlight = this.getCursorPosition();
-            if (this.renderer.$maxLines && this.session.getLength() === 1)
-                highlight = false;
-        }
-
-        if (session.$highlightLineMarker && !highlight) {
-            session.removeMarker(session.$highlightLineMarker.id);
-            session.$highlightLineMarker = null;
-        } else if (!session.$highlightLineMarker && highlight) {
-            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
-            range.id = session.addMarker(range, "ace_active-line", "screenLine");
-            session.$highlightLineMarker = range;
-        } else if (highlight) {
-            session.$highlightLineMarker.start.row = highlight.row;
-            session.$highlightLineMarker.end.row = highlight.row;
-            session.$highlightLineMarker.start.column = highlight.column;
-            session._emit("changeBackMarker");
-        }
-    };
-
-    this.onSelectionChange = function(e) {
-        var session = this.session;
-
-        if (session.$selectionMarker) {
-            session.removeMarker(session.$selectionMarker);
-        }
-        session.$selectionMarker = null;
-
-        if (!this.selection.isEmpty()) {
-            var range = this.selection.getRange();
-            var style = this.getSelectionStyle();
-            session.$selectionMarker = session.addMarker(range, "ace_selection", style);
-        } else {
-            this.$updateHighlightActiveLine();
-        }
-
-        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()
-        this.session.highlight(re);
-
-        this._emit("changeSelection");
-    };
-
-    this.$getSelectionHighLightRegexp = function() {
-        var session = this.session;
-
-        var selection = this.getSelectionRange();
-        if (selection.isEmpty() || selection.isMultiLine())
-            return;
-
-        var startOuter = selection.start.column - 1;
-        var endOuter = selection.end.column + 1;
-        var line = session.getLine(selection.start.row);
-        var lineCols = line.length;
-        var needle = line.substring(Math.max(startOuter, 0),
-                                    Math.min(endOuter, lineCols));
-
-        // Make sure the outer characters are not part of the word.
-        if ((startOuter >= 0 && /^[\w\d]/.test(needle)) ||
-            (endOuter <= lineCols && /[\w\d]$/.test(needle)))
-            return;
-
-        needle = line.substring(selection.start.column, selection.end.column);
-        if (!/^[\w\d]+$/.test(needle))
-            return;
-
-        var re = this.$search.$assembleRegExp({
-            wholeWord: true,
-            caseSensitive: true,
-            needle: needle
-        });
-
-        return re;
-    };
-
-
-    this.onChangeFrontMarker = function() {
-        this.renderer.updateFrontMarkers();
-    };
-
-    this.onChangeBackMarker = function() {
-        this.renderer.updateBackMarkers();
-    };
-
-
-    this.onChangeBreakpoint = function() {
-        this.renderer.updateBreakpoints();
-    };
-
-    this.onChangeAnnotation = function() {
-        this.renderer.setAnnotations(this.session.getAnnotations());
-    };
-
-
-    this.onChangeMode = function(e) {
-        this.renderer.updateText();
-        this._emit("changeMode", e);
-    };
-
-
-    this.onChangeWrapLimit = function() {
-        this.renderer.updateFull();
-    };
-
-    this.onChangeWrapMode = function() {
-        this.renderer.onResize(true);
-    };
-
-
-    this.onChangeFold = function() {
-        // Update the active line marker as due to folding changes the current
-        // line range on the screen might have changed.
-        this.$updateHighlightActiveLine();
-        // TODO: This might be too much updating. Okay for now.
-        this.renderer.updateFull();
-    };
-
-    
-    /**
-     * Returns the string of text currently highlighted.
-     * @returns {String}
-     **/
-    this.getSelectedText = function() {
-        return this.session.getTextRange(this.getSelectionRange());
-    };
-    
-    /**
-     * Emitted when text is copied.
-     * @event copy
-     * @param {String} text The copied text
-     *
-     **/
-    /**
-     * Returns the string of text currently highlighted.
-     * @returns {String}
-     * @deprecated Use getSelectedText instead.
-     **/
-    this.getCopyText = function() {
-        var text = this.getSelectedText();
-        this._signal("copy", text);
-        return text;
-    };
-
-    /**
-     * Called whenever a text "copy" happens.
-     **/
-    this.onCopy = function() {
-        this.commands.exec("copy", this);
-    };
-
-    /**
-     * Called whenever a text "cut" happens.
-     **/
-    this.onCut = function() {
-        this.commands.exec("cut", this);
-    };
-
-    /**
-     * Emitted when text is pasted.
-     * @event paste
-     * @param {String} text The pasted text
-     *
-     *
-     **/
-    /**
-     * Called whenever a text "paste" happens.
-     * @param {String} text The pasted text
-     *
-     *
-     **/
-    this.onPaste = function(text) {
-        // todo this should change when paste becomes a command
-        if (this.$readOnly)
-            return;
-        this._emit("paste", text);
-        this.insert(text);
-    };
-
-
-    this.execCommand = function(command, args) {
-        this.commands.exec(command, this, args);
-    };
-
-    /**
-     * Inserts `text` into wherever the cursor is pointing.
-     * @param {String} text The new text to add
-     *
-     *
-     **/
-    this.insert = function(text) {
-        var session = this.session;
-        var mode = session.getMode();
-        var cursor = this.getCursorPosition();
-
-        if (this.getBehavioursEnabled()) {
-            // Get a transform if the current mode wants one.
-            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
-            if (transform) {
-                if (text !== transform.text) {
-                    this.session.mergeUndoDeltas = false;
-                    this.$mergeNextCommand = false;
-                }
-                text = transform.text;
-
-            }
-        }
-        
-        if (text == "\t")
-            text = this.session.getTabString();
-
-        // remove selected text
-        if (!this.selection.isEmpty()) {
-            var range = this.getSelectionRange();
-            cursor = this.session.remove(range);
-            this.clearSelection();
-        }
-        else if (this.session.getOverwrite()) {
-            var range = new Range.fromPoints(cursor, cursor);
-            range.end.column += text.length;
-            this.session.remove(range);
-        }
-
-        if (text == "\n" || text == "\r\n") {
-            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);
-            }
-        }
-        this.clearSelection();
-
-        var start = cursor.column;
-        var lineState = session.getState(cursor.row);
-        var line = session.getLine(cursor.row);
-        var shouldOutdent = mode.checkOutdent(lineState, line, text);
-        var end = session.insert(cursor, text);
-
-        if (transform && transform.selection) {
-            if (transform.selection.length == 2) { // Transform relative to the current column
-                this.selection.setSelectionRange(
-                    new Range(cursor.row, start + transform.selection[0],
-                              cursor.row, start + transform.selection[1]));
-            } else { // Transform relative to the current row.
-                this.selection.setSelectionRange(
-                    new Range(cursor.row + transform.selection[0],
-                              transform.selection[1],
-                              cursor.row + transform.selection[2],
-                              transform.selection[3]));
-            }
-        }
-
-        if (session.getDocument().isNewLine(text)) {
-            var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
-
-            session.insert({row: cursor.row+1, column: 0}, lineIndent);
-        }
-        if (shouldOutdent)
-            mode.autoOutdent(lineState, session, cursor.row);
-    };
-
-    this.onTextInput = function(text) {
-        this.keyBinding.onTextInput(text);
-    };
-
-    this.onCommandKey = function(e, hashId, keyCode) {
-        this.keyBinding.onCommandKey(e, hashId, keyCode);
-    };
-
-    /**
-     * Pass in `true` to enable overwrites in your session, or `false` to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emites the `changeOverwrite` event.
-     * @param {Boolean} overwrite Defines wheter or not to set overwrites
-     *
-     *
-     * @related EditSession.setOverwrite
-     **/
-    this.setOverwrite = function(overwrite) {
-        this.session.setOverwrite(overwrite);
-    };
-
-    /**
-     * Returns `true` if overwrites are enabled; `false` otherwise.
-     * @returns {Boolean}
-     * @related EditSession.getOverwrite
-     **/
-    this.getOverwrite = function() {
-        return this.session.getOverwrite();
-    };
-
-    /**
-     * Sets the value of overwrite to the opposite of whatever it currently is.
-     * @related EditSession.toggleOverwrite
-     **/
-    this.toggleOverwrite = function() {
-        this.session.toggleOverwrite();
-    };
-
-    /**
-     * Sets how fast the mouse scrolling should do.
-     * @param {Number} speed A value indicating the new speed (in milliseconds)
-     **/
-    this.setScrollSpeed = function(speed) {
-        this.setOption("scrollSpeed", speed);
-    };
-
-    /**
-     * Returns the value indicating how fast the mouse scroll speed is (in milliseconds).
-     * @returns {Number}
-     **/
-    this.getScrollSpeed = function() {
-        return this.getOption("scrollSpeed");
-    };
-
-    /**
-     * Sets the delay (in milliseconds) of the mouse drag.
-     * @param {Number} dragDelay A value indicating the new delay
-     **/
-    this.setDragDelay = function(dragDelay) {
-        this.setOption("dragDelay", dragDelay);
-    };
-
-    /**
-     * Returns the current mouse drag delay.
-     * @returns {Number}
-     **/
-    this.getDragDelay = function() {
-        return this.getOption("dragDelay");
-    };
-
-    /**
-     * Emitted when the selection style changes, via [[Editor.setSelectionStyle]].
-     * @event changeSelectionStyle
-     * @param {Object} data Contains one property, `data`, which indicates the new selection style
-     **/
-    /**
-     * Draw selection markers spanning whole line, or only over selected text. Default value is "line"
-     * @param {String} style The new selection style "line"|"text"
-     *
-     **/
-    this.setSelectionStyle = function(val) {
-        this.setOption("selectionStyle", val);
-    };
-
-    /**
-     * Returns the current selection style.
-     * @returns {String}
-     **/
-    this.getSelectionStyle = function() {
-        return this.getOption("selectionStyle");
-    };
-
-    /**
-     * Determines whether or not the current line should be highlighted.
-     * @param {Boolean} shouldHighlight Set to `true` to highlight the current line
-     **/
-    this.setHighlightActiveLine = function(shouldHighlight) {
-        this.setOption("highlightActiveLine", shouldHighlight);
-    };
-    /**
-     * Returns `true` if current lines are always highlighted.
-     * @return {Boolean}
-     **/
-    this.getHighlightActiveLine = function() {
-        return this.getOption("highlightActiveLine");
-    };
-    this.setHighlightGutterLine = function(shouldHighlight) {
-        this.setOption("highlightGutterLine", shouldHighlight);
-    };
-
-    this.getHighlightGutterLine = function() {
-        return this.getOption("highlightGutterLine");
-    };
-    /**
-     * Determines if the currently selected word should be highlighted.
-     * @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word
-     *
-     **/
-    this.setHighlightSelectedWord = function(shouldHighlight) {
-        this.setOption("highlightSelectedWord", shouldHighlight);
-    };
-
-    /**
-     * Returns `true` if currently highlighted words are to be highlighted.
-     * @returns {Boolean}
-     **/
-    this.getHighlightSelectedWord = function() {
-        return this.$highlightSelectedWord;
-    };
-
-    this.setAnimatedScroll = function(shouldAnimate){
-        this.renderer.setAnimatedScroll(shouldAnimate);
-    };
-
-    this.getAnimatedScroll = function(){
-        return this.renderer.getAnimatedScroll();
-    };
-
-    /**
-     * If `showInvisibles` is set to `true`, invisible characters&mdash;like spaces or new lines&mdash;are show in the editor.
-     * @param {Boolean} showInvisibles Specifies whether or not to show invisible characters
-     *
-     **/
-    this.setShowInvisibles = function(showInvisibles) {
-        this.renderer.setShowInvisibles(showInvisibles);
-    };
-
-    /**
-     * Returns `true` if invisible characters are being shown.
-     * @returns {Boolean}
-     **/
-    this.getShowInvisibles = function() {
-        return this.renderer.getShowInvisibles();
-    };
-
-    this.setDisplayIndentGuides = function(display) {
-        this.renderer.setDisplayIndentGuides(display);
-    };
-
-    this.getDisplayIndentGuides = function() {
-        return this.renderer.getDisplayIndentGuides();
-    };
-
-    /**
-     * If `showPrintMargin` is set to `true`, the print margin is shown in the editor.
-     * @param {Boolean} showPrintMargin Specifies whether or not to show the print margin
-     *
-     **/
-    this.setShowPrintMargin = function(showPrintMargin) {
-        this.renderer.setShowPrintMargin(showPrintMargin);
-    };
-
-    /**
-     * Returns `true` if the print margin is being shown.
-     * @returns {Boolean}
-     **/
-    this.getShowPrintMargin = function() {
-        return this.renderer.getShowPrintMargin();
-    };
-
-    /**
-     * Sets the column defining where the print margin should be.
-     * @param {Number} showPrintMargin Specifies the new print margin
-     *
-     **/
-    this.setPrintMarginColumn = function(showPrintMargin) {
-        this.renderer.setPrintMarginColumn(showPrintMargin);
-    };
-
-    /**
-     * Returns the column number of where the print margin is.
-     * @returns {Number}
-     **/
-    this.getPrintMarginColumn = function() {
-        return this.renderer.getPrintMarginColumn();
-    };
-
-    /**
-     * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.
-     * @param {Boolean} readOnly Specifies whether the editor can be modified or not
-     *
-     **/
-    this.setReadOnly = function(readOnly) {
-        this.setOption("readOnly", readOnly);
-    };
-
-    /**
-     * Returns `true` if the editor is set to read-only mode.
-     * @returns {Boolean}
-     **/
-    this.getReadOnly = function() {
-        return this.getOption("readOnly");
-    };
-
-    /**
-     * Specifies whether to use behaviors or not. ["Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.]{: #BehaviorsDef}
-     * @param {Boolean} enabled Enables or disables behaviors
-     *
-     **/
-    this.setBehavioursEnabled = function (enabled) {
-        this.setOption("behavioursEnabled", enabled);
-    };
-
-    /**
-     * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}
-     *
-     * @returns {Boolean}
-     **/
-    this.getBehavioursEnabled = function () {
-        return this.getOption("behavioursEnabled");
-    };
-
-    /**
-     * Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets
-     * when such a character is typed in.
-     * @param {Boolean} enabled Enables or disables wrapping behaviors
-     *
-     **/
-    this.setWrapBehavioursEnabled = function (enabled) {
-        this.setOption("wrapBehavioursEnabled", enabled);
-    };
-
-    /**
-     * Returns `true` if the wrapping behaviors are currently enabled.
-     **/
-    this.getWrapBehavioursEnabled = function () {
-        return this.getOption("wrapBehavioursEnabled");
-    };
-
-    /**
-     * Indicates whether the fold widgets should be shown or not.
-     * @param {Boolean} show Specifies whether the fold widgets are shown
-     **/
-    this.setShowFoldWidgets = function(show) {
-        this.setOption("showFoldWidgets", show);
-
-    };
-    /**
-     * Returns `true` if the fold widgets are shown.
-     * @return {Boolean}
-     **/
-    this.getShowFoldWidgets = function() {
-        return this.getOption("showFoldWidgets");
-    };
-
-    this.setFadeFoldWidgets = function(fade) {
-        this.setOption("fadeFoldWidgets", fade);
-    };
-
-    this.getFadeFoldWidgets = function() {
-        return this.getOption("fadeFoldWidgets");
-    };
-
-    /**
-     * Removes words of text from the editor. A "word" is defined as a string of characters bookended by whitespace.
-     * @param {String} dir The direction of the deletion to occur, either "left" or "right"
-     *
-     **/
-    this.remove = function(dir) {
-        if (this.selection.isEmpty()){
-            if (dir == "left")
-                this.selection.selectLeft();
-            else
-                this.selection.selectRight();
-        }
-
-        var range = this.getSelectionRange();
-        if (this.getBehavioursEnabled()) {
-            var session = this.session;
-            var state = session.getState(range.start.row);
-            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
-
-            if (range.end.column == 0) {
-                var text = session.getTextRange(range);
-                if (text[text.length - 1] == "\n") {
-                    var line = session.getLine(range.end.row)
-                    if (/^\s+$/.test(line)) {
-                        range.end.column = line.length
-                    }
-                }
-            }
-            if (new_range)
-                range = new_range;
-        }
-
-        this.session.remove(range);
-        this.clearSelection();
-    };
-
-    /**
-     * Removes the word directly to the right of the current selection.
-     **/
-    this.removeWordRight = function() {
-        if (this.selection.isEmpty())
-            this.selection.selectWordRight();
-
-        this.session.remove(this.getSelectionRange());
-        this.clearSelection();
-    };
-
-    /**
-     * Removes the word directly to the left of the current selection.
-     **/
-    this.removeWordLeft = function() {
-        if (this.selection.isEmpty())
-            this.selection.selectWordLeft();
-
-        this.session.remove(this.getSelectionRange());
-        this.clearSelection();
-    };
-
-    /**
-     * Removes all the words to the left of the current selection, until the start of the line.
-     **/
-    this.removeToLineStart = function() {
-        if (this.selection.isEmpty())
-            this.selection.selectLineStart();
-
-        this.session.remove(this.getSelectionRange());
-        this.clearSelection();
-    };
-
-    /**
-     * Removes all the words to the right of the current selection, until the end of the line.
-     **/
-    this.removeToLineEnd = function() {
-        if (this.selection.isEmpty())
-            this.selection.selectLineEnd();
-
-        var range = this.getSelectionRange();
-        if (range.start.column == range.end.column && range.start.row == range.end.row) {
-            range.end.column = 0;
-            range.end.row++;
-        }
-
-        this.session.remove(range);
-        this.clearSelection();
-    };
-
-    /**
-     * Splits the line at the current selection (by inserting an `'\n'`).
-     **/
-    this.splitLine = function() {
-        if (!this.selection.isEmpty()) {
-            this.session.remove(this.getSelectionRange());
-            this.clearSelection();
-        }
-
-        var cursor = this.getCursorPosition();
-        this.insert("\n");
-        this.moveCursorToPosition(cursor);
-    };
-
-    /**
-     * Transposes current line.
-     **/
-    this.transposeLetters = function() {
-        if (!this.selection.isEmpty()) {
-            return;
-        }
-
-        var cursor = this.getCursorPosition();
-        var column = cursor.column;
-        if (column === 0)
-            return;
-
-        var line = this.session.getLine(cursor.row);
-        var swap, range;
-        if (column < line.length) {
-            swap = line.charAt(column) + line.charAt(column-1);
-            range = new Range(cursor.row, column-1, cursor.row, column+1);
-        }
-        else {
-            swap = line.charAt(column-1) + line.charAt(column-2);
-            range = new Range(cursor.row, column-2, cursor.row, column);
-        }
-        this.session.replace(range, swap);
-    };
-
-    /**
-     * Converts the current selection entirely into lowercase.
-     **/
-    this.toLowerCase = function() {
-        var originalRange = this.getSelectionRange();
-        if (this.selection.isEmpty()) {
-            this.selection.selectWord();
-        }
-
-        var range = this.getSelectionRange();
-        var text = this.session.getTextRange(range);
-        this.session.replace(range, text.toLowerCase());
-        this.selection.setSelectionRange(originalRange);
-    };
-
-    /**
-     * Converts the current selection entirely into uppercase.
-     **/
-    this.toUpperCase = function() {
-        var originalRange = this.getSelectionRange();
-        if (this.selection.isEmpty()) {
-            this.selection.selectWord();
-        }
-
-        var range = this.getSelectionRange();
-        var text = this.session.getTextRange(range);
-        this.session.replace(range, text.toUpperCase());
-        this.selection.setSelectionRange(originalRange);
-    };
-
-    /**
-     * Inserts an indentation into the current cursor position or indents the selected lines.
-     *
-     * @related EditSession.indentRows
-     **/
-    this.indent = function() {
-        var session = this.session;
-        var range = this.getSelectionRange();
-
-        if (range.start.row < range.end.row) {
-            var rows = this.$getSelectedRows();
-            session.indentRows(rows.first, rows.last, "\t");
-            return;
-        } else if (range.start.column < range.end.column) {
-            var text = session.getTextRange(range)
-            if (!/^\s+$/.test(text)) {
-                var rows = this.$getSelectedRows();
-                session.indentRows(rows.first, rows.last, "\t");
-                return;
-            }
-        }
-        
-        var line = session.getLine(range.start.row)
-        var position = range.start;
-        var size = session.getTabSize();
-        var column = session.documentToScreenColumn(position.row, position.column);
-
-        if (this.session.getUseSoftTabs()) {
-            var count = (size - column % size);
-            var indentString = lang.stringRepeat(" ", count);
-        } else {
-            var count = column % size;
-            while (line[range.start.column] == " " && count) {
-                range.start.column--;
-                count--;
-            }
-            this.selection.setSelectionRange(range);
-            indentString = "\t";
-        }
-        return this.insert(indentString);
-    };
-
-    /**
-     * Indents the current line.
-     * @related EditSession.indentRows
-     **/
-    this.blockIndent = function() {
-        var rows = this.$getSelectedRows();
-        this.session.indentRows(rows.first, rows.last, "\t");
-    };
-
-    /**
-     * Outdents the current line.
-     * @related EditSession.outdentRows
-     **/
-    this.blockOutdent = function() {
-        var selection = this.session.getSelection();
-        this.session.outdentRows(selection.getRange());
-    };
-
-    // TODO: move out of core when we have good mechanism for managing extensions
-    this.sortLines = function() {
-        var rows = this.$getSelectedRows();
-        var session = this.session;
-
-        var lines = [];
-        for (i = rows.first; i <= rows.last; i++)
-            lines.push(session.getLine(i));
-
-        lines.sort(function(a, b) {
-            if (a.toLowerCase() < b.toLowerCase()) return -1;
-            if (a.toLowerCase() > b.toLowerCase()) return 1;
-            return 0;
-        });
-
-        var deleteRange = new Range(0, 0, 0, 0);
-        for (var i = rows.first; i <= rows.last; i++) {
-            var line = session.getLine(i);
-            deleteRange.start.row = i;
-            deleteRange.end.row = i;
-            deleteRange.end.column = line.length;
-            session.replace(deleteRange, lines[i-rows.first]);
-        }
-    };
-
-    /**
-     * Given the currently selected range, this function either comments all the lines, or uncomments all of them.
-     **/
-    this.toggleCommentLines = function() {
-        var state = this.session.getState(this.getCursorPosition().row);
-        var rows = this.$getSelectedRows();
-        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
-    };
-
-    this.toggleBlockComment = function() {
-        var cursor = this.getCursorPosition();
-        var state = this.session.getState(cursor.row);
-        var range = this.getSelectionRange();
-        this.session.getMode().toggleBlockComment(state, this.session, range, cursor);
-    };
-
-    /**
-     * Works like [[EditSession.getTokenAt]], except it returns a number.
-     * @returns {Number}
-     **/
-    this.getNumberAt = function( row, column ) {
-        var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g
-        _numberRx.lastIndex = 0
-
-        var s = this.session.getLine(row)
-        while (_numberRx.lastIndex < column) {
-            var m = _numberRx.exec(s)
-            if(m.index <= column && m.index+m[0].length >= column){
-                var number = {
-                    value: m[0],
-                    start: m.index,
-                    end: m.index+m[0].length
-                }
-                return number;
-            }
-        }
-        return null;
-    };
-
-    /**
-     * If the character before the cursor is a number, this functions changes its value by `amount`.
-     * @param {Number} amount The value to change the numeral by (can be negative to decrease value)
-     *
-     **/
-    this.modifyNumber = function(amount) {
-        var row = this.selection.getCursor().row;
-        var column = this.selection.getCursor().column;
-
-        // get the char before the cursor
-        var charRange = new Range(row, column-1, row, column);
-
-        var c = this.session.getTextRange(charRange);
-        // if the char is a digit
-        if (!isNaN(parseFloat(c)) && isFinite(c)) {
-            // get the whole number the digit is part of
-            var nr = this.getNumberAt(row, column);
-            // if number found
-            if (nr) {
-                var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end;
-                var decimals = nr.start + nr.value.length - fp;
-
-                var t = parseFloat(nr.value);
-                t *= Math.pow(10, decimals);
-
-
-                if(fp !== nr.end && column < fp){
-                    amount *= Math.pow(10, nr.end - column - 1);
-                } else {
-                    amount *= Math.pow(10, nr.end - column);
-                }
-
-                t += amount;
-                t /= Math.pow(10, decimals);
-                var nnr = t.toFixed(decimals);
-
-                //update number
-                var replaceRange = new Range(row, nr.start, row, nr.end);
-                this.session.replace(replaceRange, nnr);
-
-                //reposition the cursor
-                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));
-
-            }
-        }
-    };
-
-    /**
-     * Removes all the lines in the current selection
-     * @related EditSession.remove
-     **/
-    this.removeLines = function() {
-        var rows = this.$getSelectedRows();
-        var range;
-        if (rows.first === 0 || rows.last+1 < this.session.getLength())
-            range = new Range(rows.first, 0, rows.last+1, 0);
-        else
-            range = new Range(
-                rows.first-1, this.session.getLine(rows.first-1).length,
-                rows.last, this.session.getLine(rows.last).length
-            );
-        this.session.remove(range);
-        this.clearSelection();
-    };
-
-    this.duplicateSelection = function() {
-        var sel = this.selection;
-        var doc = this.session;
-        var range = sel.getRange();
-        var reverse = sel.isBackwards();
-        if (range.isEmpty()) {
-            var row = range.start.row;
-            doc.duplicateLines(row, row);
-        } else {
-            var point = reverse ? range.start : range.end;
-            var endPoint = doc.insert(point, doc.getTextRange(range), false);
-            range.start = point;
-            range.end = endPoint;
-
-            sel.setSelectionRange(range, reverse)
-        }
-    };
-
-    /**
-     * Shifts all the selected lines down one row.
-     *
-     * @returns {Number} On success, it returns -1.
-     * @related EditSession.moveLinesUp
-     **/
-    this.moveLinesDown = function() {
-        this.$moveLines(function(firstRow, lastRow) {
-            return this.session.moveLinesDown(firstRow, lastRow);
-        });
-    };
-
-    /**
-     * Shifts all the selected lines up one row.
-     * @returns {Number} On success, it returns -1.
-     * @related EditSession.moveLinesDown
-     **/
-    this.moveLinesUp = function() {
-        this.$moveLines(function(firstRow, lastRow) {
-            return this.session.moveLinesUp(firstRow, lastRow);
-        });
-    };
-
-    /**
-     * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:
-     * ```json
-     *    { row: newRowLocation, column: newColumnLocation }
-     * ```
-     * @param {Range} fromRange The range of text you want moved within the document
-     * @param {Object} toPosition The location (row and column) where you want to move the text to
-     *
-     * @returns {Range} The new range where the text was moved to.
-     * @related EditSession.moveText
-     **/
-    this.moveText = function(range, toPosition, copy) {
-        return this.session.moveText(range, toPosition, copy);
-    };
-
-    /**
-     * Copies all the selected lines up one row.
-     * @returns {Number} On success, returns 0.
-     *
-     **/
-    this.copyLinesUp = function() {
-        this.$moveLines(function(firstRow, lastRow) {
-            this.session.duplicateLines(firstRow, lastRow);
-            return 0;
-        });
-    };
-
-    /**
-     * Copies all the selected lines down one row.
-     * @returns {Number} On success, returns the number of new rows added; in other words, `lastRow - firstRow + 1`.
-     * @related EditSession.duplicateLines
-     *
-     **/
-    this.copyLinesDown = function() {
-        this.$moveLines(function(firstRow, lastRow) {
-            return this.session.duplicateLines(firstRow, lastRow);
-        });
-    };
-
-    /**
-     * Executes a specific function, which can be anything that manipulates selected lines, such as copying them, duplicating them, or shifting them.
-     * @param {Function} mover A method to call on each selected row
-     *
-     *
-     **/
-    this.$moveLines = function(mover) {
-        var selection = this.selection;
-        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
-            var range = selection.toOrientedRange();
-            var rows = this.$getSelectedRows(range);
-            var linesMoved = mover.call(this, rows.first, rows.last);
-            range.moveBy(linesMoved, 0);
-            selection.fromOrientedRange(range);
-        } else {
-            var ranges = selection.rangeList.ranges;
-            selection.rangeList.detach(this.session);
-
-            for (var i = ranges.length; i--; ) {
-                var rangeIndex = i;
-                var rows = ranges[i].collapseRows();
-                var last = rows.end.row;
-                var first = rows.start.row;
-                while (i--) {
-                    var rows = ranges[i].collapseRows();
-                    if (first - rows.end.row <= 1)
-                        first = rows.end.row;
-                    else
-                        break;
-                }
-                i++;
-
-                var linesMoved = mover.call(this, first, last);
-                while (rangeIndex >= i) {
-                    ranges[rangeIndex].moveBy(linesMoved, 0);
-                    rangeIndex--;
-                }
-            }
-            selection.fromOrientedRange(selection.ranges[0]);
-            selection.rangeList.attach(this.session);
-        }
-    };
-
-    /**
-     * Returns an object indicating the currently selected rows. The object looks like this:
-     *
-     * ```json
-     * { first: range.start.row, last: range.end.row }
-     * ```
-     *
-     * @returns {Object}
-     **/
-    this.$getSelectedRows = function() {
-        var range = this.getSelectionRange().collapseRows();
-
-        return {
-            first: range.start.row,
-            last: range.end.row
-        };
-    };
-
-    this.onCompositionStart = function(text) {
-        this.renderer.showComposition(this.getCursorPosition());
-    };
-
-    this.onCompositionUpdate = function(text) {
-        this.renderer.setCompositionText(text);
-    };
-
-    this.onCompositionEnd = function() {
-        this.renderer.hideComposition();
-    };
-
-    /**
-     * {:VirtualRenderer.getFirstVisibleRow}
-     *
-     * @returns {Number}
-     * @related VirtualRenderer.getFirstVisibleRow
-     **/
-    this.getFirstVisibleRow = function() {
-        return this.renderer.getFirstVisibleRow();
-    };
-
-    /**
-     * {:VirtualRenderer.getLastVisibleRow}
-     *
-     * @returns {Number}
-     * @related VirtualRenderer.getLastVisibleRow
-     **/
-    this.getLastVisibleRow = function() {
-        return this.renderer.getLastVisibleRow();
-    };
-
-    /**
-     * Indicates if the row is currently visible on the screen.
-     * @param {Number} row The row to check
-     *
-     * @returns {Boolean}
-     **/
-    this.isRowVisible = function(row) {
-        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
-    };
-
-    /**
-     * Indicates if the entire row is currently visible on the screen.
-     * @param {Number} row The row to check
-     *
-     *
-     * @returns {Boolean}
-     **/
-    this.isRowFullyVisible = function(row) {
-        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
-    };
-
-    /**
-     * Returns the number of currently visibile rows.
-     * @returns {Number}
-     **/
-    this.$getVisibleRowCount = function() {
-        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
-    };
-
-    this.$moveByPage = function(dir, select) {
-        var renderer = this.renderer;
-        var config = this.renderer.layerConfig;
-        var rows = dir * Math.floor(config.height / config.lineHeight);
-
-        this.$blockScrolling++;
-        if (select == true) {
-            this.selection.$moveSelection(function(){
-                this.moveCursorBy(rows, 0);
-            });
-        } else if (select == false) {
-            this.selection.moveCursorBy(rows, 0);
-            this.selection.clearSelection();
-        }
-        this.$blockScrolling--;
-
-        var scrollTop = renderer.scrollTop;
-
-        renderer.scrollBy(0, rows * config.lineHeight);
-        if (select != null)
-            renderer.scrollCursorIntoView(null, 0.5);
-
-        renderer.animateScrolling(scrollTop);
-    };
-
-    /**
-     * Selects the text from the current position of the document until where a "page down" finishes.
-     **/
-    this.selectPageDown = function() {
-        this.$moveByPage(1, true);
-    };
-
-    /**
-     * Selects the text from the current position of the document until where a "page up" finishes.
-     **/
-    this.selectPageUp = function() {
-        this.$moveByPage(-1, true);
-    };
-
-    /**
-     * Shifts the document to wherever "page down" is, as well as moving the cursor position.
-     **/
-    this.gotoPageDown = function() {
-       this.$moveByPage(1, false);
-    };
-
-    /**
-     * Shifts the document to wherever "page up" is, as well as moving the cursor position.
-     **/
-    this.gotoPageUp = function() {
-        this.$moveByPage(-1, false);
-    };
-
-    /**
-     * Scrolls the document to wherever "page down" is, without changing the cursor position.
-     **/
-    this.scrollPageDown = function() {
-        this.$moveByPage(1);
-    };
-
-    /**
-     * Scrolls the document to wherever "page up" is, without changing the cursor position.
-     **/
-    this.scrollPageUp = function() {
-        this.$moveByPage(-1);
-    };
-
-    /**
-     * Moves the editor to the specified row.
-     * @related VirtualRenderer.scrollToRow
-     **/
-    this.scrollToRow = function(row) {
-        this.renderer.scrollToRow(row);
-    };
-
-    /**
-     * Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).
-     * @param {Number} line The line to scroll to
-     * @param {Boolean} center If `true`
-     * @param {Boolean} animate If `true` animates scrolling
-     * @param {Function} callback Function to be called when the animation has finished
-     *
-     *
-     * @related VirtualRenderer.scrollToLine
-     **/
-    this.scrollToLine = function(line, center, animate, callback) {
-        this.renderer.scrollToLine(line, center, animate, callback);
-    };
-
-    /**
-     * Attempts to center the current selection on the screen.
-     **/
-    this.centerSelection = function() {
-        var range = this.getSelectionRange();
-        var pos = {
-            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
-            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
-        }
-        this.renderer.alignCursor(pos, 0.5);
-    };
-
-    /**
-     * Gets the current position of the cursor.
-     * @returns {Object} An object that looks something like this:
-     *
-     * ```json
-     * { row: currRow, column: currCol }
-     * ```
-     *
-     * @related Selection.getCursor
-     **/
-    this.getCursorPosition = function() {
-        return this.selection.getCursor();
-    };
-
-    /**
-     * Returns the screen position of the cursor.
-     * @returns {Number}
-     * @related EditSession.documentToScreenPosition
-     **/
-    this.getCursorPositionScreen = function() {
-        return this.session.documentToScreenPosition(this.getCursorPosition());
-    };
-
-    /**
-     * {:Selection.getRange}
-     * @returns {Range}
-     * @related Selection.getRange
-     **/
-    this.getSelectionRange = function() {
-        return this.selection.getRange();
-    };
-
-
-    /**
-     * Selects all the text in editor.
-     * @related Selection.selectAll
-     **/
-    this.selectAll = function() {
-        this.$blockScrolling += 1;
-        this.selection.selectAll();
-        this.$blockScrolling -= 1;
-    };
-
-    /**
-     * {:Selection.clearSelection}
-     * @related Selection.clearSelection
-     **/
-    this.clearSelection = function() {
-        this.selection.clearSelection();
-    };
-
-    /**
-     * Moves the cursor to the specified row and column. Note that this does not de-select the current selection.
-     * @param {Number} row The new row number
-     * @param {Number} column The new column number
-     *
-     *
-     * @related Selection.moveCursorTo
-     **/
-    this.moveCursorTo = function(row, column) {
-        this.selection.moveCursorTo(row, column);
-    };
-
-    /**
-     * Moves the cursor to the position indicated by `pos.row` and `pos.column`.
-     * @param {Object} pos An object with two properties, row and column
-     *
-     *
-     * @related Selection.moveCursorToPosition
-     **/
-    this.moveCursorToPosition = function(pos) {
-        this.selection.moveCursorToPosition(pos);
-    };
-
-    /**
-     * Moves the cursor's row and column to the next matching bracket.
-     *
-     **/
-    this.jumpToMatching = function(select) {
-        var cursor = this.getCursorPosition();
-
-        var range = this.session.getBracketRange(cursor);
-        if (!range) {
-            range = this.find({
-                needle: /[{}()\[\]]/g,
-                preventScroll:true,
-                start: {row: cursor.row, column: cursor.column - 1}
-            });
-            if (!range)
-                return;
-            var pos = range.start;
-            if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
-                range = this.session.getBracketRange(pos);
-        }
-
-        pos = range && range.cursor || pos;
-        if (pos) {
-            if (select) {
-                if (range && range.isEqual(this.getSelectionRange()))
-                    this.clearSelection();
-                else
-                    this.selection.selectTo(pos.row, pos.column);
-            } else {
-                this.clearSelection();
-                this.moveCursorTo(pos.row, pos.column);
-            }
-        }
-    };
-
-    /**
-     * Moves the cursor to the specified line number, and also into the indiciated column.
-     * @param {Number} lineNumber The line number to go to
-     * @param {Number} column A column number to go to
-     * @param {Boolean} animate If `true` animates scolling
-     *
-     **/
-    this.gotoLine = function(lineNumber, column, animate) {
-        this.selection.clearSelection();
-        this.session.unfold({row: lineNumber - 1, column: column || 0});
-
-        this.$blockScrolling += 1;
-        // todo: find a way to automatically exit multiselect mode
-        this.exitMultiSelectMode && this.exitMultiSelectMode();
-        this.moveCursorTo(lineNumber - 1, column || 0);
-        this.$blockScrolling -= 1;
-
-        if (!this.isRowFullyVisible(lineNumber - 1))
-            this.scrollToLine(lineNumber - 1, true, animate);
-    };
-
-    /**
-     * Moves the cursor to the specified row and column. Note that this does de-select the current selection.
-     * @param {Number} row The new row number
-     * @param {Number} column The new column number
-     *
-     *
-     * @related Editor.moveCursorTo
-     **/
-    this.navigateTo = function(row, column) {
-        this.clearSelection();
-        this.moveCursorTo(row, column);
-    };
-
-    /**
-     * Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.
-     * @param {Number} times The number of times to change navigation
-     *
-     *
-     **/
-    this.navigateUp = function(times) {
-        if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
-            var selectionStart = this.selection.anchor.getPosition();
-            return this.moveCursorToPosition(selectionStart);
-        }
-        this.selection.clearSelection();
-        times = times || 1;
-        this.selection.moveCursorBy(-times, 0);
-    };
-
-    /**
-     * Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.
-     * @param {Number} times The number of times to change navigation
-     *
-     *
-     **/
-    this.navigateDown = function(times) {
-        if (this.selection.isMultiLine() && this.selection.isBackwards()) {
-            var selectionEnd = this.selection.anchor.getPosition();
-            return this.moveCursorToPosition(selectionEnd);
-        }
-        this.selection.clearSelection();
-        times = times || 1;
-        this.selection.moveCursorBy(times, 0);
-    };
-
-    /**
-     * Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.
-     * @param {Number} times The number of times to change navigation
-     *
-     *
-     **/
-    this.navigateLeft = function(times) {
-        if (!this.selection.isEmpty()) {
-            var selectionStart = this.getSelectionRange().start;
-            this.moveCursorToPosition(selectionStart);
-        }
-        else {
-            times = times || 1;
-            while (times--) {
-                this.selection.moveCursorLeft();
-            }
-        }
-        this.clearSelection();
-    };
-
-    /**
-     * Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.
-     * @param {Number} times The number of times to change navigation
-     *
-     *
-     **/
-    this.navigateRight = function(times) {
-        if (!this.selection.isEmpty()) {
-            var selectionEnd = this.getSelectionRange().end;
-            this.moveCursorToPosition(selectionEnd);
-        }
-        else {
-            times = times || 1;
-            while (times--) {
-                this.selection.moveCursorRight();
-            }
-        }
-        this.clearSelection();
-    };
-
-    /**
-     *
-     * Moves the cursor to the start of the current line. Note that this does de-select the current selection.
-     **/
-    this.navigateLineStart = function() {
-        this.selection.moveCursorLineStart();
-        this.clearSelection();
-    };
-
-    /**
-     *
-     * Moves the cursor to the end of the current line. Note that this does de-select the current selection.
-     **/
-    this.navigateLineEnd = function() {
-        this.selection.moveCursorLineEnd();
-        this.clearSelection();
-    };
-
-    /**
-     *
-     * 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);
-    };
-
-    /**
-     *
-     * 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);
-    };
-
-    /**
-     *
-     * Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.
-     **/
-    this.navigateWordRight = function() {
-        this.selection.moveCursorWordRight();
-        this.clearSelection();
-    };
-
-    /**
-     *
-     * Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.
-     **/
-    this.navigateWordLeft = function() {
-        this.selection.moveCursorWordLeft();
-        this.clearSelection();
-    };
-
-    /**
-     * Replaces the first occurance of `options.needle` with the value in `replacement`.
-     * @param {String} replacement The text to replace with
-     * @param {Object} options The [[Search `Search`]] options to use
-     *
-     *
-     **/
-    this.replace = function(replacement, options) {
-        if (options)
-            this.$search.set(options);
-
-        var range = this.$search.find(this.session);
-        var replaced = 0;
-        if (!range)
-            return replaced;
-
-        if (this.$tryReplace(range, replacement)) {
-            replaced = 1;
-        }
-        if (range !== null) {
-            this.selection.setSelectionRange(range);
-            this.renderer.scrollSelectionIntoView(range.start, range.end);
-        }
-
-        return replaced;
-    };
-
-    /**
-     * Replaces all occurances of `options.needle` with the value in `replacement`.
-     * @param {String} replacement The text to replace with
-     * @param {Object} options The [[Search `Search`]] options to use
-     *
-     *
-     **/
-    this.replaceAll = function(replacement, options) {
-        if (options) {
-            this.$search.set(options);
-        }
-
-        var ranges = this.$search.findAll(this.session);
-        var replaced = 0;
-        if (!ranges.length)
-            return replaced;
-
-        this.$blockScrolling += 1;
-
-        var selection = this.getSelectionRange();
-        this.clearSelection();
-        this.selection.moveCursorTo(0, 0);
-
-        for (var i = ranges.length - 1; i >= 0; --i) {
-            if(this.$tryReplace(ranges[i], replacement)) {
-                replaced++;
-            }
-        }
-
-        this.selection.setSelectionRange(selection);
-        this.$blockScrolling -= 1;
-
-        return replaced;
-    };
-
-    this.$tryReplace = function(range, replacement) {
-        var input = this.session.getTextRange(range);
-        replacement = this.$search.replace(input, replacement);
-        if (replacement !== null) {
-            range.end = this.session.replace(range, replacement);
-            return range;
-        } else {
-            return null;
-        }
-    };
-
-    /**
-     * {:Search.getOptions} For more information on `options`, see [[Search `Search`]].
-     * @related Search.getOptions
-     * @returns {Object}
-     **/
-    this.getLastSearchOptions = function() {
-        return this.$search.getOptions();
-    };
-
-    /**
-     * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].
-     * @param {String} needle The text to search for (optional)
-     * @param {Object} options An object defining various search properties
-     * @param {Boolean} animate If `true` animate scrolling
-     *
-     *
-     * @related Search.find
-     **/
-    this.find = function(needle, options, animate) {
-        if (!options)
-            options = {};
-
-        if (typeof needle == "string" || needle instanceof RegExp)
-            options.needle = needle;
-        else if (typeof needle == "object")
-            oop.mixin(options, needle);
-
-        var range = this.selection.getRange();
-        if (options.needle == null) {
-            needle = this.session.getTextRange(range)
-                || this.$search.$options.needle;
-            if (!needle) {
-                range = this.session.getWordRange(range.start.row, range.start.column);
-                needle = this.session.getTextRange(range);
-            }
-            this.$search.set({needle: needle});
-        }
-
-        this.$search.set(options);
-        if (!options.start)
-            this.$search.set({start: range});
-
-        var newRange = this.$search.find(this.session);
-        if (options.preventScroll)
-            return newRange;
-        if (newRange) {
-            this.revealRange(newRange, animate);
-            return newRange;
-        }
-        // clear selection if nothing is found
-        if (options.backwards)
-            range.start = range.end;
-        else
-            range.end = range.start;
-        this.selection.setRange(range);
-    };
-
-    /**
-     * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].
-     * @param {Object} options search options
-     * @param {Boolean} animate If `true` animate scrolling
-     *
-     *
-     * @related Editor.find
-     **/
-    this.findNext = function(options, animate) {
-        this.find({skipCurrent: true, backwards: false}, options, animate);
-    };
-
-    /**
-     * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].
-     * @param {Object} options search options
-     * @param {Boolean} animate If `true` animate scrolling
-     *
-     *
-     * @related Editor.find
-     **/
-    this.findPrevious = function(options, animate) {
-        this.find(options, {skipCurrent: true, backwards: true}, animate);
-    };
-
-    this.revealRange = function(range, animate) {
-        this.$blockScrolling += 1;
-        this.session.unfold(range);
-        this.selection.setSelectionRange(range);
-        this.$blockScrolling -= 1;
-
-        var scrollTop = this.renderer.scrollTop;
-        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
-        if (animate != false)
-            this.renderer.animateScrolling(scrollTop);
-    };
-
-    /**
-     * {:UndoManager.undo}
-     * @related UndoManager.undo
-     **/
-    this.undo = function() {
-        this.$blockScrolling++;
-        this.session.getUndoManager().undo();
-        this.$blockScrolling--;
-        this.renderer.scrollCursorIntoView(null, 0.5);
-    };
-
-    /**
-     * {:UndoManager.redo}
-     * @related UndoManager.redo
-     **/
-    this.redo = function() {
-        this.$blockScrolling++;
-        this.session.getUndoManager().redo();
-        this.$blockScrolling--;
-        this.renderer.scrollCursorIntoView(null, 0.5);
-    };
-
-    /**
-     *
-     * Cleans up the entire editor.
-     **/
-    this.destroy = function() {
-        this.renderer.destroy();
-        this._emit("destroy", this);
-    };
-
-    /**
-     * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element
-     * @param {Boolean} enable default true
-     **/
-    this.setAutoScrollEditorIntoView = function(enable) {
-        if (enable === false)
-            return;
-        var rect;
-        var self = this;
-        var shouldScroll = false;
-        if (!this.$scrollAnchor)
-            this.$scrollAnchor = document.createElement("div");
-        var scrollAnchor = this.$scrollAnchor;
-        scrollAnchor.style.cssText = "position:absolute";
-        this.container.insertBefore(scrollAnchor, this.container.firstChild);
-        var onChangeSelection = this.on("changeSelection", function() {
-            shouldScroll = true;
-        });
-        // needed to not trigger sync reflow
-        var onBeforeRender = this.renderer.on("beforeRender", function() {
-            if (shouldScroll)
-                rect = self.renderer.container.getBoundingClientRect();
-        });
-        var onAfterRender = this.renderer.on("afterRender", function() {
-            if (shouldScroll && rect && self.isFocused()) {
-                var renderer = self.renderer;
-                var pos = renderer.$cursorLayer.$pixelPos;
-                var config = renderer.layerConfig;
-                var top = pos.top - config.offset;
-                if (pos.top >= 0 && top + rect.top < 0) {
-                    shouldScroll = true;
-                } else if (pos.top < config.height &&
-                    pos.top + rect.top + config.lineHeight > window.innerHeight) {
-                    shouldScroll = false;
-                } else {
-                    shouldScroll = null;
-                }
-                if (shouldScroll != null) {
-                    scrollAnchor.style.top = top + "px";
-                    scrollAnchor.style.left = pos.left + "px";
-                    scrollAnchor.style.height = config.lineHeight + "px";
-                    scrollAnchor.scrollIntoView(shouldScroll);
-                }
-                shouldScroll = rect = null;
-            }
-        });
-        this.setAutoScrollEditorIntoView = function(enable) {
-            if (enable === true)
-                return;
-            delete this.setAutoScrollEditorIntoView;
-            this.removeEventListener("changeSelection", onChangeSelection);
-            this.renderer.removeEventListener("afterRender", onAfterRender);
-            this.renderer.removeEventListener("beforeRender", onBeforeRender);
-        };
-    };
-
-
-    this.$resetCursorStyle = function() {
-        var style = this.$cursorStyle || "ace";
-        var cursorLayer = this.renderer.$cursorLayer;
-        if (!cursorLayer)
-            return;
-        cursorLayer.setSmoothBlinking(style == "smooth");
-        cursorLayer.isBlinking = !this.$readOnly && style != "wide";
-    };
-
-}).call(Editor.prototype);
-
-
-
-config.defineOptions(Editor.prototype, "editor", {
-    selectionStyle: {
-        set: function(style) {
-            this.onSelectionChange();
-            this._emit("changeSelectionStyle", {data: style});
-        },
-        initialValue: "line"
-    },
-    highlightActiveLine: {
-        set: function() {this.$updateHighlightActiveLine();},
-        initialValue: true
-    },
-    highlightSelectedWord: {
-        set: function(shouldHighlight) {this.$onSelectionChange();},
-        initialValue: true
-    },
-    readOnly: {
-        set: function(readOnly) {
-            this.textInput.setReadOnly(readOnly); 
-            this.$resetCursorStyle(); 
-        },
-        initialValue: false
-    },
-    cursorStyle: {
-        set: function(val) { this.$resetCursorStyle(); },
-        values: ["ace", "slim", "smooth", "wide"],
-        initialValue: "ace"
-    },
-    mergeUndoDeltas: {
-        values: [false, true, "always"],
-        initialValue: true
-    },
-    behavioursEnabled: {initialValue: true},
-    wrapBehavioursEnabled: {initialValue: true},
-
-    hScrollBarAlwaysVisible: "renderer",
-    vScrollBarAlwaysVisible: "renderer",
-    highlightGutterLine: "renderer",
-    animatedScroll: "renderer",
-    showInvisibles: "renderer",
-    showPrintMargin: "renderer",
-    printMarginColumn: "renderer",
-    printMargin: "renderer",
-    fadeFoldWidgets: "renderer",
-    showFoldWidgets: "renderer",
-    showGutter: "renderer",
-    displayIndentGuides: "renderer",
-    fontSize: "renderer",
-    fontFamily: "renderer",
-    maxLines: "renderer",
-    minLines: "renderer",
-    scrollPastEnd: "renderer",
-    fixedWidthGutter: "renderer",
-
-    scrollSpeed: "$mouseHandler",
-    dragDelay: "$mouseHandler",
-    dragEnabled: "$mouseHandler",
-    focusTimout: "$mouseHandler",
-
-    firstLineNumber: "session",
-    overwrite: "session",
-    newLineMode: "session",
-    useWorker: "session",
-    useSoftTabs: "session",
-    tabSize: "session",
-    wrap: "session",
-    foldStyle: "session"
-});
-
-exports.Editor = Editor;
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/5b8fb9c3/src/fauxton/assets/js/libs/ace/editor_change_document_test.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/editor_change_document_test.js b/src/fauxton/assets/js/libs/ace/editor_change_document_test.js
deleted file mode 100644
index a1fdaad..0000000
--- a/src/fauxton/assets/js/libs/ace/editor_change_document_test.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/* ***** 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 ***** */
-
-if (typeof process !== "undefined") {
-    require("amd-loader");
-    require("./test/mockdom");
-}
-
-define(function(require, exports, module) {
-"use strict";
-
-var EditSession = require("./edit_session").EditSession;
-var Editor = require("./editor").Editor;
-var Text = require("./mode/text").Mode;
-var JavaScriptMode = require("./mode/javascript").Mode;
-var CssMode = require("./mode/css").Mode;
-var HtmlMode = require("./mode/html").Mode;
-var MockRenderer = require("./test/mockrenderer").MockRenderer;
-var assert = require("./test/assertions");
-
-module.exports = {
-
-    setUp : function(next) {
-        this.session1 = new EditSession(["abc", "def"]);
-        this.session2 = new EditSession(["ghi", "jkl"]);
-        
-        
-        this.editor = new Editor(new MockRenderer());
-        next();
-    },
-
-    "test: change document" : function() {
-        this.editor.setSession(this.session1);
-        assert.equal(this.editor.getSession(), this.session1);
-
-        this.editor.setSession(this.session2);
-        assert.equal(this.editor.getSession(), this.session2);
-    },
-
-    "test: only changes to the new document should have effect" : function() {
-        var called = false;
-        this.editor.onDocumentChange = function() {
-            called = true;
-        };
-
-        this.editor.setSession(this.session1);
-        this.editor.setSession(this.session2);
-
-        this.session1.duplicateLines(0, 0);
-        assert.notOk(called);
-
-        this.session2.duplicateLines(0, 0);
-        assert.ok(called);
-    },
-
-    "test: should use cursor of new document" : function() {
-        this.session1.getSelection().moveCursorTo(0, 1);
-        this.session2.getSelection().moveCursorTo(1, 0);
-
-        this.editor.setSession(this.session1);
-        assert.position(this.editor.getCursorPosition(), 0, 1);
-
-        this.editor.setSession(this.session2);
-        assert.position(this.editor.getCursorPosition(), 1, 0);
-    },
-
-    "test: only changing the cursor of the new doc should not have an effect" : function() {
-        this.editor.onCursorChange = function() {
-            called = true;
-        };
-
-        this.editor.setSession(this.session1);
-        this.editor.setSession(this.session2);
-        assert.position(this.editor.getCursorPosition(), 0, 0);
-
-        var called = false;
-        this.session1.getSelection().moveCursorTo(0, 1);
-        assert.position(this.editor.getCursorPosition(), 0, 0);
-        assert.notOk(called);
-
-        this.session2.getSelection().moveCursorTo(1, 1);
-        assert.position(this.editor.getCursorPosition(), 1, 1);
-        assert.ok(called);
-    },
-
-    "test: should use selection of new document" : function() {
-        this.session1.getSelection().selectTo(0, 1);
-        this.session2.getSelection().selectTo(1, 0);
-
-        this.editor.setSession(this.session1);
-        assert.position(this.editor.getSelection().getSelectionLead(), 0, 1);
-
-        this.editor.setSession(this.session2);
-        assert.position(this.editor.getSelection().getSelectionLead(), 1, 0);
-    },
-
-    "test: only changing the selection of the new doc should not have an effect" : function() {
-        this.editor.onSelectionChange = function() {
-            called = true;
-        };
-
-        this.editor.setSession(this.session1);
-        this.editor.setSession(this.session2);
-        assert.position(this.editor.getSelection().getSelectionLead(), 0, 0);
-
-        var called = false;
-        this.session1.getSelection().selectTo(0, 1);
-        assert.position(this.editor.getSelection().getSelectionLead(), 0, 0);
-        assert.notOk(called);
-
-        this.session2.getSelection().selectTo(1, 1);
-        assert.position(this.editor.getSelection().getSelectionLead(), 1, 1);
-        assert.ok(called);
-    },
-
-    "test: should use mode of new document" : function() {
-        this.editor.onChangeMode = function() {
-            called = true;
-        };
-        this.editor.setSession(this.session1);
-        this.editor.setSession(this.session2);
-
-        var called = false;
-        this.session1.setMode(new Text());
-        assert.notOk(called);
-
-        this.session2.setMode(new JavaScriptMode());
-        assert.ok(called);
-    },
-    
-    "test: should use stop worker of old document" : function(next) {
-        var self = this;
-        
-        // 1. Open an editor and set the session to CssMode
-        self.editor.setSession(self.session1);
-        self.session1.setMode(new CssMode());
-        
-        // 2. Add a line or two of valid CSS.
-        self.session1.setValue("DIV { color: red; }");
-        
-        // 3. Clear the session value.
-        self.session1.setValue("");
-        
-        // 4. Set the session to HtmlMode
-        self.session1.setMode(new HtmlMode());
-
-        // 5. Try to type valid HTML
-        self.session1.insert({row: 0, column: 0}, "<html></html>");
-        
-        setTimeout(function() {
-            assert.equal(Object.keys(self.session1.getAnnotations()).length, 0);
-            next();
-        }, 600);
-    }
-};
-
-});
-
-if (typeof module !== "undefined" && module === require.main) {
-    require("asyncjs").test.testcase(module.exports).exec()
-}