As a Christmas gift to myself, I decided to get a new keyboard; a keyboard that I had scoffed at using not too long ago because “lol where’s all the keys?”. That keyboard is the Planck EZ Glow. This post is to describe how I have it setup, not to give a whole backstory as to why I decided to get it (that’s for me and my journal to know, thank you very much). I affectionately refer to my keyboard as the macinplanck.

Some front-matter before I get into things:

  • I’ve been getting more and more into Vim, which is what inspired me to set up the keyboard the way that I did.
  • I use a Mac, so there are a bunch of mappings that I describe later that are only relevant for that OS. If you decide to duplicate this mapping, keep that in mind.
  • Currently, I’ve configured everything through the Oryx configurator online; I know that more advanced macros and such exist in QMK, and that there are some things that I describe below that could be more efficiently accomplished via editing the keymap.c directly, I just didn’t have the time (nor the patience) to get into that this time around.

Here are links to my current configuration:

…and here are resources that I used to configure my setup:

  • QMK Documentation (which is fantastic, btw) - a lot of acronyms below are coming straight out of this documentation, so it’d probably be handy to have this open as you read along.
  • (if you don’t know Vim, one thing that you should know is that this is essentially your bible)
  • r/olkb (solved pretty much any issue I encountered in this keymap build by searching here)
  • Wally (and it’s wally-cli counterpart) for easily flashing new firmware.

If history is any indication, the configuration that I’m about to describe will probably be out of date by this time tomorrow, but I feel that writing down my thought process helps me pick out the holes in my logic and give me ideas for future improvements.

But anyway, who cares? Onto those sweet, juicy layers to make sense of wtf I even did.


I currently have 9 layers (Lower, Base, Raise, Adjust, NORMAL, VISUAL, NRMLSHFT, WINDOWZ, and LGUI_ALL):

9 layers

Not the biggest of drawbacks, but for whatever reason you cannot edit or delete the names in the first four layers. Removing the ability to delete them is understandable (otherwise it’s kinda not a Planck), but the inability to rename them didn’t really make sense to me. Oh well!

I’ll be going through the Base layer first, just because that makes sense in my head, and move through all of the other layers sequentially.

The Base Layer

base layer

A lot of this layer is the same as the default config. QWERTY layout, Lower/Raise are in the same spot, etc. There are some distinguishing characteristics, though:

  • Hyper is replaced with TT(4), which brings you to the NORMAL layer.
  • Esc is mapped to the equivalent of LCTRL(KC_ESC), which means:
    • Tap -> Esc
    • Hold -> Left Control (modifier)
    • This is how it should be on every keyboard, don’t @ me.
  • Tab is mapped to the equivalent of MEH_T(KC_TAB), which means:
    • Tap -> Tab
    • Hold -> Meh (Left control, Shift, and Alt modifiers)
    • This is done this way because I have many macros defined via Keyboard Maestro that launch applications by performing Meh+<some-character> (like this).
  • The Lower and Raise keys have been changed to TT(LOWER) and TT(RAISE), respectively, instead of the regular MO() functions they are mapped to. This was done for a couple of reasons:
    • Sometimes I like to stop and think about what numbers/symbols I’m going to use, and sometimes I know exactly what I want to do and then move on with typing. TT() suited this better; if you tap the key it’ll bring you to the associated layer and then stay there, but if you hold the key, you’ll only activate the layer for as long as you hold it (which is the default behavior of the Lower and Raise keys). This is the same reason why I use TT(4) above.
    • Because I have modifiers in these layers (more on this below), keyboard shortcuts felt “clunky” to use when I switched to Lower/Raise in the default config, since you had to do essentially a dance, pressing multiple keys to get what you wanted. Changing this to that tapping the key brought you into the layer and then left you there allows me to compose shortcuts a little more fluidly.
  • cmd is slightly modified to be OSM(MOD_LGUI), which is just fancy for “if I tap this key, the modifier is ‘active’ until I hit another key (or just wait)”. This is mostly useful for the chords I have mapped in VSCode (my editor of choice).

And that concludes our Base layer tour. Onwards!

The Lower and Raise Layers


lower layer


raise layer

It helps to explain these both at the same time because there are a lot of similarities between the two, but with one key difference between the base config; the layers have essentially been swapped. When you look at a “traditional” keyboard, the number keys above the alphabetical characters have the number printed underneath the symbols, so in my mind they are “lower” than the symbols. As such, the Lower layer maps to numbers (and other keys that you get without pressing “Shift” on a traditional keyboard) while the Raise layer maps to the symbols (and other keys that you get when pressing “shift” on a traditional keyboard). The Planck layout made more sense in my brain when I did that; your mileage may vary.

Also, any action that I explicitly didn’t set in a given layer, I marked it as “None”. This was done because, by default, the Oryx configurator marks other keys in the layer “transparent” to let the key fall through to the Base layer. I do this in all layers except the Base layer (that layer is full anyway, so it doesn’t matter). This was done because I didn’t want to encounter any behavior that I didn’t explicitly program. The TT() keys are not set to “None” because they still have a function; pressing one of those keys again will take you into the Adjust layer or will take you back to the Base layer, depending on which layer you’re in.

The last “big thing” to note here (because it’s common in other layers too) is that at this point, I’ve designated the ESC key as my “escape hatch” in all layers that could be considered “not transient”. This key is mapped to TO(1) everywhere that is relevant, which brings you back to the Base layer. There are other keys in other layers that do this, but the ESC key is supposed to be my “safe key” that gets me out of anywhere I might lose myself in. Pressing ESC many times is also fine in pretty much all situations, since even if I get into the Base layer, it’s just mapped to actual ESC, which doesn’t really ever do anything destructive.

Other things to note here:

  • I removed all function keys, since I basically never use them.
  • I removed various other keys like PgUp/PgDown because I don’t really find them to be all that useful (I have other shortcuts that accomplish the same thing) and I don’t think that I’d use the Non-US characters.
  • I brought back Enter and Backspace because they “made sense” to keep (I was gaining nothing by having them removed like it is in the default configuration).
  • I persisted the same modifier keys from the Base layer into both layers because I have a lot of application-specific shortcuts that rely on using these modifiers in conjunction with characters/symbols that are in these layers.

The rest of the layout should be fairly obvious, so I’m not going to enumerate all of the mapping. 3 layers down, 9 to go.

The Adjust Layer

adjust layer

I have the least to say about this layer. Note that we have the same “escape hatch”, but all other keys remain the same as the default configuration. If you have any ideas as to what else I should put here, please let me know!

The NORMAL Layer

normal layer

You get to the NORMAL layer by tapping the QMK key at the bottom-left of the Base layer. This is where things get a bit more interesting, and where Vim’s influence started getting the best of me.

This layer is called NORMAL because, if you’re in a text field that isn’t Vim (which happens more often than I would like), this layer gives some basic Vim motions that allow you to navigate text easily using shortcuts that are native to the OS.

An important thing to call out is that, although it’s called NORMAL, this isn’t meant to be the layer that you’re always in (which is common when you’re in an actual Vim buffer). I had considered making this the Base layer, but then it got in the way when editing in “real” Vim. So, even though in a conceptual sense I try to consider the Base layer analogous to INSERT mode, they’re still two very distinct concepts that shouldn’t be intermingled. If I’m in an actual Vim buffer, I ignore these layers altogether and always return to Base, since the other layers wouldn’t make a lot of sense to use in place of honest-to-goodness Vim keybindings.

Here is the key mapping for the NORMAL layer as it stands now (anything not listed can be assumed to be “None”):

Physical KeyMappingAction PerformedColor
TabtabTab#00a3e9 Desert Sun Blue
Walt+rightMove right 1 word#00a3e9 Desert Sun Blue
Ealt+rightMove right 1 word#00a3e9 Desert Sun Blue
Rcmd+shift+zRedo#00a3e9 Desert Sun Blue
Ycmd+cCopy#00a3e9 Desert Sun Blue
Ucmd+zUndo#00a3e9 Desert Sun Blue
ITO(1)Go to Base#f2671f Sunset Orange
Pcmd+vPaste#00a3e9 Desert Sun Blue
BackspaceleftMove left 1 character#00a3e9 Desert Sun Blue
ESCTO(1)Go to Base#f2671f Sunset Orange
ATO(1)Go to Base#f2671f Sunset Orange
HleftMove left 1 character#00a3e9 Desert Sun Blue
JdownMove down 1 character#00a3e9 Desert Sun Blue
KupMove up 1 character#00a3e9 Desert Sun Blue
LrightMove right 1 character#00a3e9 Desert Sun Blue
ShiftMO(6)Momentarily go to NRMLSHIFT#219e20 Material Green
XdelDelete 1 character#00a3e9 Desert Sun Blue
CTO(1)Go to Base#f2671f Sunset Orange
VTG(5)Toggle VISUAL#878eff Solarized Purple
Balt+leftMove left 1 word#00a3e9 Desert Sun Blue
/?cmd+fSearch (most apps use this)#00a3e9 Desert Sun Blue
EnterdownMove down 1 line#00a3e9 Desert Sun Blue
QMKTRNSGo back to Base#f2671f Sunset Orange
CTRLctrlLeft Control key#00a3e9 Desert Sun Blue
ALTaltLeft Alt key#00a3e9 Desert Sun Blue
OSOSM(MOD_LGUI)One-shot CMD Modifier#00a3e9 Desert Sun Blue
LowerMacro 1 RecStart recording a macro#00a3e9 Desert Sun Blue
SpaceMacro 1 PlayPlay macro 1 that was recorded#00a3e9 Desert Sun Blue
RaiseMacro Stop RecStop recording the macro#00a3e9 Desert Sun Blue
LeftMO(8)Momentarily go to LGUI_ALL#ea1e63 Material Red
RightTG(7)Toggle WINDOWZ#2e00e9 Sunset Blue/Purple

Scroll down to the “Special Mention: RGB Handling” section to understand what the colors mean.

The VISUAL Layer

visual layer

The VISUAL layer is meant to be the layer that performs selection-based actions, similar to how VISUAL mode works in Vim. You get to it from the NORMAL layer by tapping V. The main draw of this layer is that you can perform large selections relatively quickly; it basically takes all of the text navigation shortcuts from the NORMAL layer and adds “Shift” to them.

Here is the keymapping for this layer.:

Physical KeyMappingAction PerformedColor
Walt+shift+rightSelect right 1 word#878eff Solarized Purple
Ealt+shift+rightSelect right 1 word#878eff Solarized Purple
Ycmd+cCopy#878eff Solarized Purple
ITO(1)Go to Base#878eff Solarized Purple
Pcmd+vPaste#878eff Solarized Purple
Backspaceshift+leftSelect left 1 character#878eff Solarized Purple
ESCTO(1)Go to Base#878eff Solarized Purple
ATO(1)Go to Base#878eff Solarized Purple
Dcmd+xCut#878eff Solarized Purple
Hshift+leftSelect left 1 character#878eff Solarized Purple
Jshift+downSelect down 1 line#878eff Solarized Purple
Kshift+upSelect up 1 line#878eff Solarized Purple
Lshift+rightSelect right 1 character#878eff Solarized Purple
CTO(1)Go to Base#878eff Solarized Purple
VTRNSGo back to NORMAL#00a3e9 Desert Sun Blue
Balt+shift+leftSelect left 1 word#878eff Solarized Purple
<,shift+tabUnindent (depends on app)#878eff Solarized Purple
>.tabIndent (depends on app)#878eff Solarized Purple
Entershift+downSelect down 1 line#878eff Solarized Purple
QMKTO(4)Go to NORMAL#00a3e9 Desert Sun Blue
CTRLctrlLeft Control key#878eff Solarized Purple
ALTaltLeft Alt key#878eff Solarized Purple
OSOSM(MOD_LGUI)One-shot cmd modifier#878eff Solarized Purple
LowerMacro 1 RecStart recording a macro#878eff Solarized Purple
SpaceMacro 1 PlayPlay macro 1 that was recorded#878eff Solarized Purple
RaiseMacro Stop RecStop recording the macro#878eff Solarized Purple
LeftMO(8)Momentarily go to LGUI_ALL#ea1e63 Material Red

Not much else going on here, so onto the next layer.


nrmlshft layer

The NRMLSHFT layer is only accessible from the NORMAL layer and, as the name implies, it contains actions that are analogous to “shifted” keys in Vim’s NORMAL mode (like X or G). I didn’t do a whole lot of customization here, and there are probably some actions that I’ve missed; I’ll slowly add more as I discover them.

Here is the keymapping for this layer.:

Physical KeyMappingAction PerformedColor
Walt+rightMove right 1 word#219e20 Material Green
Ealt+rightMove right 1 word#219e20 Material Green
Icmd+leftMove to beginning of line#219e20 Material Green
Pcmd+vCopy#219e20 Material Green
BackspacebackspaceBackspace 1 character#219e20 Material Green
Acmd+rightMove to end of line#219e20 Material Green
Gcmd+downMove to bottom#219e20 Material Green
ShiftMO(6)Momentarily activate NRMLSHFT#219e20 Material Green
XbackspaceBackspace 1 character#219e20 Material Green
Balt+leftMove left 1 word#219e20 Material Green
<,cmd+shift+tabUnindent (depends on app)#219e20 Material Green
>.cmd+tabIndent (depends on app)#219e20 Material Green
EnterenterInsert newline#219e20 Material Green
CTRLctrlLeft Control key#219e20 Material Green
ALTaltLeft Alt key#219e20 Material Green
OSOSM(MOD_LGUI)One-shot cmd modifier#219e20 Material Green


windowz layer

This layer doesn’t make much sense to the casual onlooker, mostly because it is used exclusively for my window management tool on macOS: Rectangle. I tile/move/resize my windows on macOS all day thanks to this tool. It’s invaluable enough for me that I’ve dedicated an entire layer to it. The above keymap makes more sense when you see how the keyboard shortcuts for that application are set up on my machine:

rectangle keymap

That’s all there is to the WINDOWZ layer! Here’s the keymapping:

Physical KeyMappingAction PerformedColor
Qalt+ctrl+qMove window top left#2e00e9 Sunset Blue/Purple
Walt+ctrl+wMove window top right#2e00e9 Sunset Blue/Purple
Ealt+ctrl+eMove window first two thirds#2e00e9 Sunset Blue/Purple
Talt+ctrl+tMove window last two thirds#2e00e9 Sunset Blue/Purple
Palt+ctrl+pMove window to previous display#2e00e9 Sunset Blue/Purple
Backspacealt+ctrl+backspaceRestore original window size/pos#2e00e9 Sunset Blue/Purple
ESCTO(1)Go to Base#878eff Solarized Purple
Aalt+ctrl+aMove window bottom left#2e00e9 Sunset Blue/Purple
Salt+ctrl+sMove window bottom right#2e00e9 Sunset Blue/Purple
Dalt+ctrl+dMove window first third#2e00e9 Sunset Blue/Purple
Falt+ctrl+fMove window center third#2e00e9 Sunset Blue/Purple
Galt+ctrl+gMove window last third#2e00e9 Sunset Blue/Purple
Halt+ctrl+hMove window left half#2e00e9 Sunset Blue/Purple
Jalt+ctrl+jMove window bottom half#2e00e9 Sunset Blue/Purple
Kalt+ctrl+kMove window top half#2e00e9 Sunset Blue/Purple
Lalt+ctrl+lMove window right half#2e00e9 Sunset Blue/Purple
'alt+ctrl+'‘Almost maximize’ window#2e00e9 Sunset Blue/Purple
Calt+ctrl+cCenter current window#2e00e9 Sunset Blue/Purple
Nalt+ctrl+nMove window to next display#2e00e9 Sunset Blue/Purple
,alt+ctrl+,Make window smaller#2e00e9 Sunset Blue/Purple
.alt+ctrl+.Make window bigger#2e00e9 Sunset Blue/Purple
Enteralt+ctrl+enterMaximize window#2e00e9 Sunset Blue/Purple
QMKTO(4)Go to NORMAL#00a3e9 Desert Sun Blue
LowerMacro 1 RecStart recording a macro#2e00e9 Sunset Blue/Purple
SpaceMacro 1 PlayPlay macro 1 that was recorded#2e00e9 Sunset Blue/Purple
RaiseMacro Stop RecStop recording the macro#2e00e9 Sunset Blue/Purple
Right-Go back to NORMAL#00a3e9 Desert Sun Blue

The LGUI_ALL Layer

lgui_all layer

This layer is an example of pure laziness on my part. The only reason why LGUI_ALL exists is because, when I was in the NORMAL or VISUAL layers, I occasionally found myself wanting to perform some kind of modifier + “regular” key combination (almost always cmd + something), but then stay on the current layer. This is an incredibly brute-forced approach to handling that need, and is definitely something that I’ll come back and revisit in the near future. For now, it works fine, so I’m not really worried. If you have any suggestions for an approach to this, I’m all ears!

I didn’t create a keymap gist for this because it’s simply a layer that has cmd prepended to all the keys on the keyboard (i.e. cmd+q, cmd+w, etc.).

Special Mention: RGB Handling

Each layer has what you’d call a “dominant” color that signifies what layer you’re in. If you were to tap/hold/whatever a key that is illuminated with the color that is dominant for that layer, you are guaranteed to not be kicked out of that layer.

The same logic applies if there is a key with a color that is “not” dominant for the layer you’re on; if you tap a key that is not dominant, you should be taken to a layer where the color of the key you pressed is dominant.

The only layers where there are no other colors that signify other layers are NRMLSHIFT and LGUI_ALL; this is because the only way to get into those layers is by holding an MO() key, and once you release that key you’re back on the layer that you started with. No need for an “escape hatch” in those layers.

Here are the colors that I used for this layout (colors are taken from the per-key color options in the Oryx configurator):

Lower 0#ecb392 Raspberry Light Brown
Base 1#f2671f Sunset Orange
Raise 2#219e20 Material Green
Adjust 3#d91f89 Sunset Pink
NORMAL 4#00a3e9 Desert Sun Blue
VISUAL 5#878eff Solarized Purple
NRMLSHFT 6#219e20 Material Green
WINDOWZ 7#2e00e9 Sunset Blue/Purple
LGUI_ALL 8#ea1e63 Material Red

NRMLSHIFT and Raise having the same color as the dominant color is an accident that I’m too lazy to fix. They’ll never be accessible from the same layer, so I think that it’s fine.

Feedback (if anyone is listening)

After going through all of this, I’ve got some feedback.

  • The Wally GUI application was a tad more unreliable than I would’ve liked. Sometimes I would go to flash the board, the app would hang, and then every keyboard I used wouldn’t work until I rebooted. The wally-cli CLI tool was rock solid, though, and I’ve been using that for all of my flashing. Your mileage may vary.
  • Especially when I was in the midst of changing colors, I found it basically impossible to tell what color was already used from the per-key palettes when you selected a key. It’d be great if, when you selected a key in the UI, it’d also tell you what color you’ve assigned to that key.
  • The OSL() layer action can bring you to a layer, but it disables the key in that layer. This makes sense for layer actions like MO(), because the layer is only active when you are actively holding the key that got you there. However, for layer functions like OSL(), it’s perfectly fine to lift your finger off the key that got you into that layer, freeing that key up for other actions. This made things like a gg motion in the NORMAL layer (which I would’ve mapped to cmd+up) much more clumsy to implement with the UI, so I didn’t bother.

What’s next?

There are already multiple things that I want to improve upon for this layout.

  • Add some more actions into the Adjust layer; I basically ignored it heavily because I couldn’t think of anything, so this is ripe for improvement.
  • Come up with some more common Vim motions that I can accomplish without getting into macros; at a certain point, getting into macros will be inevitable, but using the GUI tool is so much easier than editing the keymap code (IMO) that I’m going to dread when I have to switch over.
  • Once I exhaust all available options to me in the UI, I want to start messing around with creating more complex macros. There were a few chords/motions that I created that definitely could have been more cleanly defined via macros, and that’s probably the next thing that I’d get around to messing with.
  • I want to investigate using leader keys with QMK. Especially coming from Spacemacs, this capability made me salivate; but I knew that it would be an unending hole of complexity and opportunities that I just avoided it altogether. Maybe the next time I have 5 solid days of playing around, I’ll do it, but right now… nope.

Anyway, that about wraps this up. For those of you that made it to the end, you get a virtual pat on the back, and permission to go and have a cookie!