ソフトウェアエンジニアの日常の雑記

日々思ったことをまとめます

komodo-editでダブルクリックでハイライトさせるソース

komodo-editでダブルクリックして指定したワードをハイライトさせるマクロ。これはとても便利なので、メモ。リンク先のサイトがなくなると嫌なので、コピーもはっておく。中身はみてませんw

/**
 * Copyright (c) 2009 Stan Angeloff http://blog.angeloff.name
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

if (typeof (extensions) === 'undefined')
        window.extensions = {};

(function() {

        const Cc = Components.classes;
        const Ci = Components.interfaces;

        // Get a reference to the script namespace
        var $self = extensions.findWordUnderCursor ||
                                (extensions.findWordUnderCursor = { events: {} });

        // Clean-up after previous execution
        if ($self.onViewClosed)
                window.removeEventListener('view_closed', $self.onViewClosed, false);
        if ($self.onViewOpened)
                window.removeEventListener('view_opened', $self.onViewOpened, false);
        if ($self.destroyAll)
                $self.destroyAll();

        $self.isSupportedView = function(view) {

                return (view && view.getAttribute('type') === 'editor');
        };

        $self.onViewOpened = function(e) {

                var view = e.originalTarget;

                if ($self.isSupportedView(view))
                        $self.apply(view);
        };

        $self.onViewClosed = function(e) {

                var view = e.originalTarget;

                if ($self.isSupportedView(view))
                        $self.destroy(view);
        };

        $self.destroy = function(view) {

                if (view.uid in $self.events) {

                        view.removeEventListener('mouseup', $self.events[view.uid], false);

                        delete $self.events[view.uid];
                }
        };

        $self.apply = function(view) {

                var fn = function(e) {

                        if (e.which === 1 &&
                                //e.altKey &&
                                ! (e.ctrlKey || e.metaKey || e.shiftKey) &&
                                ! (view.scimoz._startDragDrop || view.scimoz._inDragDrop)) {

                                e.stopPropagation();
                                e.preventDefault();

                                $self.jumpToSearch(view);
                        }
                };

                //view.addEventListener('mouseup', fn, false);
                dblclick:view.addEventListener('dblclick', fn, false);

                $self.events[view.uid] = fn;
        };

        window.addEventListener('view_opened', $self.onViewOpened, false);
        window.addEventListener('view_closed', $self.onViewClosed, false);

        $self.forEach = function(fn) {

                var viewsByType = ko.views.manager.topView.getViewsByType(true, 'editor'),
                        view;

                for (var i = 0; i < viewsByType.length; i ++) {

                        view = viewsByType[i];

                        if ($self.isSupportedView(view))
                                fn.apply($self, [view]);
                }
        };

        $self.applyToAll = function() { $self.forEach($self.apply); };
        $self.destroyAll = function() { $self.forEach($self.destroy); };

        $self.jumpToSearch = function(view) {

                var findSvc = Cc['@activestate.com/koFindService;1'].getService(Ci.koIFindService);

                var backupPatternType = findSvc.options.patternType;
                        backupCaseSensitivity = findSvc.options.caseSensitivity;
                        backupSearchBackward = findSvc.options.searchBackward;
                        backupMatchWord = findSvc.options.matchWord;

                try {

                        view.scimoz.beginUndoAction();

                        var searchQuery = null;

                        if (view.scimoz.anchor === view.scimoz.currentPos) {

                                var editorPosition = view.scimoz.currentPos,
                                        rangeStart, rangeEnd,
                                        searchRegExp = /^[\w\-\_\.\$]*$/;

                                for (rangeStart = editorPosition;
                                         rangeStart > 0 &&
                                         searchRegExp.test(view.scimoz.getTextRange(rangeStart - 1, editorPosition));
                                         rangeStart --);

                                for (rangeEnd = editorPosition;
                                         rangeEnd < view.scimoz.length &&
                                         searchRegExp.test(view.scimoz.getTextRange(rangeStart, rangeEnd + 1));
                                         rangeEnd ++);

                                if (rangeStart < editorPosition ||
                                        rangeEnd > editorPosition) {

                                        var rangeText = view.scimoz.getTextRange(rangeStart, rangeEnd);

                                        rangeText = rangeText.replace(/^[\-\_\.]+|[\-\_\.]+$/g, '');

                                        if (searchRegExp.test(rangeText)) {

                                                searchQuery = rangeText;
                                                view.scimoz.anchor = view.scimoz.currentPos = rangeStart;
                                        }
                                }

                        } else {

                                searchQuery = view.scimoz.selText;
                                view.scimoz.anchor = view.scimoz.currentPos = Math.min(view.scimoz.anchor, view.scimoz.currentPos);
                        }

                        if (searchQuery && searchQuery.length) {

                                var context = Cc['@activestate.com/koFindContext;1'].createInstance(Ci.koIFindContext);

                                context.type = Ci.koIFindContext.FCT_CURRENT_DOC;

                                findSvc.options.patternType = Ci.koIFindOptions.FOT_SIMPLE;
                                findSvc.options.caseSensitivity = Ci.koIFindOptions.FOC_INSENSITIVE;
                                findSvc.options.searchBackward = false;
                                findSvc.options.matchWord = false;

                                var wasVisible = ko.uilayout.outputPaneShown();

                                Find_FindAll(window, context, searchQuery);
                                Find_FindNext(window, context, searchQuery, 'find', true, false);

                                if ( ! wasVisible && ko.uilayout.outputPaneShown())
                                        ko.uilayout.toggleSplitter('cmd_viewBottomPane');

                                StatusBar_AddMessage('Find Word under Cursor: ' + searchQuery, 'findwordundercursor', 2500, true);

                        } else
                                StatusBar_AddMessage('Find Word under Cursor: did not match a word', 'findwordundercursor', 1500, true);

                } catch (exception) {

                        ko.dialogs.alert('Whoops! Find Word under Cursor encountered an exception:', exception);

                        throw exception;

                } finally {

                        view.scimoz.endUndoAction();

                        findSvc.options.patternType = backupPatternType;
                        findSvc.options.caseSensitivity = backupCaseSensitivity;
                        findSvc.options.searchBackward = backupSearchBackward;
                        findSvc.options.matchWord = backupMatchWord;
                }
        };

        $self.applyToAll();
})();