Home Row Arrow Keys
Tags: ijkl, navigation, tooling
Published: 2019-10-25 23:44:50

---
title: Home Row Arrow Keys
published: true
description: How to get vim like navigation across all your applications.
tags: ijkl, navigation, tooling
---

## What are home row arrow keys?

Home row arrow keys are a way of remapping your keyboard to make navigating around your computer faster and more efficient. In this tutorial I will be remapping my `ijkl` keys to become my arrow keys (up, left, down, right) when I hold a specific `modifier` key. In this case `caps_lock`.

## Why is this a good thing?

Have you ever noticed how you actually type and move your cursor around files currently? You probably even find yourself reaching for your mouse quite frequently. Look at it carefully, you'll see you do a lot of hand context switching, moving from typing to navigating around back and forth, back and forth. I'm not sure about you, but for me at least, this context switching would cause a lot of issues and misspellings if I misplaced my hand even slightly when switching between the two modes.

To be honest, I never really thought of this as a major issue as it was just one of those things you had to deal with to use a computer. That is until an old coworker turned me onto _home row arrow keys_. He was seriously a wizard! We would pair program and his speed and efficiency moving around files, slicing/pasting text and typing were blazing fast! It was incredible! Even outside of his `ide` he was a ninja. Opening other programs, navigating around them, especially web browsing. I was astonished.

He was using a nifty mechanical keyboard and I assumed it was that but when he explained to me how he remapped his `ijkl` keys and that was how he was able to perform such fast actions I knew I had to try this out. He told me how to do it in a few easy steps and I've since refined it a bit but it's basically the exact same setup. Huge shout out to this wiz for changing my life and reducing the translation time from thought to computer action. You've saved me countless hours over the years, my dude!

## Getting Started

**DISCLAIMER: this is only for mac at this time, if you know how to set it up for windows or linux let me know I'm very interested!**

**If you just want a copy of json config file click [here](https://gist.github.com/gpynes/1ec21aa683980a8b8e3a14a4d6584feb)**

## Download and Install Karabiner-Elements

[Karabiner Elements](https://github.com/tekezo/Karabiner-Elements) is this amazing application that gives you a great and flexible way of remapping your keyboard layout. You can either build it from the source there or download the installer [here](https://pqrs.org/osx/karabiner/).

Once downloaded, go ahead and install it. You may need to give it some extra privileges depending on your configuration.

![Install Step One](https://res.cloudinary.com/dmpj0puyj/image/upload/v1566797555/HomeRow/1_Install_Step_One.png)
<br />
![Install Step Two](https://res.cloudinary.com/dmpj0puyj/image/upload/v1566797555/HomeRow/2_Install_Step_Two.png)

## Setup key remappings

We'll start by setting up a new `profile`. Open the app:
`cmd+spacebar` then type `karabiner-elements` and go to the app's `preferences`

![Opening Karabiner Elements](https://res.cloudinary.com/dmpj0puyj/image/upload/v1566797797/HomeRow/3_Opening_Karabiner_Elements.png)
<br />

From the menu screen select the `profiles` tab

![Profiles Tab Selected](https://res.cloudinary.com/dmpj0puyj/image/upload/v1566797554/HomeRow/5_Navigating_To_Profile.png)

Create a new profile and name it whatever you want.

![Create Profile Name](https://res.cloudinary.com/dmpj0puyj/image/upload/v1566797549/HomeRow/4_Creating_New_Profile.png)

Hit `enter` to save the name and then toggle to the new `profile`.

Open your `~/.config/karabiner` directory and you should now see a `karabiner.json` file. We will need to open and edit this file. (If it's not there, you can simply create it and copy in my config above.)

![Finder displaying karabiner.json location](https://res.cloudinary.com/dmpj0puyj/image/upload/v1566797555/HomeRow/6_Open_Json.png)

Looking through the file you should see that it contains a `profile` section with all the profile names listed in the profiles tab.

## Break down

Okay so this file may be a bit confusing at first but the key things here are the `complex_modifications` and `simple_modifications`.

You can think of `simple_modifications` as basic key remappings.
ie. change key `a` to act as key `b` etc.

The `complex_modifications` are macros. Combinations of keypresses that together, will perform certain actions.

### Simple Modification

Let's start with the `simple_modifications` that we need to change since that's an easy way to get more comfortable.

As you can see the `simple_modifications` is an array so let's add a new item to it.

```json
...
"simple_modifications": [
  {
    "from": {
      "key_code": "caps_lock"
    },
    "to": {
      "key_code": "left_control"
    }
  }
]
...
```

All we're saying here is that we want Karabiner to overwrite the `caps_lock` key (`"from"`) on our keyboard with `left_control` (`"to"`). (As far as I know you have to specify the control orientation and can't just do `control` for any kind of ctrl key.)

Once the file is saved. Use the profile selector to swap between `Default` and our new profile to refresh the changes. You should now see your `caps_lock` key now acts as your `ctrl` key.

Pretty `simple` right?

### Complex Modification

Alright with that out of the way let's get to the good stuff.

We're interested in the the `rules` section of the `complex_modifications`, we can ignore the `parameters` section for now. (But I do recommend looking that over at some point).

We are going to create a new rule, you can call it whatever you like but I named mine: `Change left_ctrl+jikl to arrow keys`

You can copy and paste this into the `rules` array:

```json
{
  "description": "Change left_ctrl+jikl to arrow keys",
  "manipulators": [
    {
      "from": {
        "key_code": "j",
        "modifiers": {
          "mandatory": ["left_control"],
          "optional": ["any"]
        }
      },
      "to": [
        {
          "key_code": "left_arrow"
        }
      ],
      "type": "basic"
    },
    {
      "from": {
        "key_code": "k",
        "modifiers": {
          "mandatory": ["left_control"],
          "optional": ["any"]
        }
      },
      "to": [
        {
          "key_code": "down_arrow"
        }
      ],
      "type": "basic"
    },
    {
      "from": {
        "key_code": "i",
        "modifiers": {
          "mandatory": ["left_control"],
          "optional": ["any"]
        }
      },
      "to": [
        {
          "key_code": "up_arrow"
        }
      ],
      "type": "basic"
    },
    {
      "from": {
        "key_code": "l",
        "modifiers": {
          "mandatory": ["left_control"],
          "optional": ["any"]
        }
      },
      "to": [
        {
          "key_code": "right_arrow"
        }
      ],
      "type": "basic"
    }
  ]
}
```

For this rule all we're saying is that for each of the `jikl` keys if they're pressed while `left_control` is pressed, make that key act as the corresponding arrow key. The `optional` parameter is necessary as it will map any additional modifiers to be allowed to be passed along to our combination as well. So things like `left_control + shift + j` will now act like `shift + left_arrow` etc.

Refresh the profile again and since we just remapped our `caps_lock` to be `left_control` you should now be able to navigate around your computer using `caps_lock + jikl`!

![Switch Profiles](https://res.cloudinary.com/dmpj0puyj/image/upload/v1566797550/HomeRow/7_Switch_Profiles.png)

If it's not working for you, you can copy and paste my settings into your `karabiner.json` file from this [link](https://gist.github.com/gpynes/1ec21aa683980a8b8e3a14a4d6584feb) and then refresh to see if it works.

# The End!

That's it! I hope you enjoyed this and that it helps speed up your workflow as much as it has mine. If you have any questions or comments for me feel free to leave them below.

Happy coding!

<br />
<br />
<br />

# Extra topics

## Why `ctrl` and not `fn`

Okay you may be thinking, why set `caps_lock` as `ctrl` and not `fn` or something more complex so it doesn't interfere with other key combos you rely on? That is a fair point and you're more than welcome to modify the json config to your liking. The reason I stick with `ctrl` is because Unix based OS's come with some built in navigation shortcuts automatically that utilize the `ctrl` key.

Some that I use all the time are `ctrl + a` and `ctrl + e` for navigating to the beginning and ending of a line easily. By swapping to `ctrl` and not something else I keep cursor navigation consistent across my entire computer, regardless of the application I'm in. (Try going to your url bar in your browser and hitting `ctrl + shift + e`)

Sortcut reference - https://www.computerhope.com/ushort.htm

## Downsides to the switch

There are some downsides to making this switch. I don't think they're big but they are worth noting:

### Becoming reliant on setup

By making this swap and becoming reliant on this setup I now find it hard to use other computers. Not terribly difficult, but I definitely start YELLING pretty quickly when I first start typing on someone else's computer. I then remember to use the real arrow keys and then it just feels uncomfortable to navigate around like someone has put weights on my thoughts.

### Reliant on third party app

When I first made the transition `Karabiner-Elements` wasn't around and it's predecessor `Karabiner` wasn't as easy to setup. It also didn't play as well with OSX and when I upgraded to Sierra it stopped working completely. This sucked and I got very scared I would have to go back to my old life of slow navigation. Thankfully elements was made with the intention of being long term, but it's still something to keep in mind that I am now dependent on this 3rd party application.