Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Vim-Like Layer for Xorg and Wayland (cedaei.com)
148 points by ceda_ei on Aug 27, 2020 | hide | past | favorite | 62 comments

I am also using a custom keyboard layout (basically the movement layer from the NEO layout + left alt → left ctrl, right alt → left alt, caps lock → esc). Initially it was implemented as xmodmap, then as xkb layout and finally as C program using Interception Tools [0]. I had problems with both xmodmap and xkb where it wouldn't work in certain applications; Interception tools works everywhere (even in VMs and outside of X/Wayland).

[0]: https://gitlab.com/interception/linux/tools/blob/master/READ...

I came here to mention Interception Tools and you beat me to it! They really do work incredibly well! Currently I'm only using them to map my space bar to Ctrl upon holding using this[0] plugin.

[0] https://gitlab.com/interception/linux/plugins/dual-function-...

Does it need root/sudo? Or only plugdev or some other "sit-in-front"-privileged group and there you go?

I don't think the program itself needs elevated privileges, because it only reads from stdin and writes to stdout. I am running the interception tools as systemd service, though. I think the Intercepton Tools themselves need elevated privileges; I mean, it's kind of key logger if you think about it.

I'm looking for a way to have a key press becoming a repeated key press (for example 'a' producing 'a' every 150 ms). Is that possible with this software? I'm able to do it with AutoHotKey, but I'm unable to get it to work in Wine.

I am pretty sure this is possible. The program called by Interception Tools can basically do anything (including being stateful), it just reads input events, rewrites it, ignores it, or raises entirely different input events etc. You could probably move your mouse with arrow keys if you wanted to.

I've been able to get AutoHotKey working with almost the same script I use on Windows (had to make a few adjustments because keys were not recognized even though they're exactly the same). The way I got it working is by running it in the same Wine container.

I still prefer a native tool, to be fair, but I haven't been able to Interception to work. It seems a bit too complicated to my liking. Not that AHK is not complicated (it is) but the documentation is superb.

What it would need is some kind of way to define delay. Is that possible? I've tried this with multiple programs, including one where you could script in Python. Never got it to work, sadly.

Here is my layout for people who wonder how it is implemented.


Thanks for this! I wanted to have a space that doubles as a layer key if kept pressed, and I wasn't having great success trying to do it with a custom program using the X bindings. This seems way simpler, while also more powerful.

I've done a similar thing at the hardware level using a QMK layer. The main benefit for me is being able to use VIM movement keys in every text input.

As I'm using a dual boot setup, it's also pretty handy to have the mapping directly embedded in the keyboard firmware.

Was thinking that the whole time I was reading this! I actually have my layout optimized for i3/Vim-controls and it's the default for GergoPlex. I used to use xmodmap hacks but I got sick of maintaining changes across/OS's, having it on the keyboard makes it so much easier. Only downside is carrying around a QMK keyboard!

Layout: https://1.bp.blogspot.com/-rRS_TOYuIQQ/XhRERox3moI/AAAAAAABE...

GergoPlex: https://www.gboards.ca/product/gergoplex

I recently got a GergoPlex and it's so fun to be able to actually reprogram the keyboard itself.

In fact, I got so addicted to keybindings that I tweaked the chording engine to make chords QMK-layer-dependent. The ability to do "modal chords" is just great.

Anyway, thank you for making these things -- I may never have heard of QMK if it wasn't for your boards!

Modal chords sound interesting. Would you mind linking to your keymap / QMK fork?

Sure! I don't have the GergoPlex keymap on Github yet (still a WIP, that one...) but I used the modal chords concept in my Faunchpad keymap as well. Here's the .def file with "modal chords" in it (the first parameter is the layer aka mode, then the rest are the usual ones.)


The forked engine (with very minimal changes) that's used in that keymap is here:


The only change is that all the chording macros (PRES, KEYS, etc.) accept a QMK layer number as the first parameter, and will only activate when that layer is active. The end result is similar to the "sticky bits" functionality, but without the side-effect of masking the signal of those bits.

This is my first foray into embedded programming stuff, so I can't promise I didn't do anything dumb in there. It seems to work for me, though!

Just curious, how much time would you say it took you to 1) build and make it, 2) get used to the layout?

I made the transition from a Thinkpad keyboard to an ErgoDox 3-ish years ago. For me I'd say it took about 2 weeks to be fully back to normal with it, and about a week to stop feeling like I couldn't type.

In my case, I had some bad habits I was needing or wanting to get rid of at the same time: I typed "b" with the wrong finger, I always used my right pinky for shift, I always looked when typing numbers so I never really got to touch-typing them, sometimes I would also peek for regular letters or keys, just to make sure I was where I thought I was.

If you have fewer bad habits, it might take less time. If you have more... :-)

>build and make it

Depends on how you define 'build' here, I'm assuming you mean come to what would become the final design for GergoPlex. That took about a year and a half, my first two designs (Gergo and Georgi respectively) sought to improve on my issues with the ErgoDox (mostly size, PCB-forehead, height, thumb-cluster). After a year of using Gergo and diving into QMK and a failed attempt at picking up stenography, I came up with the idea for a more chord-orientated layout. It didn't take long to get working hardware (as it was a reduction of an existing design), but the layout took about two weeks before everything had settled into it's final place. I did a bit of a write-up over on the blog of how I ended up dailying GergoPlex from a full size 104 [1] and the slow descent into preprocessor madness [2] to make the Combo decorators work. The weird part was tuning QMK so combos like 'we' wouldn't misfire while typing and analyzing my Vim usage to find comfortable places for frequently used chords. (Such as JK for :, WE or UI for Esc, NM for Enter, XC for -, M< for _, etc)

>get used to the layout

At every transitional step I'd say maybe a week? The harder part was finding a keymap that worked for me. But I started with a Sun-Style layout on the ErgoDox and slowly adpated it as I moved to smaller boards. Control is on 'A' (and ';') on GergoPlex for that reason, and the symbols layers are fairly similar. Honestly, just using it in a active chat server for a few hours was enough to get me 90% of the way there.

Every users needs are going to be different, and their layout should match that (it's _why_ you get a programmable keyboard after all!). How you get there is a fiddly endeavour involving lots of flashing and tweaking, but you end up with something ergonomic and deeply personal!

[1] https://blog.gboards.ca/2020/01/weird-keyboards-programmable...

[2] https://blog.gboards.ca/2020/02/adventures-in-obscure-c-feat...

Oh wow, I thought you were replicating it off of the site, not the actual designer of it! That's awesome, I've seen it before and been curious to try to make it myself. Helix keyboard is pretty popular here (Japan) but never tried it more than brushing them (pre-COVID lol) in the mech specialty shop in Akihabara.

I'll definitely make the plunge at some point, just gauging expectations on how roughly much I should expect to invest time-wise before :)

Thank you for your work, I think it's hard to appreciate the contribution things like the ergodex is making for moving towards chorded and other more suitable text input interface for computers. Especially as we transition to VR.

Skip on the Helix and grab something like the Crkbd (Make sure it's a model where the outer column can snap off) or the MiniAxe, Yushakobo carries both I believe. Also check out the 'Self Made Keyboards In Japan' Discord server as there are tons of boards available to you domestically via booth! Worst case, Yushakobo should have everything you need to get a build done (and even has a wonderful selection of blank keycaps), go hit their workshop! :)

No worries, we spend all day using these devices, the fact that we're not using them in a highly configurable fashion pains me. Make technology work for you, not the other way around

Wow, the MiniAxe LP looks exactly like what I think I want (despite the Crkbd being much more aesthetic IMO). I realized over 1y+ on a brown-switch mech that despite loving the layout, I'm just struggling typing properly in a way I don't on a normal Thinkpad laptop chiclet. Just really hard to figure out how switches actually feel IRL even when trying a switch tester.

Had completely missed it, thanks for the pointer :)

Thanks for mentioning QMK [0], it's not something I've heard of before, and it seems like a huge step up from standard keyboard firmware. As far as I can tell only a small number of manufacturers officially support it, but at least one person seems to have made some progress getting a standard cooler master keyboard to run it [1].

[0] https://qmk.fm/ [1] https://github.com/qmk/qmk_firmware/tree/master/keyboards/bp...

That's quite helpful, thank you. The Arduino option also seems to be a useful alternative.

It’s reasonably simple to port QMK (at least partially) to a new microcontroller.

I have worked on Teensy 3.6 support for QMK, and plan to work on Teensy 4.x support as well.

I'm sorry to barge in,but I am in dire need of what you are working on. Could you share your progress or material, Sir?

Is any special hardware needed, or is it all software work?

It's more like full-hardware-no-software work.

Basically if you want to use this on your "standard" keyboards bought off the shelf, you have to either:

1. Open your keyboard, replace the keyboard controller with something that you can program via soldering etc.

or 2. Pray your keyboard doesn't use a mask ROM to store its firmware, and it has a powerful enough MCU as keyboard controller, then figure out how to reflash it and port QMK to it blindly.

Drop (née Massdrop) makes a number of fairly 'normal' QMK keyboards. From smallest to largest, the Alt, Ctrl, and Shift.

Then there's Ergodox EZ, a company which makes the eponymous ortholinear split key (my daily driver), as well as a 40% keyboard called the Planck, and a new next-gen ergo keyboard called the Moonlander. These are designed from the get go to use layers, where each layer assigns its own meaning to keys, and that's where QMK gets really powerful.

There's a whole ecosystem of kits and group buys if you're looking to make a hobby out of it, but if you just want a keyboard you can program, these have you covered.

For people based in Europe who might be interested in an Ergodox or similar, I can recommend a visit to falba.tech.

I've ordered two Redox from them by now (for work & home) and am very satisfied with the product so far.

I did the same thing on my Ergodox with QMK, only with emacs/readline bindings. control-M for enter, control-A for beginning of line, control-E for end of line, control-N for next line, control-H for backspace etc...

It makes using those clunky web edit boxes (such as the one I'm typing this into right now) somewhat bearable.

Getting a fancy ergonomic programmable keyboards is one of the best decisions I've made over the past few years. It's so much more comfortable in the long run.

I'm also a big fan of "space cadet shift", which makes left and right shift input ( and ) when pressed on their own. I also have a dual-function caps lock: when pressed on its own it's Escape, when chorded with an other key it's control. You can do that in software with xcape for those who want to give it a try:

    xcape -t 500 -e 'Shift_L=parenleft;Shift_R=parenright;Control_L=Escape'
You'll have to swap left control and caps lock using xmodmap or setxkbmap as well.

And for those who are curious to see what a QMK config looks like, it's fairly straightforward (this one is a WIP, there are a few problems with it, but it gives you an idea):


That's of course assuming that your board is already supported, adding support for a new board is a bit trickier and requires some embedded C know-how.

What are your thoughts on the vertical stagger on ergonomics, vs. just having the left and right side split? Does it actually help, or is it more of an aesthetic choice?

I notice carpal tunnel pain in my wrists when I tension or release the tendons in my wrist that curl my fingers to move them up and down. Moving them from side to side doesn't hurt at all, so I'm skeptical that there's anything ergonomically wrong with the normal staggered layout. Split still seems like a good idea, though.

How infuriating are regular keyboards after getting used to Ergodox?

What I did here was starting to use a premade programmable 60% keyboard (Vortexgear Pok3r) and remapping "Caps-Lock" as modifier to make hjkl into the actual arrow keys. No software config needed.

Would you write about it? I am really curious.

Care to share please?

The NEO keyboard layout (https://neo-layout.org/) which I’m using for over a decade, has a similar concept of a number of additional layers.

This is quite handy for having a bunch of special characters for programming readily available (hover over the layers on https://neo-layout.org/ to see).

For any other modal use-cases (e.g. resizing windows, changing music volume), I use i3’s modes: https://i3wm.org/docs/userguide.html#binding_modes

They're using sway/i3. I don't understand why they're doing it like that when sway/i3 already has support for modes.

They could have just done something like this in the sway/i3 config:

  mode "normal" {
    bindsym i mode "default"

    bindsym q kill
    bindsym y exec volchange -5
    bindsym u exec volchange +5
    bindsym o exec brightness -200
    bindsym p exec brightness +200
    bindsym w exec mpc prev
    bindsym e exec mpc toggle
    bindsym r exec mpc next

  bindsym $mod+c mode "normal"
EDIT: I've realized their method has the benefit of working with other window managers that don't support modes or on-the-fly reconfiguration.

As someone who uses Vim daily, I quite like this idea. I would customise it to mimic the original Vim bindings a bit more closely where possible though, to e.g. keep Ctrl-D as page down.

I'm not sure if this would be possible, but it would be fun to have customisable per-application bindings (based on the active window, probably) in addition to the set of global bindings. I can also think of minor cases where motions would be useful, like 3x alt-tab (i.e. 3gt) to switch to a specific application.

I wonder at what point the depth of the mode-ness will become too much, if you were running this, for example, with a vi-mode bash readline.

> e.g. keep Ctrl-D as page down.

I tried doing the same using xdotool by binding Ctrl+F<something> to PageDown but for some reason it didn't work for some reason and I didn't investigate enough.

I believe a possible reason is that the OP used xkb, which if I'm not mistaken is lower level than xdotool (so xdotool would not suffice)

I am the OP. What I tried was something along these lines.

e.g. to get w in normal mode to send Ctrl+right, I did the following.

1. Bind w to F14 in normal mode.

2. In i3 config, add `bindsym 0xffcb exec xdotool key ctrl+Right`

If I simply ran the command (`xdotool key ctrl+Right`) in normal mode, it would work but it didn't work via a binding.

This was infact the initial idea behind all this but after quite some testing xdotool turned out to be unreliable so I repurposed it as a shortcut layer.

I'm fan of heavy key mapping customization to boost productivity.

The most productive remapping so far which I made is to globally remap (via xkb) Left Alt + HJKL to respective arrow keys. Works in all GUI applications which rely on arrow keys for navigation, plus standard Ctrl + Shift + Left Alt + H (Left Arrow) works to select previous word in text fields (e.g. in browser).

Next one is to remap Left Ctrl to Left Shift and to press it with upper side of the palm just below pinky (not sure how this part of the hand is called correctly) instead of utilizing finger for that. Works best on mechanical keyboards without bevels.

Also I find quite useful to remap keys 5-0 to Right Shift + Q (5), W (6), E (7), R (8), D (9), F (0). I find these keys are easier to reach and type without a mistake instead of using standard 5-0 keys which you should stretch your fingers to type. For example, to type "()" I use Left Ctrl (remapped to Shift) + Right Shift + D, F which is easier to type without fingers leaving home row.

I use Hammerspoon and Karabiner Elements on macOS to rebind keys (including the examples you gave). There's some examples and repositories available for these applications.

On Windows, I use AutoHotKey, though mainly for gaming (be aware it can get you banned on some games though; investigate this beforehand).

On Linux, I have a bit more difficulty with all of this because:

1) There's no standard application or configuration or even desktop. As of now I mainly use Gnome, but my preference would be to use more lightweight WM/DE on some of my devices.

2) I sometimes use a Linux desktop in a VM, from macOS.

I've been thinking about doing something like this for quite a while. One question that's been bothering me is: How will I know what mode I'm in? Can I somehow change the cursor system-wide? Can I add some sort of notification to my i3bar?

EDIT: I just noticed that the article mentions this as a "bonus" at the end. Does this work reliably with i3status-rust? In case of i3bar at least there'd always be a delay coming from the low refresh rate of (in my case) 5s.

I wrote a keyboard hook in C for Windows (I was using AHK but it was unreliable). Initially it was modal but I found over time that I would get caught out. So now it's not modal. I hold down capslock and then use ijkl to navigate etc. The only thing left that is modal is spacebar for select/visual mode but I still a have to hold down capslock for that (e.g. capslock down, space bar, ijkl to select text, capslock up). Also I was using hjkl but switched to ijkl to match the arrow keys. I don't use vim enough anymore to justify hjkl.

Holding down capslock turns out to not be a problem in practice. The main benefit of vim style navigation for me is not leaving the home row.

> Also I was using hjkl but switched to ijkl to match the arrow keys. I don't use vim enough anymore to justify hjkl.

Same here. ijkl is so much better!

> So now it's not modal. I hold down capslock and then use ijkl to navigate etc.

Hmm… maybe I should try that. Then again, I am afraid of getting the Emacs pinky all over again…

In my case, the interval is set to 0.5 which has a slight delay but enough for me to not mind. I usually have a mental idea of what mode I am in at all times.

> Can I somehow change the cursor system-wide?

Check the arch wiki article on Cursor themes[0]. Generally,, DEs have nice support for switching cursor themes after startup. In either case, you would need to modify `xkb_swapper.sh` to set a cursor theme whenever the mode is changed.

[0]: https://wiki.archlinux.org/index.php/Cursor_themes

Oh cool, I hadn't noticed that you were actually around here on HN! Thanks so much responding!

> In my case, the interval is set to 0.5

I noticed that more frequent updates of the status bar do eat away at the battery, though. :\

Get a keyboard with layer support, https://docs.qmk.fm/. No need for different modes ...

I wonder if, instead of having two different layouts and changing between them, an alternative would be to put all the navigation keys at fifth level and above, and then hijack the Kanji modifier to switch to them, or maybe pretend you're a Far East keyboard and use Eisu_toggle.

Good idea. This could be also useful for assigning custom functionality instead of vim (e.g. window management).

Also one can switch backlights/keyboard colors depending of the keyboard mode for visual feedback.

In the fluxbox WM you could achieve something like this using keymodes


Have you considered just using a (sticky) compose key and setting macros for some weird characters? That way you wouldn't have to run scripts to change modes.

Does this get confusing when you're actually using Vim? Do you ever use Keyboard Normal Mode when you're in Vim?

No, it doesn't. I use keyboard normal mode sometimes for things other than navigation, like seeking audio, etc

sadly wayland means only sway. I've done some remapping as well, but don't know how to make Gnome in wayland mode (which is nice on a cramped notebook and someone has to test wayland...) read anything from a user-specified directory, so I have to edit stuff in /usr every update anew...

Some concrete examples of using it? Did I miss the demo showing some good exemplary behaviour driven by this?

I just had a crazy idea based on this- (it's not going to be useful as is, mostly novel and potentially good)

You know how a desktop screen is fixed width and windows cannot be outside of the screen (at least in tiling), I want a single workspace for all windows, where they arrange non-ovrlappingly and screen would just be a view to a fixed point so I can scroll (quickly using hjkl) in 4 directions to look at other windows and even maybe select a group of windows and make them my current view.

Much more dynamic than i3, my current wm.

I've never used AwesomeWM but from a brief reading, maybe it could do part of what you want: "maybe select a group of windows and make them my current view".

From what I understand, windows don't belong to a workspace, but a workspace is a collection of windows having a certain tag. A given window may have multiple tags, so it can belong to multiple workspaces.

Somewhat related: https://github.com/SimulaVR/Simula. This is the same concept but with VR.

Sounds a bit like the infamous 10/GUI


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact