Keyboard emulated VI-like editing

macroxue

28 Jan 2017, 20:48

I have been long missing the editing power of VI outside the editor, for example, when writing an email or composing a post like this in a browser. Now I have a major update to the firmware of my keyboard to provide a usable VI-like editing environment almost everywhere. The idea is as simple as translating one key sequence to another key sequence.

For example, h,j,k and l move the cursor in VI and they can be mapped to left, down, up and right arrow keys in a browser. This is straightforward and I believe all multi-layered keyboards can do that. The challenge is to take a further step to have
command sequences like "3b" to move the cursor three words backwards, "c2w" to change the next two words, and "ddp" to
swap two lines.

In a browser, there are a set of editing commands to work with. They are basically combinations from {shift, control, left, right, up, down, backspace, delete, home, end, page-up, page-down} plus control-c for copy, control-v for paste, control-x for cut, control-z for undo and control-y for redo.

Take the above VI sequences for example. "3b" can be translated to 3 times of control-left combo. "c2w" becomes control-shift-right twice and switching to insert mode. "ddp" is more like home, shift-end, control-x, end, enter and control-v.

However, the editing commands in a browser don't always work the same way. For example, control-right always moves the cursor to the beginning of the next word in Google Docs but it moves the cursor to the end of the current word or the end of the next word when I'm editing this post. So it's hard to get the exact VI behavior since the keyboard has no idea about the editing box in a browser.

Some VI commands can't be easily translated. For example, the '.' command repeats the last text-altering command, which is super useful in VI. This requires the keyboard to remember the entire editing sequence including the entered text which is unbounded in size. Another example is the 'f' command which finds a character in a line and move the cursor there. It can be done with some finesse around control-f which brings up a search box but I haven't got time to implement it. Its behavior probably is browser-dependent.

Do we have some ardent VI users here? Any suggestions for making this more useful? If you are interested, you can find the firmware at https://github.com/macroxue/keyboard-firmware. The two key files are vi_command.h and vi_translator.h. Quite a lot of commands are there but they are far from all. Here is a cheat sheet for VI commands. Some of them are probably impossible to get right with just keyboard firmware.
Image

codemonkeymike

28 Jan 2017, 21:45

I haven't found myself writing any C since college but I do know that you can run Neovim in headless mode. What you could do then is funnel in the text your headless Neovim instance as well as the commands. Run your keyboard commands in the Neovim instance and sync the changes with the text you are modifying on the screen. This is, I believe how, Sublime text does its vi-mode.

I say this as an alternative to actually rewriting vim on a keyboard.

User avatar
Laser
emacs -nw

28 Jan 2017, 21:55

I think there was a thread like this somewhere (with this idea, or this question - where is the best place to implement a modal layer at OS level) - and I think the answer is: somewhere at the level of the operating system.

In your keyboard firmware, you can monitor *inserted* text, but you can not monitor what text gets deleted, how many lines/rows/'text objects' etc. your cursor jumped or deleted and so on. The best place, the place that has all the info is of course the focused, running software application, but it's not practical to expect all software to support a modal (vim like layer). Unfortunately. The next best thing would be then the OS, which - in many cases, perhaps not all - can install hooks (or use some other mechanisms) to 'get' a meaning of what's happening inside an application. A number of graphical "text-area" widgets could be supported, or even extended/replaced, to report to the OS (i.e your modal app) cursor movement, text deletion, processing and so on; similar to the graphical 'text-area' widgets, a number of terminal emulators (or at least a good one) could be extended to report that info (if one who could be queried can't be found already). This is all hypothetical, but really I can't see another 'place' to do this stuff.

codemonkeymike

28 Jan 2017, 22:51

Laser's title text gave me a bit an idea. You could write the command by composing readline/emacs commands which are used in most programs and browsers. For example using the readline "alt+b" for vi's "b". The nice thing is that any program that implements a yank buffer or whatever it is called in readline will allow you to have a pseudo vi buffer.

Here is the guide to readline
http://web.mit.edu/gnu/doc/html/rlman_1.html

Post Reply

Return to “Workshop”