Interested in using/teaching VIM editor keybindings?

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);
1 Like

Credit to https://intoli.com/blog/sandbox-breakout/ for explaining how to overcome the browser extension javascript sandbox issues (interestingly, by default, javascript run by a browser extension in Google Chrome can see the DOM elements, including the Ace editor div, but it cannot see properties added with javascript. So the actual Editor instance that is added to the element with the env property is not there).

1 Like

for those who have not heard of Vim:
vim adventures game

Thanks (I think). That’ll be my Sunday disappearing then :laughing:. I wasn’t planning on learning VIM, but it’s a game…

Jenny