Greasy Fork

Greasy Fork is available in English.

Overleaf Editor Custom VIM Keybindings (Code Mirror v6)

Configure a list of shortcuts for Vim-mode + user-defined :commands for toggling panels on Overleaf.

当前为 2023-03-03 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Overleaf Editor Custom VIM Keybindings (Code Mirror v6)
// @namespace    http://tampermonkey.net/
// @version      0.0.4.1
// @match        https://www.overleaf.com/project/*
// @grant        none
// @description  Configure a list of shortcuts for Vim-mode + user-defined :commands for toggling panels on Overleaf.
// @license MIT
// ==/UserScript==

(function() {
    'use strict';
    // Interact with Writefull suggestion card.
    setTimeout(function(){
        var card;
        var editor = window.editor
        // Use ESC to dismiss the suggestion card
        $(document).keyup(function(event){
            switch(event.keyCode) {
                case 27:
                    esc()
                case 96:
                    esc()
            }
        });
        function esc(){
            card = $('.writefull-suggest-card');
            if(card.css("display")=='flex'){
                card.css("display",'none')
                // Restore the focus back to ACE editor
                editor.focus() // side-effect - a side box is drawn
            }
        };
        // work in progress: use 1,2 to accept/reject; 3,4 for accept/reject all.
        var DA = {48:-1,49:0,50:1,51:2};
        $(document).keypress(function(e){
            if(e.which>47 && e.which < 52){
                card = $('.writefull-suggest-card');
                if(card.css("display")=='flex'){
                    console.log(DA[e.which])
                    card.find('li.replacement').eq(DA[e.which])[0].click();
                    editor.focus() // side-effect - a side box is drawn
                }
            }
        });

    },2000);

    window.addEventListener("UNSTABLE_editor:extensions", (event) => {
        const { CodeMirror, CodeMirrorVim, extensions } = event.detail;

        // Mappings in insert mode
        CodeMirrorVim.Vim.map("<c-]>", "<Esc>", "insert");
        CodeMirrorVim.Vim.map("jj", "<Esc>", "insert");
        CodeMirrorVim.Vim.map("jk", "<Esc>", "insert");
        // Remap in normal mode
        /// To navigate through wrapped long lines
        CodeMirrorVim.Vim.map("$", "g$", "normal");
        CodeMirrorVim.Vim.map("0", "g0", "normal");
        CodeMirrorVim.Vim.map("j", "gj", "normal");
        CodeMirrorVim.Vim.map("k", "gk", "normal");



        // User-defined commands
        CodeMirrorVim.Vim.defineEx("forward", undefined, buctton_click_forward_search); // ref: https://discuss.codemirror.net/t/vim-how-to-use-defineex/738/2
        CodeMirrorVim.Vim.defineEx("pdf", undefined, buctton_click_toggle_pdf_panel);
        CodeMirrorVim.Vim.defineEx("toc", undefined, buctton_click_toggle_TOC_left_panel);
        CodeMirrorVim.Vim.defineEx("only", undefined, buctton_click_toggle_editor_only);
        CodeMirrorVim.Vim.defineEx("o", undefined, buctton_click_toggle_editor_only); // :o as :o[nly]
        CodeMirrorVim.Vim.defineEx("re", undefined, writefull_rephrase); // :re[phrase]
        // Access the functions by defining them as actions first
        CodeMirrorVim.Vim.defineAction('jumpToPdf', buctton_click_forward_search);
        CodeMirrorVim.Vim.defineAction('only', buctton_click_toggle_editor_only);
        CodeMirrorVim.Vim.defineAction('toc', buctton_click_toggle_TOC_left_panel);
        CodeMirrorVim.Vim.defineAction('WritefullPrevious', writefull_previous_error);
        CodeMirrorVim.Vim.defineAction('WritefullNext', writefull_next_error);
        CodeMirrorVim.Vim.defineAction('WritefullRephrase', writefull_rephrase);

        // forward search: from VimTeX, <localleader>lv
        CodeMirrorVim.Vim.unmap(';');
        CodeMirrorVim.Vim.mapCommand("\\lv", "action", "jumpToPdf");
        CodeMirrorVim.Vim.mapCommand(";lv", 'action', 'jumpToPdf');
        // Alternatively: use , as leader key
        CodeMirrorVim.Vim.unmap(',');
        CodeMirrorVim.Vim.mapCommand(",lv", 'action', 'jumpToPdf');
        // quick toggles
        CodeMirrorVim.Vim.mapCommand(",v", 'action', 'toc'); // <leader>v is from VimTeX
        CodeMirrorVim.Vim.mapCommand(",o", 'action', 'only'); // <leader>o for :o[nly]


        // Writefull shortcuts:
        // Jump to suggested typo using Writefull, with [s and ]s
        CodeMirrorVim.Vim.mapCommand("[s", 'action', 'WritefullPrevious');
        CodeMirrorVim.Vim.mapCommand("]s", 'action', 'WritefullNext');
        // Remap in visual mode - select a paragraph, press r to trigger the rephrase tool
        CodeMirrorVim.Vim.mapCommand("r", "action", "WritefullRephrase", "visual");
        // Next step:
        // It would be nice to accept/reject the suggestion card using 1/a or 2/r, for example. Leave it for Writefull to build this for now (2023-03-02, 15:52)


        // 2. Restore Ctrl+C to copy into system clipboard - Currently, on Windows laptops, Ctrl+V in visual mode won't do anything. Overleaf should fix this ASAP, though.
        //CodeMirrorVim.Vim.defineAction('CopySelection', copy_in_visual_mode);
        //CodeMirrorVim.Vim.mapCommand("<c-c>", 'action', 'CopySelection');
    });
})();

// Collection of functions

// Clipboard access on Windows machines
function copy_in_visual_mode(cm) {
    document.execCommand('copy');
    alert("Triggered the copy function");
}

// Navigation releated functions
function buctton_click_forward_search(cm) {
    document.querySelector('.fa-arrow-right').click()
};
function buctton_click_toggle_pdf_panel(cm) {
    document.querySelector('a[class*="custom-toggler-east"]').click()
};
function buctton_click_toggle_TOC_left_panel(cm) {
    document.querySelector('a[tooltip*="the file-tree"]').click()
};
function buctton_click_toggle_editor_only(cm) {
    // This is just the sum of the two: toggle toc and toggle pdf
    document.querySelector('a[class*="custom-toggler-east"]').click()
    document.querySelector('a[tooltip*="the file-tree"]').click()
}

// Spell-checker specific functions
function writefull_next_error(cm) {
    document.querySelector('mwc-icon-button[id="writefull-next"]').click()
}
function writefull_previous_error(cm) {
    document.querySelector('mwc-icon-button[id="writefull-previous"]').click()
}
function writefull_rephrase(cm) {
    document.querySelector('mwc-icon-button[id="writefull-rephrase"]').click()
}