Thoughts of Keyboard.io

I was an original backer of the keyboard.io Kickstarter, and spent months and then years on a roller coaster ride with Jesse and Kaia and their ambitious plan to craft the ultimate keyboard. As a serious knerd (keyboard nerd) that has a few too many mechanical keyboards in his office, I couldn’t wait to use it.

looking_across_from_front_l_corner_grande.jpg

While all projects take longer than expected, good ones where the craftsman cares about the quality, require even more time. Now that I am finally typing this review on the keyboard, I am quite pleased with the results.

Product Quality

The combination of the switches and the wood enclosure gives the keyboard an amazingly solid feel. A simple gaze at the website will show you that the keyboard has a unique design, so it took a week to hone the angle and placement of the halves to fit my typing style. I initially assumed that I wanted them splayed at an angle that tented in the middle, but having the outside edges tilted up actually worked the best for me. Kudos to the unexpected, but ingenious design to have each half float on angled pads.

Support

The Model 1 comes in two flavors … loud and soft. As a long term Kinesis user, I appreciate the springiness typically associated with louder switches, but since I wanted one for my office, I decided to order one of each.

However, when it came time to fill in the form, I accidentally checked two loud keyboards, and didn’t realize this until the second had arrived. At first, I was confused and started with questions on the nice Community Forum. I suppose I shouldn’t be surprised that Jesse immediately contacted me and worked with me to get a different model. I couldn’t be happier with the experience.

Hacking

I love products that support and encourage hacking and personalizing, and this is one of the best keyboards for this. I actually got along for a month or so before I felt compelled to hack…that and I wasn’t sure if I wanted a OneShot-based program where the modifier keys were sticky (allowing me to type and release the Control and then the c to copy), or if wanted to double the modifiers so that if they were pressed and released on their own, they would send other keys to the system.

Eventually, I settled on a OneShot and then programmed the Butterfly and other keys for values that Emacs could use…but more about that later.

Along with fostering a community, they’ve been working hard at providing a rich series of tutorials for hacking aimed at non-programmers. Customizing involves downloading code and modules and then uploading this into the keyboard from an Arduino editor, and while this may appear daunting for some, I thought the tutorials were detailed enough, that I would recommend at least trying.

Issues and Concerns

This keyboard won’t be for everyone, so I’ll state a few concerns that people should be aware.

First, I realize that keycaps have their own subculture within the knerd community, and with this design, you can’t swap out the keycaps you grab from Massdrop. I found the supplied keycaps to be solid and attractive (especially since I’m more focused on programming the blinken lights), but I could be tempted if someone were to design a wood-colored keycap set.

Second, the loud version of the keyboard is…well, quite loud. If I’m on a conference call and forget to press the mute button, people duck under the table for fear of gunfire. During the Kickstarter Campaign, I ran into Jesse at OSCON, and he tried to talk me out of the loud keyboard. While I have gotten a bit used to it, I do wish I had purchased two quiet ones (so if anyone out there has one they feel is too quiet, I’ll gladly swap with you).

Third, the separate floating design (the butterfly wings) is great for personalizing it for your hands (and I even adjust the position during the day to minimize the fatigue), this makes it more difficult to transport. The solution for me was just to have two, so I haven’t attempted to throw them in my messenger bag.

Let’s Customize!

Notice that compared to other keyboards, all keys are within a smaller proximity to the home row keys (where de ol’ fingers rest). To compensate for what would be a smaller number of key options, this keyboard (and others like ErgoDox) subscribe to the notion of layers turned on either temporarily with a modifier key (like the palm placed Fn key) or toggled (like the num lock).

On a typical laptop keyboard, the Fn key is only associated with some keys (notably the Function keys). This means, you can play/pause your music on a Macbook with Fn-F8. While on the keyboard.io, this is bound to Fn-Enter, the Fn key can work with any other key.

Most of the application-associated keycodes are connected to keys on the right-side of the keyboard, leaving the left side to move the mouse. While moving the mouse seemed like a nice idea, the precision associated to placing the mouse on particular text drove me crazy. Replacing these, means I have a whole side of my keyboard that could be used for global shortcuts.

The problem I encountered was generating key codes my computer’s operating system recognized. While I tried various ideas, but finally settled on having Fn-z send a z with all the modifier keys pressed, i.e. Control, Option/Alt and Command:

LGUI(LALT(LCTRL(Key_Z)))

Next, I needed to have the operating system do something interesting with that keycode. Alfred allows you to associate various keybindings with applications, Applescripts and whatnot:

keyboardio-review-01.png

Now instead of using the Command-Tab to get to significant apps, I can easily pop over to my browser, emacs or corporate communications systems. For starting my browser, I use this AppleScript instead of Alfred’s Launcher:

set possurl to (the clipboard)
if possurl starts with "http" then
  tell application "Firefox"
    open location possurl
  end tell
end if

tell application "Firefox" to activate

If I have copied a URL to my clipboard and then use the Hotkey, then it automatically opens that URL in a new tab, otherwise, it just switches to it.

My current favorite keyboard-binding-to-fun, is binding the top-left key, labeled prog, to trigger a Applescript that selects the Zoom app, send it the Command-A sequence to toggle the mute button, and then return to the original app:

 set old to (path to frontmost application as text)

if old is not "zoom.us" then
   tell application "zoom.us" to activate
 end if

 tell application "System Events" to keystroke "a" using {shift down, command down}

 if old is not "zoom.us" then
   activate application old
 end if

Even though Zoom doesn’t offer a global way for me to mute the microphone while I’m both talking and taking notes in Emacs, I was able to solve this problem. I’m currently wondering if it is possible for me to have an application set particular leds on particular keys, so that I would know if my Zoom is or is not muted.

Emacs?

When I first saw the key layout for the keyboardio, I felt that this was a very vi-friendly keyboard. Since our collective love-hate relationship with browser-based applications, none of us are able to stay in either our VI or Emacs world exclusively, so having the arrow keys on the VI home row is brilliant. While everyone rebinds Escape to some keychord in Vi, having the Escape key as prominent as Tab or Return on the index finger is also quite nice.

Due to this, my friends and colleagues were shocked when I switched from Emacs to Vi bindings. No, I didn’t switch to Vi, I just use a Vi layer on top of Emacs, joining Dr. Pangloss in the best of all possible worlds.

That said, Jesse and Kaia gave me the greatest hacking temptation… three prominent keys in the center of the keyboard with no good default value: The famous Any key actually generates a random character, the LED cycles the backlit coloring program, and the cute butterfly key generates a Right-Alt.

Binding keys to cool functions is what Emacsians do, so I easily followed these instructions to have these keys send the extended function keys, and then added the following to my Emacs system:

;; Bind the prominent keys on my keyboard.io to useful functions:
(global-set-key (kbd "<f16>") 'er/expand-region)
(global-set-key (kbd "<f17>") 'special-return)
(global-set-key (kbd "<f18>") 'evil-avy-goto-char-timer)

Now, pressing the Butterfly key (that sends the F18 keycode) allows me to quickly jump to any word on the screen just by typing the first few letters of it, using the Avy project.

The led (F16) allows me to select text syntactically in greater chunks with repeated taps, using Magmar’s cool expand-region project.

When the region is active (due to the expand-region), the any key (that is just across from the led) acts in the opposite way, and shrinks the region to the previous size. If the region is not active, then the any key (next to the enter key) acts like a context-aware return key.

The code for that special-return is:

(defun special-return ()
  "Fancy return bound to a almost-return key. If in org-mode,
this inserts a new line of the same type as the current line (if
making a list, it makes a new list, etc). Otherwise, this inserts
a new blank line.

Note: If the region is active, this use the expand-region package
to shrink the region, essentially making an expand region
opposite key."
  (interactive)
  (if (region-active-p)
      (er/contract-region 1)
    (if (equal major-mode 'org-mode)
        (ha/org-special-return)
      (newline-for-code))))

Clearly, it doesn’t do much as it just calls out to other functions.

The newline-for-code is a simply function that allows me to hit return, but not split the current line:

(defun newline-for-code ()
  "Inserts a newline character, but from the end of the current line."
  (interactive)
  (move-end-of-line 1)
  (newline-and-indent))

However, the org-special-return is far more complicated, for within org-mode files:

  • If I’m currently entering a list of items, it creates a new list item element
  • If I’m entering a header, it creates a new header
  • If I’m in a table, it enters a new row, etc.

For the details of this function, check out my git repository.

Obviously, what I think is helpful and useful now, will change over time… but all the better to have a hackable keyboard that doesn’t require a special app to be installed in order to generate special features.

Emacs + Alfred?

As a prodigious user of Org, I often need to collect information while not actively in Emacs. I found a great idea to use some Emacs Lisp to run org-capture in a new frame. The end result looks like:

keyboardio-review-03.png

Since we’re talking about a graphical solution using the Emacs GUI, I wanted to start this process from any running application, therefore, an Alfred Workflow. I created a new workflow with a List Filter I could start with Fn-E (using a Shift):

keyboardio-review-05.png

When started, this displays a small list of choices (a subset of my entire org-capture collection):

keyboardio-review-04.png

Each option simply sends an argument to a script that does the work:

keyboardio-review-06.png

With standard -letter format, my script can be written in shell, and parse those options with getopts and specify the org-capture key:

while getopts "mnst" arg; do
  case $arg in
    m) ORGKEY=$arg;
       TITLE="Capture Meeting Notes";;
    n) ORGKEY=$arg;
       TITLE="Capture General Note";;
    s) ORGKEY=$arg;
       TITLE="Capture Daily Status";;
    t) ORGKEY=$arg;
       TITLE="Capture General Task";;
  esac
done

/usr/local/bin/emacsclient -c -n \
    -F "((title . \"${TITLE}\") (left . (+ 550)) (top . (+ 400)) (width . 110) (height . 12))" \
    -e "(progn (org-capture nil \"${ORGKEY}\") (delete-other-windows) (raise-frame) (x-focus-frame (selected-frame)))"

A simpler approach may be to just call org-capture and use its standard menu instead of Alfred’s list filter feature, but…

I suppose that was more about Alfred and Emacs than it was about using keyboard.io, however, my next hack is to have Emacs tell my keyboard which Evil mode is currently active and set the LEDs accordingly.

Summary

I really, really like this keyboard, and I am very glad that I purchased two for both home and office. Now that production runs are finalizing deliverables to Kickstarter Backers, I would encourage you to consider getting one.

Let me know if you have any questions, and I’ll try to answer them.

Date: 2018-03-22 March

Created: 2024-01-12 Fri 17:05