As a VIM user I really wanted to be able to use VIM keybindings when testing out levels in Code Combat. I noticed the text editor being used was Ace which supports VIM keybindings, but I could’t find a way to enable them in the options. Fortunately I was able to make it work using the following javascript and a browser extension that allows you to inject arbitrary javascript:
function runVimLoader() {
if (!window.vimLoader) {
window.runCount = 0;
window.vimLoader = window.setInterval(
() => {
let aceElement = document.getElementsByClassName('ace')[0];
if (aceElement) {
let editor = aceElement.env && aceElement.env.editor;
if (editor) {
let bindings = editor.getKeyboardHandler();
if (bindings.$id !== 'ace/keyboard/vim') {
editor.setKeyboardHandler('ace/keyboard/vim');
console.log('Vim keybindings enabled.');
}
} else {
console.log('No editor found.');
}
} else {
console.log('No editor element found.');
}
},
1000
);
}
}
const runInPageContext = (method, ...args) => {
// The stringified method which will be parsed as a function object.
const stringifiedMethod = method instanceof Function
? method.toString()
: `() => { ${method} }`;
// The stringified arguments for the method as JS code that will reconstruct the array.
const stringifiedArgs = JSON.stringify(args);
// The full content of the script tag.
const scriptContent = `
// Parse and run the method with its arguments.
(${stringifiedMethod})(...${stringifiedArgs});
// Remove the script element to cover our tracks.
document.currentScript.parentElement
.removeChild(document.currentScript);
`;
// Create a script tag and inject it into the document.
const scriptElement = document.createElement('script');
scriptElement.innerHTML = scriptContent;
document.documentElement.prepend(scriptElement);
};
runInPageContext(runVimLoader);