Overleaf fileswitcher

Custom hotkeys for switching between files on overleaf.com

目前為 2019-07-03 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==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));