diff --git a/lib/ace/commands/occur_commands.js b/lib/ace/commands/occur_commands.js index b8669203..1d4a97ec 100644 --- a/lib/ace/commands/occur_commands.js +++ b/lib/ace/commands/occur_commands.js @@ -37,16 +37,8 @@ var config = require("../config"), var occurStartCommands = [{ name: "occur", exec: function(editor, options) { - if (!options.needle) return; - var pos = editor.getCursorPosition(); - var handler = new OccurKeyboardHandler(); - editor.keyBinding.addKeyboardHandler(handler); - editor.commands.addCommands(occurCommands); - editor.setReadOnly(true); - var occur = new Occur(); - occur.display(editor.session, options); - pos = occur.originalToOccurPosition(editor.session, pos); - editor.moveCursorToPosition(pos); + var occurSessionActive = new Occur().enter(editor, options); + if (occurSessionActive) OccurKeyboardHandler.installIn(editor); }, readOnly: true }]; @@ -55,26 +47,20 @@ var occurCommands = [{ name: "occurexit", bindKey: 'esc|Ctrl-G', exec: function(editor) { - // if (!options.needle) return; - var session = editor.session, occur = session.doc.$occur; - if (occur) occur.displayOriginal(session); - editor.commands.removeCommands(occurCommands); - editor.setReadOnly(false); - var handler = editor.getKeyboardHandler(); - if (handler.isOccurHandler) editor.keyBinding.removeKeyboardHandler(handler); + var occur = editor.session.getDocument().$occur; + if (!occur) return; + occur.exit(editor, {}); + OccurKeyboardHandler.uninstallFrom(editor); }, readOnly: true }, { name: "occuraccept", bindKey: 'enter', exec: function(editor) { - var occur = editor.session.doc.$occur, - pos = editor.getCursorPosition(); - if (occur) { - pos = occur.occurToOriginalPosition(editor.session, pos); - } - editor.commands.byName.occurexit.exec(editor); - editor.moveCursorToPosition(pos); + var occur = editor.session.getDocument().$occur; + if (!occur) return; + occur.exit(editor, {translatePosition: true}); + OccurKeyboardHandler.uninstallFrom(editor); }, readOnly: true }]; @@ -82,6 +68,7 @@ var occurCommands = [{ var HashHandler = require("../keyboard/hash_handler").HashHandler; var oop = require("../lib/oop"); + function OccurKeyboardHandler() {} oop.inherits(OccurKeyboardHandler, HashHandler); @@ -95,8 +82,6 @@ oop.inherits(OccurKeyboardHandler, HashHandler); this.$editor = editor; } - this.detach = function() {} - var handleKeyboard$super = this.handleKeyboard; this.handleKeyboard = function(data, hashId, key, keyCode) { var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode); @@ -105,6 +90,18 @@ oop.inherits(OccurKeyboardHandler, HashHandler); }).call(OccurKeyboardHandler.prototype); +OccurKeyboardHandler.installIn = function(editor) { + var handler = new this(); + editor.keyBinding.addKeyboardHandler(handler); + editor.commands.addCommands(occurCommands); +} + +OccurKeyboardHandler.uninstallFrom = function(editor) { + editor.commands.removeCommands(occurCommands); + var handler = editor.getKeyboardHandler(); + if (handler.isOccurHandler) editor.keyBinding.removeKeyboardHandler(handler); +} + exports.commands = occurStartCommands; }); diff --git a/lib/ace/occur.js b/lib/ace/occur.js index 6ab695dd..6b7b0558 100644 --- a/lib/ace/occur.js +++ b/lib/ace/occur.js @@ -39,8 +39,9 @@ var Document = require("./document").Document; /** * @class Occur * - * Finds all lines matching a search term in the current docuement and - * displays them instead of the original document. + * Finds all lines matching a search term in the current [[Document + * `Document`]] and displays them instead of the original `Document`. Keeps + * track of the mapping between the occur doc and the original doc. * **/ @@ -52,15 +53,52 @@ var Document = require("./document").Document; * * @constructor **/ -function Occur() { - // this.$options = {wrap: false, skipCurrent: false}; - // this.$keyboardHandler = new ISearchKbd(this); -} +function Occur() {} oop.inherits(Occur, Search); (function() { + /** + * Enables occur mode. expects that `options.needle` is a search term. + * This search term is used to filter out all the lines that include it + * and these are then used as the content of a new [[Document + * `Document`]]. The current cursor position of editor will be translated + * so that the cursor is on the matching row/column as it was before. + * @param {Editor} editor + * @param {Object} options options.needle should be a String + * @return {Boolean} Whether occur activation was successful + * + **/ + this.enter = function(editor, options) { + if (!options.needle) return false; + var pos = editor.getCursorPosition(); + editor.setReadOnly(true); + this.display(editor.session, options); + var translatedPos = this.originalToOccurPosition(editor.session, pos); + editor.moveCursorToPosition(translatedPos); + return true; + } + + /** + * Disables occur mode. Resets the [[Sessions `EditSession`]] [[Document + * `Document`]] back to the original doc. If options.translatePosition is + * truthy also maps the [[Editors `Editor`]] cursor position accordingly. + * @param {Editor} editor + * @param {Object} options options.translatePosition + * @return {Boolean} Whether occur deactivation was successful + * + **/ + this.exit = function(editor, options) { + var session = editor.session, + pos = options.translatePosition && editor.getCursorPosition(), + translatedPos = pos && this.occurToOriginalPosition(editor.session, pos); + this.displayOriginal(session); + editor.setReadOnly(false); + if (translatedPos) editor.moveCursorToPosition(translatedPos); + return true; + } + this.display = function(session, options) { this.$originalDoc = session.doc; var found = this.matchingLines(session, options),