Greasy Fork

Overleaf fileswitcher

Custom hotkeys for switching between files on overleaf.com

目前为 2019-07-03 提交的版本。查看 最新版本

// ==UserScript==
// @name         Overleaf fileswitcher
// @namespace    http://tampermonkey.net/
// @version      1.1
// @license      apache2
// @description  Custom hotkeys for switching between files on overleaf.com
// @author       Aditya Sriram
// @match        https://www.overleaf.com/project/*
// @grant        none
// @require      http://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js
// @require      http://cdnjs.cloudflare.com/ajax/libs/mousetrap/1.6.1/mousetrap.min.js
// @require      http://cdnjs.cloudflare.com/ajax/libs/mousetrap/1.6.1/plugins/global-bind/mousetrap-global-bind.min.js
// ==/UserScript==

(function($, undefined) {
    var allow_ext = ['tex', 'bib'];
    var editor;

    var shortcuts = {};

    function keybindg(key, desc, func) {
        shortcuts[key] = desc;
        Mousetrap.bindGlobal(key, function() {
            console.log("triggered " + key);
            func();
        });
    }

    function getfilename(i,e) {
        if (typeof(e) === "undefined") e = i;
        return $(e).find('span.ng-binding').eq(0).text().trim();
    }

    function match_ext(i, f) {
        var fname = getfilename(f);
        for (var ext of allow_ext) {
            if (fname.endsWith(ext))
                return true;
        }
        return false;
    }

    function switchFile(n) {
        var files = $('file-entity:not(:has(div[ng-controller]))');
        files = files.filter(match_ext);

        var idx = files.index(files.filter(':has(.selected)'));
        if (idx < 0) {
            idx = 0;
            console.log('no filtered file selected, falling back to first file');
        }

        var newidx = idx+n;
        if (newidx >= files.length) newidx = 0;
        if (newidx < 0) newidx = files.length-1;

        var newfile = files.eq(newidx);
        newfile.find('li').click(); // click li to focus file

        var filename = getfilename(newfile); // get file name
        var parents = newfile.parents('file-entity');
        var filepath = parents.map(getfilename).get().reverse();
        //filename = filename.replace(/RenameDelete/g, "");

        if ($('#monkey-filename').length == 0) { // add file name display if it doesn't already exist
            $('span.name.ng-binding').parent().after('<span id="monkey-filename" style="color:white;"></span>');
        }
        $('#monkey-filename').text("/" + filepath.concat(filename).join("/"));
    }

    function encloser(cmd) {
        var fn = function(editor) {
            var selection = editor.getSelection();
            if (selection.isEmpty()) {
                editor.insert("\\" + cmd + "{}");
                return editor.navigateLeft(1);
            }
            var text = editor.getCopyText();
            return editor.insert("\\" + cmd + "{" + text + "}");
        }
        return fn;
    }

    function init() {
        console.log("activating custom overleaf hotkeys...");
        editor = ace.edit($('.ace-editor-body')[0]);
        console.log(editor);
        editor.commands.byName['italics'].exec = encloser('emph');
        keybindg('ctrl+shift+pageup', 'Previous File', function() {switchFile(-1);});
        keybindg('ctrl+shift+pagedown', 'Next File', function() {switchFile(+1);});
        keybindg('ctrl+shift+,', 'Previous File', function() {switchFile(-1);});
        keybindg('ctrl+shift+.', 'Next File', function() {switchFile(1);});
        //keybindg('ctrl+shift+/', 'Past File', function() {console.log("past");});
        console.log('hotkeys:', JSON.parse(JSON.stringify(shortcuts)));
    }

    function wait_for_var(varname, callback) {
        //console.log("checking for " + varname);
        if (typeof(window[varname]) != 'undefined') {
            console.log("found " + varname, window[varname]);
            console.log("initiating callback");
            callback();
        } else {
            //console.log("didn't find " + varname + ". will check again");
            window.setTimeout(wait_for_var, 500, varname, callback);
        }
    }

    $(document).ready(function() {
        wait_for_var('_debug_editors', init);
    });

})(window.jQuery.noConflict(true));