Skip to content

Instantly share code, notes, and snippets.

@Kirens
Created December 26, 2018 10:36
Show Gist options
  • Save Kirens/bdb1e128107c885d73327fb9a80da98e to your computer and use it in GitHub Desktop.
Save Kirens/bdb1e128107c885d73327fb9a80da98e to your computer and use it in GitHub Desktop.
Overleaf vim controls - scroll, select files, etc.
// ==UserScript==
// @name Overleaf Vim File Select
// @namespace Violentmonkey Scripts
// @version 1
// @grant unsafeWindow
// @include https://www.overleaf.com/project/*
// @run-at document-idle
// ==/UserScript==
const getFileTree = () => document.getElementsByClassName('file-tree-inner')[0]
const children =
el =>
Array.from(el.children)
const getUlChild =
el =>
children(el)
.find(el => el.nodeName.toLowerCase() === 'ul')
const getEntries =
rootTree =>
children(getUlChild(rootTree))
.filter(el => el.nodeName.toLowerCase() === 'file-entity')
.map(el => el.children[0].children[0])
const getEntryName =
entry =>
entry.querySelector('[ng-hide="entity.renaming"]').textContent.trim()
const entryIsFile =
entry =>
entry.getAttribute('ng-if').indexOf('== \'folder\'') == -1
const openEntry =
entry =>
entry.children[0].click()
var files = Array.from(document.querySelectorAll('.entity[ng-if="entity.type != \'folder\'"]')).map(file => {
const fileName = file.querySelector('[ng-hide="entity.renaming"]').textContent.trim();
return [fileName, file.children[0]]
})
const debug = (val, ...other) => console.log(val, ...other) || val
const resolvePath =
path =>
path
.split('/')
.reduce(
(element, name) =>
getEntries(element)
.find(entry => getEntryName(entry).indexOf(name) !== -1)
, getFileTree())
const edit =
path =>
openEntry(resolvePath(path))
const scrollPdf =
steps =>
document.getElementsByClassName('pdfjs-viewer')[0]
.scrollBy({top: 100 * steps})
const scroller =
event =>
event.key === 'ArrowDown'
? (scrollPdf(1), event.stopPropagation())
: event.key === 'ArrowUp'
? (scrollPdf(-1), event.stopPropagation())
: undefined
// Register key strokes
document.addEventListener('keydown',
event =>
event.target.className.indexOf('ace_text-input') !== -1 &&
scroller(event)
, true)
const awaitAce =
callback =>
setTimeout(() => unsafeWindow.ace ? callback(unsafeWindow.ace) : awaitAce(callback), 1000)
// Register shortcut
awaitAce(ace =>
ace.config.loadModule('ace/keyboard/vim',
({ Vim }) =>
Vim.defineEx('edit', 'e',
(_, { args }) => edit(args[0])
)
)
)
console.info('Overleaf Edit File Script Loaded')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment