// ==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.1
// @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
// ==/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]
// Option for a vertical split. Source: https://stackoverflow.com/a/24417327/3925312
editor.setOption("showPrintMargin", true)
// 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", "<Esc>", "insert")
// Equilivantly, from https://groups.google.com/d/msg/ace-discuss/gwXMzUM17I4/9B_acHBSCQAJ
// window.ace.require("ace/keyboard/vim").Vim.map('jj', '<Esc>', 'insert')
vimKeyboard.Vim.map("jk", "<Esc>", "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)
})();