From 887aa24cebd4f3e2c19492e529e673a98420947a Mon Sep 17 00:00:00 2001 From: Robert Krahn Date: Sun, 17 Mar 2013 01:42:49 -0700 Subject: [PATCH] [occur] starting with simple occur functionality --- lib/ace/commands/occur_commands.js | 93 +++++++++++++++++++++++++++++ lib/ace/occur.js | 96 ++++++++++++++++++++++++++++++ lib/ace/occur_test.js | 95 +++++++++++++++++++++++++++++ lib/ace/test/all_browser.js | 1 + lib/ace/test/asyncjs/assert.js | 4 +- 5 files changed, 287 insertions(+), 2 deletions(-) create mode 100644 lib/ace/commands/occur_commands.js create mode 100644 lib/ace/occur.js create mode 100644 lib/ace/occur_test.js diff --git a/lib/ace/commands/occur_commands.js b/lib/ace/commands/occur_commands.js new file mode 100644 index 00000000..cf332133 --- /dev/null +++ b/lib/ace/commands/occur_commands.js @@ -0,0 +1,93 @@ +/* ***** 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) { + +var config = require("../config"), + Occur = require("../occur").Occur; + +// These commands can be installed in a normal command handler to start occur: +exports.occurStartCommands = [{ + name: "occur", + exec: function(editor, options) { + if (!options.needle) return; + var handler = new OccurKeyboardHandler(); + editor.keyBinding.addKeyboardHandler(handler); + editor.commands.addCommands(exports.occurCommands); + var occur = new Occur(); + occur.display(editor.session, options); + }, + readOnly: true +}]; + +exports.occurCommands = [{ + name: "occurexit", + exec: function(editor) { + // if (!options.needle) return; + var session = editor.session, occur = session.doc.$occur; + if (occur) occur.displayOriginal(session); + editor.commands.removeCommands(exports.occurCommands); + var handler = editor.getKeyboardHandler(); + if (handler.isOccurHandler) editor.keyBinding.removeKeyboardHandler(handler); + }, + readOnly: true +}]; + +var HashHandler = require("../keyboard/hash_handler").HashHandler; +var oop = require("../lib/oop"); + +function OccurKeyboardHandler() {} + +oop.inherits(OccurKeyboardHandler, HashHandler); + +;(function() { + + this.isOccurHandler = true; + + this.attach = function(editor) { + HashHandler.call(this, exports.iSearchCommands, editor.commands.platform); + this.$editor = editor; + } + + this.detach = function(editor) { + } + + var handleKeyboard$super = this.handleKeyboard; + this.handleKeyboard = function(data, hashId, key, keyCode) { + var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode); + return (cmd && cmd.command) ? cmd : {command: "null"}; + } + +}).call(OccurKeyboardHandler.prototype); + + +exports.OccurKeyboardHandler = OccurKeyboardHandler; + +}); diff --git a/lib/ace/occur.js b/lib/ace/occur.js new file mode 100644 index 00000000..56f07713 --- /dev/null +++ b/lib/ace/occur.js @@ -0,0 +1,96 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var Range = require("./range").Range; +var Search = require("./search").Search; +var Document = require("./document").Document; +var iSearchCommandModule = require("./commands/incremental_search_commands"); +var ISearchKbd = iSearchCommandModule.IncrementalSearchKeyboardHandler; + +/** + * @class Occur + * + * Finds all lines matching a search term in the current docuement and + * displays them instead of the original document. + * + **/ + + +/** + * + * + * Creates a new `Occur` object. + * + * @constructor + **/ +function Occur() { + // this.$options = {wrap: false, skipCurrent: false}; + // this.$keyboardHandler = new ISearchKbd(this); +} + +oop.inherits(Occur, Search); + +(function() { + + this.display = function(session, options) { + this.$originalDoc = session.doc; + var found = this.matchingLines(session, options), + lines = found.map(function(foundLine) { return foundLine.content; }), + occurDoc = new Document(lines); + occurDoc.$occur = this; + session.setDocument(occurDoc); + } + + this.displayOriginal = function(session) { + session.setDocument(this.$originalDoc); + } + + this.matchingLines = function(session, options) { + options = options || {}; + if (!session || !options.needle) return []; + var search = new Search(); + search.set(options); + var ranges = search.findAll(session); + return ranges.map(function(range) { + var row = range.start.row; + return {row: row, content: session.getLine(row)}; + }); + } + +}).call(Occur.prototype); + + +exports.Occur = Occur; + +}); diff --git a/lib/ace/occur_test.js b/lib/ace/occur_test.js new file mode 100644 index 00000000..ab92e8be --- /dev/null +++ b/lib/ace/occur_test.js @@ -0,0 +1,95 @@ +/* ***** 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"); +} + +define(function(require, exports, module) { +"use strict"; + +var EditSession = require("./edit_session").EditSession; +var Editor = require("./editor").Editor; +var MockRenderer = require("./test/mockrenderer").MockRenderer; +var Range = require("./range").Range; +var assert = require("./test/assertions"); +var Occur = require("./occur").Occur; +var occurCommands = require("./commands/occur_commands"); +// var OccurKeyboardHandler = occurCommands.OccurKeyboardHandler; + +var editor, occur, session; + +module.exports = { + + name: "ACE occur.js", + + setUp: function() { + session = new EditSession(''); + editor = new Editor(new MockRenderer(), session); + occur = new Occur(); + }, + + "test: find lines matching" : function() { + session.doc.insertLines(0, ['abc', 'def', 'xyz', 'bcx']); + var result = occur.matchingLines(session, {needle: 'bc'}), + expected = [{row: 0, content: 'abc'}, {row: 3, content: 'bcx'}]; + assert.deepEqual(result, expected); + }, + + "test: display occurrences" : function() { + var lines = ['abc', 'def', 'xyz', 'bcx']; + session.doc.insertLines(0, lines); + occur.display(session, {needle: 'bc'}); + assert.equal(session.getValue(), 'abc\nbcx'); + occur.displayOriginal(session); + assert.equal(session.getValue(), lines.join('\n') + '\n'); + }, + + "test: occur command" : function() { + var lines = ['hel', 'lo', '', 'wo', 'rld']; + session.doc.insertLines(0, lines); + editor.commands.addCommands(occurCommands.occurStartCommands); + editor.execCommand('occur', {needle: 'o'}); + assert.equal(session.getValue(), 'lo\nwo'); + assert.ok(editor.getKeyboardHandler().isOccurHandler, 'no occur handler installed'); + assert.ok(editor.commands.byName.occurexit, 'no exitoccur command installed'); + editor.execCommand('occurexit'); + assert.ok(!editor.getKeyboardHandler().isOccurHandler, 'occur handler installed after detach'); + assert.ok(!editor.commands.byName.occurexit, 'exitoccur installed after exiting occur'); + assert.equal(session.getValue(), lines.join('\n') + '\n'); + } + +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/test/all_browser.js b/lib/ace/test/all_browser.js index 9a274329..29527221 100644 --- a/lib/ace/test/all_browser.js +++ b/lib/ace/test/all_browser.js @@ -42,6 +42,7 @@ var testNames = [ "ace/mode/folding/xml_test", "ace/mode/folding/coffee_test", "ace/multi_select_test", + "ace/occur_test", "ace/range_test", "ace/range_list_test", "ace/search_test", diff --git a/lib/ace/test/asyncjs/assert.js b/lib/ace/test/asyncjs/assert.js index 6cdc611a..96e3f6e2 100644 --- a/lib/ace/test/asyncjs/assert.js +++ b/lib/ace/test/asyncjs/assert.js @@ -1,5 +1,5 @@ define(function(require, exports, module) { - + // http://wiki.commonjs.org/wiki/Unit_Testing/1.0 // // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! @@ -141,7 +141,7 @@ function _deepEqual(actual, expected) { if (actual === expected) { return true; - } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { + } else if (typeof Buffer !== "undefined" && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { if (actual.length != expected.length) return false; for (var i = 0; i < actual.length; i++) {