// ==UserScript== // @name Overleaf Editor Custom VIM Keybindings // @description Configure a list of shortcuts for Vim-mode + :commands for toggling panes on Overleaf // @namespace http://tampermonkey.net/ // @version 0.2 // @match https://www.overleaf.com/project/* // @grant none // Source 1: https://groups.google.com/d/msg/ace-discuss/gwXMzUM17I4/9B_acHBSCQAJ // Source 2: https://www.overleaf.com/learn/how-to/How_can_I_define_custom_Vim_macros_in_a_vimrc_file_on_Overleaf%3F // @downloadURL none // ==/UserScript== (function() { 'use strict'; // poll until editor is loaded const retry = setInterval(() => { if (window._debug_editors === undefined) return clearInterval(retry) // get current editor instance // get current editor instance var editor = window._debug_editors[window._debug_editors.length -1] // vim keyboard plugin var vimKeyboard = window.ace.require("ace/keyboard/vim") //////////////////////////////////////////////////////////// // j k within long lines vimKeyboard.Vim.map("j", "gj", "normal") vimKeyboard.Vim.map("k", "gk", "normal") // add custom keybindings - insert mode applies on insert vimKeyboard.Vim.map("jj", "", "insert") // Equilivantly, from https://groups.google.com/d/msg/ace-discuss/gwXMzUM17I4/9B_acHBSCQAJ // window.ace.require("ace/keyboard/vim").Vim.map('jj', '', 'insert') vimKeyboard.Vim.map("jk", "", "insert") //////////////////////////////////////////////////////////// // Remapping one key to another is doable, in Normal mode // `nmap h j` can be defined as the following: // Though, why should this mapping be here anyways? It is just meant for demo purpose. // vimKeyboard.Vim.map("h", "j", "normal") // Define local commands ==> matching elements along with a identifier that matches. // Maintenance note: if one hotkey/cmd does not work, check here for the matching HTML element. editor.commands.addCommands( [ { // Note, this is not working as the element will change to "Split screen" // At least, we need an "or-condition" for the querySelector. name: "FullScreen", exec: function() { document.querySelector('a[tooltip*="Full screen"]').click() } }, { name: "ToggleLog", exec: function() { document.querySelector('a[tooltip*="Logs and output files"]').click() } }, { name: "jumpToPdf", exec: function() { document.querySelector(".synctex-control-goto-pdf").click() } }, { name: "VimtexTocToggle", exec: function() { document.querySelector('a[tooltip*="the file-tree"]').click() } }, { name: "CloseComment", exec: function() { document.querySelector('a[class*="review-panel-toggler"]').click() } }, { name: "TogglePDF", exec: function() { document.querySelector('a[tooltip*="the PDF"]').click() } }]) // add keybindings for jump to pdf vimKeyboard.Vim.mapCommand("\\v", "action", "aceCommand", { name: "VimtexTocToggle" }, { context: "normal" }); vimKeyboard.Vim.mapCommand("\\lv", "action", "aceCommand", { name: "jumpToPdf" }, { context: "normal" }); vimKeyboard.Vim.mapCommand("\\o", "action", "aceCommand", { name: "TogglePDF" }, { context: "normal" }); // bind to ;lv vimKeyboard.Vim.unmap(";") vimKeyboard.Vim.unmap(",") vimKeyboard.Vim.map(";lv", "\\lv", "normal") vimKeyboard.Vim.map(",v", "\\v", "normal") // Use ,o to activate two hotkeys: hide file-menu and hide PDF preview vimKeyboard.Vim.map(",o", "\\v\\o", "normal") //vimKeyboard.Vim.mapCommand(",o", "action", "aceCommand", // { name: "FullScreen" }, { context: "normal" }); //vimKeyboard.Vim.defineEx("full", "", ()=>editor.commands.exec("FullScreen")) vimKeyboard.Vim.defineEx("log", "", ()=>editor.commands.exec("ToggleLog")) vimKeyboard.Vim.defineEx("ShowPDF", "", ()=>editor.commands.exec("TogglePDF")) vimKeyboard.Vim.defineEx("ClosePDF", "", ()=>editor.commands.exec("TogglePDF")) vimKeyboard.Vim.defineEx("OpenPDF", "", ()=>editor.commands.exec("TogglePDF")) vimKeyboard.Vim.defineEx("PDF", "", ()=>editor.commands.exec("TogglePDF")) vimKeyboard.Vim.defineEx("pdf", "", ()=>editor.commands.exec("TogglePDF")) // Close comment: CC, cc, CloseComment vimKeyboard.Vim.defineEx("CloseComment", "", ()=>editor.commands.exec("CloseComment")) vimKeyboard.Vim.defineEx("CC", "", ()=>editor.commands.exec("CloseComment")) vimKeyboard.Vim.defineEx("cc", "", ()=>editor.commands.exec("CloseComment")) // set the modified keyboard handler for editor editor.setKeyboardHandler(vimKeyboard.handler) console.log("Custom key bindings applied") }, 100) })();