diff --git a/README.md b/README.md
index 6de16c23..c96cc3fe 100644
--- a/README.md
+++ b/README.md
@@ -43,133 +43,159 @@ While I find that these customizations yield a more-useful keyboard for me, they
These customizations currently provide a fraction of what I want from my more-useful keyboard.
I find it to be a very useful fraction, but I don't consider it complete by any means.
-Here's what it provides so far:
+## Features
-![Karabiner Change Key Configuration - 01](screenshots/karabiner-change-key-config-01.png)
+- [Access **control** and **escape** on the home row](#a-more-useful-caps-lock-key)
+- [Navigate (up/down/left/right) via the home row](#super-duper-mode)
+- [Navigate to previous/next word via the home row](#super-duper-mode)
+- [Arrange windows via the home row](#window-layout-mode)
+- [Enable other commonly-used actions on or near the home row](#miscellaneous-goodness)
+- [Format text as Markdown](#markdown-mode)
+- [Launch commonly-used apps via global keyboard shortcuts](#hyper-key-for-quickly-launching-apps)
+- [And more...](#miscellaneous-goodness)
-![Karabiner Change Key Configuration - 02](screenshots/karabiner-change-key-config-02.png)
+### A more useful caps lock key
-![Karabiner Change Key Configuration - 03](screenshots/karabiner-change-key-config-03.png)
+By repurposing the anachronistic **caps lock** key, we can make **control** and **escape** accessible via the home row.
-![Karabiner Change Key Configuration - 04](screenshots/karabiner-change-key-config-04.png)
+- Tap **caps lock** for **escape**
+- Hold **caps lock** for **control**
-## Dependencies
+### (S)uper (D)uper Mode
-This setup is honed and tested with the following dependencies.
+To activate, push the **s** and **d** keys simultaneously and hold them down. Now you're in (S)uper (D)uper Mode. It's like a secret keyboard _inside_ your keyboard. (Whoa.) It's optimized for keeping you on the home row, or very close to it. Now you can:
-- OS X El Capitan, 10.11
-- [Seil 12.1][seil]
-- [Karabiner 10.21][karabiner]
-- [SizeUp 1.7][sizeup] (optional)
+- Use **h**/**j**/**k**/**l** for **up**/**down**/**left**/**right** respectively
+- Use **a** for **option** (AKA **alt**)
+- Use **f** for **command**
+- Use **space** for **shift**
+- Use **a** + **j**/**k** for **page down**/**page up**
+- Use **i**/**o** to move to the previous/next tab
+- Use **u**/**p** to go to the first/last tab (in most apps)
+- Use **a** + **h**/**l** to move to previous/next word (in most apps)
-## The Setup
+[
](https://cloud.githubusercontent.com/assets/2988/22397420/f2b3e346-e53e-11e6-97bb-9db71f86994b.png)
-### Grab the bits
+### Window Layout Mode
-```sh
-git clone https://github.com/jasonrudolph/keyboard.git
+Quickly arrange and resize windows in common configurations, using keyboard shortcuts that are on or near the home row.
-cd keyboard
+Use **control** + **s** to turn on Window Layout Mode. Then, use any shortcut below to make windows do your bidding. For example, to send the window left, hit **control** + **s**, and then hit **h**.
-mkdir -p ~/Library/Application\ Support/Karabiner
+- Use **h** to send window left (left half of screen)
+- Use **j** to send window down (bottom half of screen)
+- Use **k** to send window up (top half of screen)
+- Use **l** to send window right (right half of screen)
+- Use **i** to send window to upper left quarter of screen
+- Use **o** to send window to upper right quarter of screen
+- Use **,** to send window to lower left quarter of screen
+- Use **.** to send window to lower right quarter of screen
+- Use **space** to send window to center of screen
+- Use **enter**: Resize window to fill the screen
+- Use **n** to send window to next monitor
+- Use **control** + **s** to exit Window Layout Mode without moving any windows
-# Prepare custom settings for Karabiner
-ln -s $PWD/karabiner/private.xml \
- ~/Library/Application\ Support/Karabiner/private.xml
+[
](https://cloud.githubusercontent.com/assets/2988/22397114/715cc12e-e538-11e6-9dcd-b3447af0d9dd.png) [
](https://cloud.githubusercontent.com/assets/2988/22397111/45672fe6-e538-11e6-905d-5b0234e290bb.png)
-ln -s $PWD/karabiner/ext \
- ~/Library/Application\ Support/Karabiner/ext
-```
+### Markdown Mode
-### Install the apps
+Perform common Markdown-formatting tasks anywhere that you're editing text (e.g. in a GitHub comment, in your editor, in your email client).
-- Install [Seil][seil]
-- Install [Karabiner][karabiner]
-- Install [SizeUp][sizeup] (optional)
+Use **control** + **m** to turn on Markdown Mode. Then, use any shortcut below to perform an action. For example, to wrap the selected text in double asterisks, hit **control** + **m**, and then **b**.
-### Put _control_ and _escape_ on the home row
+- Use **b** to wrap the currently-selected text in double asterisks ("B" for "Bold")
-#### Goals
+ Example: `**selection**`
-- Tap **caps lock** for **escape**
-- Hold **caps lock** for **control**
-- Access the default **caps lock** behavior in those rare cases where it's helpful
+- Use **i** to wrap the currently-selected text in single asterisks ("I" for "Italic")
-#### Making it happen
+ Example: `**selection**`
-1. Launch Seil.
-2. Enable the "Change Caps Lock" option, and map **caps lock** to keycode 80.
- (80 is **F19**. I don't have a physical **F19** key, so this setting will not
- conflict with any existing keys.)
- [[screenshot][seil-screenshot]]
-3. Launch Karabiner.
-4. In the "Change Key" tab, enable the "F19 to Escape/Control" option.
- [[screenshot][karabiner-change-key-screenshot-01]]
-5. In the "Change Key" tab, enable the "Double-tap Left Shift for CapsLock" option.
-6. In the "Key Repeat" tab, change the "[Key Overlaid Modifier] Timeout" to
- 300ms. (As [recommended][modern-space-cadet-key-repeat] by Steve Losh, I find
- that this avoids accidentally triggering **escape** when you meant to trigger
- **control**.)
- [[screenshot][karabiner-key-repeat-screenshot]]
+- Use **s** to wrap the currently-selected text in double tildes ("S" for "Strikethrough")
-### Unleash (S)uper (D)uper mode
+ Example: `~~selection~~`
-#### Goals
+- Use **l** to convert the currently-selected text to an inline link, using a URL from the clipboard ("L" for "Link")
-- Enable navigation (up/down/left/right) via the home row
-- Enable word navigation (option+left/right) via the home row
-- Enable other commonly-used actions on or near the home row
+ Example: `[selection](clipboard)`
-#### Making it happen
+- Use **control** + **m** to exit Markdown Mode without performing any actions
-1. Launch Karabiner.
-2. In the "Change Key" tab, enable the "(S)uper (D)uper Mode" option.
- [[screenshot][karabiner-change-key-screenshot-02]]
+### Hyper key for quickly launching apps
-### Control SizeUp from the home row
+macOS doesn't have a native **hyper** key. But thanks to Karabiner-Elements, we can [create our own](karabiner/karabiner.json).
-#### Goals
+In this setup, we'll use the **right option** key as our **hyper** key. With a new modifier key defined, we open a whole world of possibilities. I find it especially useful for providing global shortcuts for launching apps:
-- Quickly arrange and resize windows in common configurations, using keyboard
- shortcuts that are on or near the home row
+- **hyper** + **a** to open iTunes ("A" for "Apple Music")
+- **hyper** + **b** to open Google Chrome ("B" for "Browser")
+- **hyper** + **c** to open [Hackable Slack Client](https://github.com/bhuga/hackable-slack-client) ("C for "Chat")
+- **hyper** + **d** to open [Remember The Milk](https://www.rememberthemilk.com/) ("D" for "Do!" ... or "Done!")
+- **hyper** + **e** to open [Atom Beta](https://atom.io/beta) ("E" for "Editor")
+- **hyper** + **f** to open Finder ("F" for "Finder")
+- **hyper** + **g** to open [Mailplane](http://mailplaneapp.com/) ("G" for "Gmail")
+- **hyper** + **t** to open [iTerm2](https://www.iterm2.com/) ("T" for "Terminal")
-#### Making it happen
+Edit [`hammerspoon/hyper.lua`](hammerspoon/hyper.lua) to configure shortcuts to launch your most commonly-used apps.
-1. Launch Karabiner.
-2. In the "Change Key" tab, enable the "SizeUp Mode" option.
- [[screenshot][karabiner-change-key-screenshot-03]]
+### Miscellaneous goodness
-### Format text as Markdown
+- Use **control** + **-** (dash) to split iTerm2 panes horizontally
+- Use **control** + **|** (pipe) split iTerm2 panes vertically
+- Use **control** + **h**/**j**/**k**/**l** to move left/down/up/right by one pane in iTerm2
+- Use **control** + **u** to delete to the start of the line
+- Use **control** + **;** to delete to the end of the line
+- Use **option** + **h**/**l** to delete the previous/next word
-#### Goals
+## Dependencies
-- Perform common Markdown-formatting tasks anywhere that you're editing text
- (e.g. in a GitHub comment, in your editor, in your email client)
+This setup is honed and tested with the following dependencies.
-#### Making it happen
+- macOS Sierra, 10.12
+- [Karabiner-Elements 0.90.83][karabiner]
+- [Hammerspoon 0.9.52][hammerspoon]
-1. Launch Karabiner.
-2. In the "Change Key" tab, enable the "Markdown Mode" option.
- [[screenshot][karabiner-change-key-screenshot-04]]
+## Installation
-## TODO
+1. Grab the bits
+
+ ```sh
+ git clone https://github.com/jasonrudolph/keyboard.git
-- Document usage of "Hyper" key
-- Incorporate [Keyboard Maestro][keyboard-maestro] configuration
-- Add `./script/setup` command to automate the manual setup steps
+ cd keyboard
+
+ # Prepare custom settings for Karabiner-Elements
+ mkdir -p ~/.config/karabiner/
+ ln -s $PWD/karabiner/karabiner.json ~/.config/karabiner/karabiner.json
+
+ # Prepare custom settings for Hammerspoon
+ ln -s $PWD/hammerspoon ~/.hammerspoon
+
+ # Prepare custom settings for navigating between words in iTerm2
+ cat $PWD/inputrc >> ~/.inputrc
+ ```
+
+2. Install [Karabiner-Elements][karabiner]
+
+ 1. Install it
+ 2. Launch it
+ 3. Configure it to launch at login [[screenshot](screenshots/login-items-for-karabiner-and-hammerspoon.png)]
+
+3. Install [Hammerspoon][hammerspoon-releases]
+
+ 1. Install it
+ 2. Launch it
+ 3. Configure it to launch at login [[screenshot](screenshots/login-items-for-karabiner-and-hammerspoon.png)]
+ 4. Enable accessibility to allow Hammerspoon to do its thing [[screenshot]](screenshots/accessibility-permissions-for-hammerspoon.png)
+
+## TODO
+- [ ] Add `./script/setup` command to automate the manual setup steps
[customize]: http://dictionary.reference.com/browse/customize
[don't-make-me-think]: http://en.wikipedia.org/wiki/Don't_Make_Me_Think
-[keyboard-maestro]: http://keyboardmaestro.com
-[karabiner]: http://pqrs.org/macosx/karabiner/
-[karabiner-change-key-screenshot-01]: screenshots/karabiner-change-key-config-01.png
-[karabiner-change-key-screenshot-02]: screenshots/karabiner-change-key-config-02.png
-[karabiner-change-key-screenshot-03]: screenshots/karabiner-change-key-config-03.png
-[karabiner-change-key-screenshot-04]: screenshots/karabiner-change-key-config-04.png
-[karabiner-key-repeat-screenshot]: screenshots/karabiner-key-repeat-config.png
+[karabiner]: https://github.com/tekezo/Karabiner-Elements
+[hammerspoon]: http://www.hammerspoon.org
+[hammerspoon-releases]: https://github.com/Hammerspoon/hammerspoon/releases
[modern-space-cadet]: http://stevelosh.com/blog/2012/10/a-modern-space-cadet
[modern-space-cadet-key-repeat]: http://stevelosh.com/blog/2012/10/a-modern-space-cadet/#controlescape
-[seil]: https://pqrs.org/macosx/keyremap4macbook/seil.html.en
-[seil-screenshot]: screenshots/seil-config.png
-[sizeup]: http://www.irradiatedsoftware.com/sizeup/
diff --git a/hammerspoon/control-escape.lua b/hammerspoon/control-escape.lua
new file mode 100644
index 00000000..e91f1c4b
--- /dev/null
+++ b/hammerspoon/control-escape.lua
@@ -0,0 +1,43 @@
+-- Credit for this implementation goes to @arbelt and @jasoncodes 🙇⚡️😻
+--
+-- https://gist.github.com/arbelt/b91e1f38a0880afb316dd5b5732759f1
+-- https://github.com/jasoncodes/dotfiles/blob/ac9f3ac/hammerspoon/control_escape.lua
+
+send_escape = false
+last_mods = {}
+
+control_key_handler = function()
+ send_escape = false
+end
+
+control_key_timer = hs.timer.delayed.new(0.15, control_key_handler)
+
+control_handler = function(evt)
+ local new_mods = evt:getFlags()
+ if last_mods["ctrl"] == new_mods["ctrl"] then
+ return false
+ end
+ if not last_mods["ctrl"] then
+ last_mods = new_mods
+ send_escape = true
+ control_key_timer:start()
+ else
+ if send_escape then
+ keyUpDown({}, 'escape')
+ end
+ last_mods = new_mods
+ control_key_timer:stop()
+ end
+ return false
+end
+
+control_tap = hs.eventtap.new({hs.eventtap.event.types.flagsChanged}, control_handler)
+control_tap:start()
+
+other_handler = function(evt)
+ send_escape = false
+ return false
+end
+
+other_tap = hs.eventtap.new({hs.eventtap.event.types.keyDown}, other_handler)
+other_tap:start()
diff --git a/hammerspoon/delete-words.lua b/hammerspoon/delete-words.lua
new file mode 100644
index 00000000..c43a5bd0
--- /dev/null
+++ b/hammerspoon/delete-words.lua
@@ -0,0 +1,70 @@
+local log = hs.logger.new('delete-words.lua', 'debug')
+
+local isInTerminal = function()
+ app = hs.application.frontmostApplication():name()
+ return app == 'iTerm2' or app == 'Terminal'
+end
+
+-- Use option + h to delete previous word
+hs.hotkey.bind({'alt'}, 'h', function()
+ if isInTerminal() then
+ keyUpDown({'ctrl'}, 'w')
+ else
+ keyUpDown({'alt'}, 'delete')
+ end
+end)
+
+-- Use option + l to delete next word
+hs.hotkey.bind({'alt'}, 'l', function()
+ if isInTerminal() then
+ keyUpDown({}, 'escape')
+ keyUpDown({}, 'd')
+ else
+ keyUpDown({'alt'}, 'forwarddelete')
+ end
+end)
+
+-- Use control + u to delete to beginning of line
+--
+-- In bash, control + u automatically deletes to the beginning of the line, so
+-- we don't need (or want) this hotkey in the terminal. If this hotkey was
+-- enabled in the terminal, it would break the standard control + u behavior.
+-- Therefore, we only enable this hotkey for non-terminal apps.
+local wf = hs.window.filter.new():setFilters({iTerm2 = false, Terminal = false})
+enableHotkeyForWindowsMatchingFilter(wf, hs.hotkey.new({'ctrl'}, 'u', function()
+ keyUpDown({'cmd'}, 'delete')
+end))
+
+-- Use control + ; to delete to end of line
+--
+-- I prefer to use control+h/j/k/l to move left/down/up/right by one pane in all
+-- multi-pane apps (e.g., iTerm, various editors). That's convenient and
+-- consistent, but it conflicts with the default macOS binding for deleting to
+-- the end of the line (i.e., control+k). To maintain that very useful
+-- functionality, and to keep it on the home row, this hotkey binds control+; to
+-- delete to the end of the line.
+hs.hotkey.bind({'ctrl'}, ';', function()
+ -- If we're in the terminal, then temporarily disable our custom control+k
+ -- hotkey used for pane navigation, then fire control+k to delete to the end
+ -- of the line, and then renable the control+k hotkey.
+ --
+ -- If we're not in the terminal, then just select to the end of the line and
+ -- then delete the selected text.
+ if isInTerminal() then
+ hotkeyForControlK = hs.fnutils.find(hs.hotkey.getHotkeys(), function(hotkey)
+ return hotkey.idx == '⌃K'
+ end)
+ if hotkeyForControlK then hotkeyForControlK:disable() end
+
+ keyUpDown({'ctrl'}, 'k')
+
+ -- Allow some time for the control+k keystroke to fire asynchronously before
+ -- we re-enable our custom control+k hotkey.
+ hs.timer.doAfter(0.2, function()
+ if hotkeyForControlK then hotkeyForControlK:enable() end
+ end)
+ else
+ keyUpDown({'cmd', 'shift'}, 'right')
+ keyUpDown({}, 'forwarddelete')
+ end
+end)
diff --git a/hammerspoon/hyper.lua b/hammerspoon/hyper.lua
new file mode 100644
index 00000000..2b9f106b
--- /dev/null
+++ b/hammerspoon/hyper.lua
@@ -0,0 +1,33 @@
+-- A global variable for Hyper Mode
+hyperMode = hs.hotkey.modal.new({}, 'F18')
+
+-- Keybindings for launching apps in Hyper Mode
+hyperModeAppMappings = {
+ { 'a', 'iTunes' }, -- "A" for "Apple Music"
+ { 'b', 'Google Chrome' }, -- "B" for "Browser"
+ { 'c', 'Hackable Slack Client' }, -- "C for "Chat"
+ { 'd', 'Remember The Milk' }, -- "D" for "Do!" ... or "Done!"
+ { 'e', 'Atom Beta' }, -- "E" for "Editor"
+ { 'f', 'Finder' }, -- "F" for "Finder"
+ { 'g', 'Mailplane 3' }, -- "G" for "Gmail"
+ { 't', 'iTerm' }, -- "T" for "Terminal"
+}
+
+for i, mapping in ipairs(hyperModeAppMappings) do
+ hyperMode:bind({}, mapping[1], function()
+ hs.application.launchOrFocus(mapping[2])
+ end)
+end
+
+-- Enter Hyper Mode when F17 (right option key) is pressed
+pressedF17 = function()
+ hyperMode:enter()
+end
+
+-- Leave Hyper Mode when F17 (right option key) is released.
+releasedF17 = function()
+ hyperMode:exit()
+end
+
+-- Bind the Hyper key
+f17 = hs.hotkey.bind({}, 'F17', pressedF17, releasedF17)
diff --git a/hammerspoon/init.lua b/hammerspoon/init.lua
new file mode 100644
index 00000000..9be6a3e3
--- /dev/null
+++ b/hammerspoon/init.lua
@@ -0,0 +1,41 @@
+local log = hs.logger.new('init.lua', 'debug')
+
+-- Use Control+` to reload Hammerspoon config
+hs.hotkey.bind({'ctrl'}, '`', nil, function()
+ hs.reload()
+end)
+
+keyUpDown = function(modifiers, key)
+ -- Un-comment & reload config to log each keystroke that we're triggering
+ -- log.d('Sending keystroke:', hs.inspect(modifiers), key)
+ hs.eventtap.keyStroke(modifiers, key, 0)
+end
+
+-- Subscribe to the necessary events on the given window filter such that the
+-- given hotkey is enabled for windows that match the window filter and disabled
+-- for windows that don't match the window filter.
+--
+-- windowFilter - An hs.window.filter object describing the windows for which
+-- the hotkey should be enabled.
+-- hotkey - The hs.hotkey object to enable/disable.
+--
+-- Returns nothing.
+enableHotkeyForWindowsMatchingFilter = function(windowFilter, hotkey)
+ windowFilter:subscribe(hs.window.filter.windowFocused, function()
+ hotkey:enable()
+ end)
+
+ windowFilter:subscribe(hs.window.filter.windowUnfocused, function()
+ hotkey:disable()
+ end)
+end
+
+require('control-escape')
+require('delete-words')
+require('hyper')
+require('markdown')
+require('panes')
+require('super')
+require('windows')
+
+hs.notify.new({title='Hammerspoon', informativeText='Ready to rock 🤘'}):send()
diff --git a/hammerspoon/markdown.lua b/hammerspoon/markdown.lua
new file mode 100644
index 00000000..1945b22b
--- /dev/null
+++ b/hammerspoon/markdown.lua
@@ -0,0 +1,107 @@
+function wrapSelectedText(wrapCharacters)
+ -- Preserve the current contents of the system clipboard
+ local originalClipboardContents = hs.pasteboard.getContents()
+
+ -- Copy the currently-selected text to the system clipboard
+ keyUpDown('cmd', 'c')
+
+ -- Allow some time for the command+c keystroke to fire asynchronously before
+ -- we try to read from the clipboard
+ hs.timer.doAfter(0.2, function()
+ -- Construct the formatted output and paste it over top of the
+ -- currently-selected text
+ local selectedText = hs.pasteboard.getContents()
+ local wrappedText = wrapCharacters .. selectedText .. wrapCharacters
+ hs.pasteboard.setContents(wrappedText)
+ keyUpDown('cmd', 'v')
+
+ -- Allow some time for the command+v keystroke to fire asynchronously before
+ -- we restore the original clipboard
+ hs.timer.doAfter(0.2, function()
+ hs.pasteboard.setContents(originalClipboardContents)
+ end)
+ end)
+end
+
+function inlineLink()
+ -- Fetch URL from the system clipboard
+ local linkUrl = hs.pasteboard.getContents()
+
+ -- Copy the currently-selected text to use as the link text
+ keyUpDown('cmd', 'c')
+
+ -- Allow some time for the command+c keystroke to fire asynchronously before
+ -- we try to read from the clipboard
+ hs.timer.doAfter(0.2, function()
+ -- Construct the formatted output and paste it over top of the
+ -- currently-selected text
+ local linkText = hs.pasteboard.getContents()
+ local markdown = '[' .. linkText .. '](' .. linkUrl .. ')'
+ hs.pasteboard.setContents(markdown)
+ keyUpDown('cmd', 'v')
+
+ -- Allow some time for the command+v keystroke to fire asynchronously before
+ -- we restore the original clipboard
+ hs.timer.doAfter(0.2, function()
+ hs.pasteboard.setContents(originalClipboardContents)
+ end)
+ end)
+end
+
+--------------------------------------------------------------------------------
+-- Define Markdown Mode
+--
+-- Markdown Mode allows you to perform common Markdown-formatting tasks anywhere
+-- that you're editing text. Use Control+m to turn on Markdown mode. Then, use
+-- any shortcut below to perform a formatting action. For example, to wrap the
+-- selected text in double asterisks, hit Control+m, and then b.
+--
+-- b => wrap the selected text in double asterisks ("b" for "bold")
+-- i => wrap the selected text in single asterisks ("i" for "italic")
+-- s => wrap the selected text in double tildes ("s" for "strikethrough")
+-- l => convert the currently-selected text to an inline link, using a URL
+-- from the clipboard ("l" for "link")
+--------------------------------------------------------------------------------
+
+markdownMode = hs.hotkey.modal.new({}, 'F20')
+
+local message = require('status-message')
+markdownMode.statusMessage = message.new('Markdown Mode (control-m)')
+markdownMode.entered = function()
+ markdownMode.statusMessage:show()
+end
+markdownMode.exited = function()
+ markdownMode.statusMessage:hide()
+end
+
+-- Bind the given key to call the given function and exit Markdown mode
+function markdownMode.bindWithAutomaticExit(mode, key, fn)
+ mode:bind({}, key, function()
+ mode:exit()
+ fn()
+ end)
+end
+
+markdownMode:bindWithAutomaticExit('b', function()
+ wrapSelectedText('**')
+end)
+
+markdownMode:bindWithAutomaticExit('i', function()
+ wrapSelectedText('*')
+end)
+
+markdownMode:bindWithAutomaticExit('s', function()
+ wrapSelectedText('~~')
+end)
+
+markdownMode:bindWithAutomaticExit('l', function()
+ inlineLink()
+end)
+
+-- Use Control+m to toggle Markdown Mode
+hs.hotkey.bind({'ctrl'}, 'm', function()
+ markdownMode:enter()
+end)
+markdownMode:bind({'ctrl'}, 'm', function()
+ markdownMode:exit()
+end)
diff --git a/hammerspoon/panes.lua b/hammerspoon/panes.lua
new file mode 100644
index 00000000..cc31ffe6
--- /dev/null
+++ b/hammerspoon/panes.lua
@@ -0,0 +1,43 @@
+local itermHotkeyMappings = {
+ -- Use control + dash to split panes horizontally
+ {
+ from = {{'ctrl'}, '-'},
+ to = {{'cmd', 'shift'}, 'd'}
+ },
+
+ -- Use control + pipe to split panes vertically
+ {
+ from = {{'ctrl', 'shift'}, '\\'},
+ to = {{'cmd'}, 'd'}
+ },
+
+ -- Use control + h/j/k/l to move left/down/up/right by one pane
+ {
+ from = {{'ctrl'}, 'h'},
+ to = {{'cmd', 'alt'}, 'left'}
+ },
+ {
+ from = {{'ctrl'}, 'j'},
+ to = {{'cmd', 'alt'}, 'down'}
+ },
+ {
+ from = {{'ctrl'}, 'k'},
+ to = {{'cmd', 'alt'}, 'up'}
+ },
+ {
+ from = {{'ctrl'}, 'l'},
+ to = {{'cmd', 'alt'}, 'right'}
+ },
+}
+
+local terminalWindowFilter = hs.window.filter.new('iTerm2')
+local itermHotkeys = hs.fnutils.each(itermHotkeyMappings, function(mapping)
+ local fromMods = mapping['from'][1]
+ local fromKey = mapping['from'][2]
+ local toMods = mapping['to'][1]
+ local toKey = mapping['to'][2]
+ local hotkey = hs.hotkey.new(fromMods, fromKey, function()
+ keyUpDown(toMods, toKey)
+ end)
+ enableHotkeyForWindowsMatchingFilter(terminalWindowFilter, hotkey)
+end)
diff --git a/hammerspoon/status-message.lua b/hammerspoon/status-message.lua
new file mode 100644
index 00000000..f317de8b
--- /dev/null
+++ b/hammerspoon/status-message.lua
@@ -0,0 +1,62 @@
+local drawing = require 'hs.drawing'
+local geometry = require 'hs.geometry'
+local screen = require 'hs.screen'
+local styledtext = require 'hs.styledtext'
+
+local statusmessage = {}
+statusmessage.new = function(messageText)
+ local buildParts = function(messageText)
+ local frame = screen.primaryScreen():frame()
+
+ local styledTextAttributes = {
+ font = { name = 'Monaco', size = 24 },
+ }
+
+ local styledText = styledtext.new('🔨 ' .. messageText, styledTextAttributes)
+
+ local styledTextSize = drawing.getTextDrawingSize(styledText)
+ local textRect = {
+ x = frame.w - styledTextSize.w - 40,
+ y = frame.h - styledTextSize.h,
+ w = styledTextSize.w + 40,
+ h = styledTextSize.h + 40,
+ }
+ local text = drawing.text(textRect, styledText):setAlpha(0.7)
+
+ local background = drawing.rectangle(
+ {
+ x = frame.w - styledTextSize.w - 45,
+ y = frame.h - styledTextSize.h - 3,
+ w = styledTextSize.w + 15,
+ h = styledTextSize.h + 6
+ }
+ )
+ background:setRoundedRectRadii(10, 10)
+ background:setFillColor({ red = 0, green = 0, blue = 0, alpha=0.6 })
+
+ return background, text
+ end
+
+ return {
+ _buildParts = buildParts,
+ show = function(self)
+ self:hide()
+
+ self.background, self.text = self._buildParts(messageText)
+ self.background:show()
+ self.text:show()
+ end,
+ hide = function(self)
+ if self.background then
+ self.background:delete()
+ self.background = nil
+ end
+ if self.text then
+ self.text:delete()
+ self.text = nil
+ end
+ end
+ }
+end
+
+return statusmessage
diff --git a/hammerspoon/super.lua b/hammerspoon/super.lua
new file mode 100644
index 00000000..5d0cdd89
--- /dev/null
+++ b/hammerspoon/super.lua
@@ -0,0 +1,164 @@
+local eventtap = hs.eventtap
+local eventTypes = hs.eventtap.event.types
+local message = require('status-message')
+
+-- If 's' and 'd' are *both* pressed within this time period, consider this to
+-- mean that they've been pressed simultaneously, and therefore we should enter
+-- Super Duper Mode.
+local MAX_TIME_BETWEEN_SIMULTANEOUS_KEY_PRESSES = 0.02 -- 20 milliseconds
+
+local superDuperMode = {
+ statusMessage = message.new('(S)uper (D)uper Mode'),
+ enter = function(self)
+ if not self.active then self.statusMessage:show() end
+ self.active = true
+ end,
+ reset = function(self)
+ self.active = false
+ self.isSDown = false
+ self.isDDown = false
+ self.ignoreNextS = false
+ self.ignoreNextD = false
+ self.modifiers = {}
+ self.statusMessage:hide()
+ end,
+}
+superDuperMode:reset()
+
+superDuperModeActivationListener = eventtap.new({ eventTypes.keyDown }, function(event)
+ -- If 's' or 'd' is pressed in conjuction with any modifier keys
+ -- (e.g., command+s), then we're not activating Super Duper Mode.
+ if not (next(event:getFlags()) == nil) then
+ return false
+ end
+
+ local characters = event:getCharacters()
+
+ if characters == 's' then
+ if superDuperMode.ignoreNextS then
+ superDuperMode.ignoreNextS = false
+ return false
+ end
+ -- Temporarily suppress this 's' keystroke. At this point, we're not sure if
+ -- the user intends to type an 's', or if the user is attempting to activate
+ -- Super Duper Mode. If 'd' is pressed by the time the following function
+ -- executes, then activate Super Duper Mode. Otherwise, trigger an ordinary
+ -- 's' keystroke.
+ superDuperMode.isSDown = true
+ hs.timer.doAfter(MAX_TIME_BETWEEN_SIMULTANEOUS_KEY_PRESSES, function()
+ if superDuperMode.isDDown then
+ superDuperMode:enter()
+ else
+ superDuperMode.ignoreNextS = true
+ keyUpDown({}, 's')
+ return false
+ end
+ end)
+ return true
+ elseif characters == 'd' then
+ if superDuperMode.ignoreNextD then
+ superDuperMode.ignoreNextD = false
+ return false
+ end
+ -- Temporarily suppress this 'd' keystroke. At this point, we're not sure if
+ -- the user intends to type a 'd', or if the user is attempting to activate
+ -- Super Duper Mode. If 's' is pressed by the time the following function
+ -- executes, then activate Super Duper Mode. Otherwise, trigger an ordinary
+ -- 'd' keystroke.
+ superDuperMode.isDDown = true
+ hs.timer.doAfter(MAX_TIME_BETWEEN_SIMULTANEOUS_KEY_PRESSES, function()
+ if superDuperMode.isSDown then
+ superDuperMode:enter()
+ else
+ superDuperMode.ignoreNextD = true
+ keyUpDown({}, 'd')
+ return false
+ end
+ end)
+ return true
+ end
+end):start()
+
+superDuperModeDeactivationListener = eventtap.new({ eventTypes.keyUp }, function(event)
+ local characters = event:getCharacters()
+ if characters == 's' or characters == 'd' then
+ superDuperMode:reset()
+ end
+end):start()
+
+--------------------------------------------------------------------------------
+-- Watch for key down/up events that represent modifiers in Super Duper Mode
+--------------------------------------------------------------------------------
+superDuperModeModifierKeyListener = eventtap.new({ eventTypes.keyDown, eventTypes.keyUp }, function(event)
+ if not superDuperMode.active then
+ return false
+ end
+
+ local charactersToModifers = {}
+ charactersToModifers['a'] = 'alt'
+ charactersToModifers['f'] = 'cmd'
+ charactersToModifers[' '] = 'shift'
+
+ local modifier = charactersToModifers[event:getCharacters()]
+ if modifier then
+ if (event:getType() == eventTypes.keyDown) then
+ superDuperMode.modifiers[modifier] = true
+ else
+ superDuperMode.modifiers[modifier] = nil
+ end
+ return true
+ end
+end):start()
+
+--------------------------------------------------------------------------------
+-- Watch for h/j/k/l key down events in Super Duper Mode, and trigger the
+-- corresponding arrow key events
+--------------------------------------------------------------------------------
+superDuperModeNavListener = eventtap.new({ eventTypes.keyDown }, function(event)
+ if not superDuperMode.active then
+ return false
+ end
+
+ local charactersToKeystrokes = {
+ h = 'left',
+ j = 'down',
+ k = 'up',
+ l = 'right',
+ }
+
+ local keystroke = charactersToKeystrokes[event:getCharacters()]
+ if keystroke then
+ local modifiers = {}
+ n = 0
+ for k, v in pairs(superDuperMode.modifiers) do
+ n = n + 1
+ modifiers[n] = k
+ end
+
+ keyUpDown(modifiers, keystroke)
+ return true
+ end
+end):start()
+
+--------------------------------------------------------------------------------
+-- Watch for i/o key down events in Super Duper Mode, and trigger the
+-- corresponding key events to navigate to the previous/next tab respectively
+--------------------------------------------------------------------------------
+superDuperModeTabNavKeyListener = eventtap.new({ eventTypes.keyDown }, function(event)
+ if not superDuperMode.active then
+ return false
+ end
+
+ local charactersToKeystrokes = {
+ u = { {'cmd'}, '1' }, -- go to first tab
+ i = { {'cmd', 'shift'}, '[' }, -- go to previous tab
+ o = { {'cmd', 'shift'}, ']' }, -- go to next tab
+ p = { {'cmd'}, '9' }, -- go to last tab
+ }
+ local keystroke = charactersToKeystrokes[event:getCharacters()]
+
+ if keystroke then
+ keyUpDown(table.unpack(keystroke))
+ return true
+ end
+end):start()
diff --git a/hammerspoon/windows.lua b/hammerspoon/windows.lua
new file mode 100644
index 00000000..2b90ccda
--- /dev/null
+++ b/hammerspoon/windows.lua
@@ -0,0 +1,257 @@
+hs.window.animationDuration = 0
+
+-- +-----------------+
+-- | | |
+-- | HERE | |
+-- | | |
+-- +-----------------+
+function hs.window.left(win)
+ local f = win:frame()
+ local screen = win:screen()
+ local max = screen:frame()
+
+ f.x = max.x
+ f.y = max.y
+ f.w = max.w / 2
+ f.h = max.h
+ win:setFrame(f)
+end
+
+-- +-----------------+
+-- | | |
+-- | | HERE |
+-- | | |
+-- +-----------------+
+function hs.window.right(win)
+ local f = win:frame()
+ local screen = win:screen()
+ local max = screen:frame()
+
+ f.x = max.x + (max.w / 2)
+ f.y = max.y
+ f.w = max.w / 2
+ f.h = max.h
+ win:setFrame(f)
+end
+
+-- +-----------------+
+-- | HERE |
+-- +-----------------+
+-- | |
+-- +-----------------+
+function hs.window.up(win)
+ local f = win:frame()
+ local screen = win:screen()
+ local max = screen:frame()
+
+ f.x = max.x
+ f.w = max.w
+ f.y = max.y
+ f.h = max.h / 2
+ win:setFrame(f)
+end
+
+-- +-----------------+
+-- | |
+-- +-----------------+
+-- | HERE |
+-- +-----------------+
+function hs.window.down(win)
+ local f = win:frame()
+ local screen = win:screen()
+ local max = screen:frame()
+
+ f.x = max.x
+ f.w = max.w
+ f.y = max.y + (max.h / 2)
+ f.h = max.h / 2
+ win:setFrame(f)
+end
+
+-- +-----------------+
+-- | HERE | |
+-- +--------+ |
+-- | |
+-- +-----------------+
+function hs.window.upLeft(win)
+ local f = win:frame()
+ local screen = win:screen()
+ local max = screen:fullFrame()
+
+ f.x = 0
+ f.y = 0
+ f.w = max.w/2
+ f.h = max.h/2
+ win:setFrame(f)
+end
+
+-- +-----------------+
+-- | |
+-- +--------+ |
+-- | HERE | |
+-- +-----------------+
+function hs.window.downLeft(win)
+ local f = win:frame()
+ local screen = win:screen()
+ local max = screen:fullFrame()
+
+ f.x = 0
+ f.y = max.h/2
+ f.w = max.w/2
+ f.h = max.h/2
+ win:setFrame(f)
+end
+
+-- +-----------------+
+-- | |
+-- | +--------|
+-- | | HERE |
+-- +-----------------+
+function hs.window.downRight(win)
+ local f = win:frame()
+ local screen = win:screen()
+ local max = screen:fullFrame()
+
+ f.x = max.w/2
+ f.y = max.h/2
+ f.w = max.w/2
+ f.h = max.h/2
+
+ win:setFrame(f)
+end
+
+-- +-----------------+
+-- | | HERE |
+-- | +--------|
+-- | |
+-- +-----------------+
+function hs.window.upRight(win)
+ local f = win:frame()
+ local screen = win:screen()
+ local max = screen:fullFrame()
+
+ f.x = max.w/2
+ f.y = 0
+ f.w = max.w/2
+ f.h = max.h/2
+ win:setFrame(f)
+end
+
+-- +--------------+
+-- | | | |
+-- | | HERE | |
+-- | | | |
+-- +---------------+
+function hs.window.centerWithFullHeight(win)
+ local f = win:frame()
+ local screen = win:screen()
+ local max = screen:fullFrame()
+
+ f.x = max.w * 1/5
+ f.w = max.w * 3/5
+ f.y = max.y
+ f.h = max.h
+ win:setFrame(f)
+end
+
+function hs.window.nextScreen(win)
+ local currentScreen = win:screen()
+ local allScreens = hs.screen.allScreens()
+ currentScreenIndex = hs.fnutils.indexOf(allScreens, currentScreen)
+ nextScreenIndex = currentScreenIndex + 1
+
+ if allScreens[nextScreenIndex] then
+ win:moveToScreen(allScreens[nextScreenIndex])
+ else
+ win:moveToScreen(allScreens[1])
+ end
+end
+
+--------------------------------------------------------------------------------
+-- Define WindowLayout Mode
+--
+-- WindowLayout Mode allows you to manage window layout using keyboard shortcuts
+-- that are on the home row, or very close to it. Use Control+s to turn
+-- on WindowLayout mode. Then, use any shortcut below to perform a window layout
+-- action. For example, to send the window left, press and release
+-- Control+s, and then press h.
+--
+-- h/j/k/l => send window to the left/bottom/top/right half of the screen
+-- i => send window to the upper left quarter of the screen
+-- o => send window to the upper right quarter of the screen
+-- , => send window to the lower left quarter of the screen
+-- . => send window to the lower right quarter of the screen
+-- return => make window full screen
+-- n => send window to the next monitor
+--------------------------------------------------------------------------------
+
+windowLayoutMode = hs.hotkey.modal.new({}, 'F16')
+
+local message = require('status-message')
+windowLayoutMode.statusMessage = message.new('Window Layout Mode (control-s)')
+windowLayoutMode.entered = function()
+ windowLayoutMode.statusMessage:show()
+end
+windowLayoutMode.exited = function()
+ windowLayoutMode.statusMessage:hide()
+end
+
+-- Bind the given key to call the given function and exit WindowLayout mode
+function windowLayoutMode.bindWithAutomaticExit(mode, key, fn)
+ mode:bind({}, key, function()
+ mode:exit()
+ fn()
+ end)
+end
+
+windowLayoutMode:bindWithAutomaticExit('return', function()
+ hs.window.focusedWindow():maximize()
+end)
+
+windowLayoutMode:bindWithAutomaticExit('space', function()
+ hs.window.focusedWindow():centerWithFullHeight()
+end)
+
+windowLayoutMode:bindWithAutomaticExit('h', function()
+ hs.window.focusedWindow():left()
+end)
+
+windowLayoutMode:bindWithAutomaticExit('j', function()
+ hs.window.focusedWindow():down()
+end)
+
+windowLayoutMode:bindWithAutomaticExit('k', function()
+ hs.window.focusedWindow():up()
+end)
+
+windowLayoutMode:bindWithAutomaticExit('l', function()
+ hs.window.focusedWindow():right()
+end)
+
+windowLayoutMode:bindWithAutomaticExit('i', function()
+ hs.window.focusedWindow():upLeft()
+end)
+
+windowLayoutMode:bindWithAutomaticExit('o', function()
+ hs.window.focusedWindow():upRight()
+end)
+
+windowLayoutMode:bindWithAutomaticExit(',', function()
+ hs.window.focusedWindow():downLeft()
+end)
+
+windowLayoutMode:bindWithAutomaticExit('.', function()
+ hs.window.focusedWindow():downRight()
+end)
+
+windowLayoutMode:bindWithAutomaticExit('n', function()
+ hs.window.focusedWindow():nextScreen()
+end)
+
+-- Use Control+s to toggle WindowLayout Mode
+hs.hotkey.bind({'ctrl'}, 's', function()
+ windowLayoutMode:enter()
+end)
+windowLayoutMode:bind({'ctrl'}, 's', function()
+ windowLayoutMode:exit()
+end)
diff --git a/inputrc b/inputrc
new file mode 100644
index 00000000..d5b7efad
--- /dev/null
+++ b/inputrc
@@ -0,0 +1,7 @@
+# Configure option + right arrow to move forward one word in iTerm2
+# https://www.gnu.org/software/bash/manual/bashref.html#Commands-For-Moving
+"\e\e[C": forward-word
+
+# Configure option + left arrow to move backward one word in iTerm2
+# https://www.gnu.org/software/bash/manual/bashref.html#Commands-For-Moving
+"\e\e[D": backward-word
diff --git a/karabiner/ext/markdown_inline_link b/karabiner/ext/markdown_inline_link
deleted file mode 100755
index 1863a3c0..00000000
--- a/karabiner/ext/markdown_inline_link
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-# Get URL from clipboard
-LINK_URL=`/usr/bin/pbpaste`
-
-# Copy currently-selected text to use as the link text
-osascript -e 'tell application "System Events" to keystroke "c" using command down'
-sleep 0.1 # allow some time for async applescript to complete
-LINK_TEXT=`/usr/bin/pbpaste`
-
-# Construct the formatted link and paste it over top of the currently-selected text
-/bin/echo -n "[${LINK_TEXT}](${LINK_URL})" | /usr/bin/pbcopy
-osascript -e 'tell application "System Events" to keystroke "v" using command down'
-sleep 0.1 # allow some time for async applescript to complete
-
-# Restore the clipboard to its original state
-echo $LINK_URL | /usr/bin/pbcopy
diff --git a/karabiner/ext/markdown_reference_link b/karabiner/ext/markdown_reference_link
deleted file mode 100755
index 39220a07..00000000
--- a/karabiner/ext/markdown_reference_link
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-
-LINK_LABEL=$1
-
-# Get URL from clipboard
-LINK_URL=`/usr/bin/pbpaste`
-
-# Copy currently-selected text to use as the link text
-osascript -e 'tell application "System Events" to keystroke "c" using command down'
-sleep 0.1 # allow some time for async applescript to complete
-LINK_TEXT=`/usr/bin/pbpaste`
-
-# Construct the formatted link and paste it over top of the currently-selected text
-/bin/echo -n "[${LINK_TEXT}][${LINK_LABEL}]" | /usr/bin/pbcopy
-osascript -e 'tell application "System Events" to keystroke "v" using command down'
-sleep 0.1 # allow some time for async applescript to complete
-
-# Construct the link definition and paste it at the bottom of the document
-/bin/echo -n "[${LINK_LABEL}]: ${LINK_URL}" | /usr/bin/pbcopy
-osascript \
- -e 'tell application "System Events"' \
- -e 'keystroke (ASCII character 31) using command down' \
- -e 'keystroke return' \
- -e 'keystroke "v" using command down' \
- -e 'end tell'
-sleep 0.1 # allow some time for async applescript to complete
-
-# Restore the clipboard to its original state
-echo $LINK_URL | /usr/bin/pbcopy
diff --git a/karabiner/ext/open_selected_url b/karabiner/ext/open_selected_url
deleted file mode 100755
index 27e8caff..00000000
--- a/karabiner/ext/open_selected_url
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-ORIGINAL_CLIPBOARD=`/usr/bin/pbpaste`
-
-# Copy currently-selected URL
-osascript -e 'tell application "System Events" to keystroke "c" using command down'
-sleep 0.1 # allow some time for async applescript to complete
-URL=`/usr/bin/pbpaste`
-
-open $URL
-
-# Restore the clipboard to its original state
-echo $ORIGINAL_CLIPBOARD | /usr/bin/pbcopy
diff --git a/karabiner/ext/wrap_selected_text b/karabiner/ext/wrap_selected_text
deleted file mode 100755
index 10b1ecf0..00000000
--- a/karabiner/ext/wrap_selected_text
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-WRAP_CHARACTERS=$1
-
-ORIGINAL_CLIPBOARD=`/usr/bin/pbpaste`
-
-# Copy currently-selected text
-osascript -e 'tell application "System Events" to keystroke "c" using command down'
-sleep 0.1 # allow some time for async applescript to complete
-TEXT=`/usr/bin/pbpaste`
-
-# Construct the formatted output and paste it over top of the currently-selected text
-/bin/echo -n "${WRAP_CHARACTERS}${TEXT}${WRAP_CHARACTERS}" | /usr/bin/pbcopy
-osascript -e 'tell application "System Events" to keystroke "v" using command down'
-sleep 0.1 # allow some time for async applescript to complete
-
-echo $ORIGINAL_CLIPBOARD | /usr/bin/pbcopy
diff --git a/karabiner/karabiner.json b/karabiner/karabiner.json
new file mode 100644
index 00000000..e196c217
--- /dev/null
+++ b/karabiner/karabiner.json
@@ -0,0 +1,42 @@
+{
+ "profiles": [
+ {
+ "devices": [
+ {
+ "disable_built_in_keyboard_if_exists": false,
+ "identifiers": {
+ "is_keyboard": true,
+ "is_pointing_device": false,
+ "product_id": 276,
+ "vendor_id": 4176
+ },
+ "ignore": true
+ }
+ ],
+ "fn_function_keys": {
+ "f1": "vk_consumer_brightness_down",
+ "f10": "mute",
+ "f11": "volume_down",
+ "f12": "volume_up",
+ "f2": "vk_consumer_brightness_up",
+ "f3": "vk_mission_control",
+ "f4": "vk_launchpad",
+ "f5": "vk_consumer_illumination_down",
+ "f6": "vk_consumer_illumination_up",
+ "f7": "vk_consumer_previous",
+ "f8": "vk_consumer_play",
+ "f9": "vk_consumer_next"
+ },
+ "name": "Default profile",
+ "selected": true,
+ "simple_modifications": {
+ "caps_lock": "left_control",
+ "right_option": "f17"
+ },
+ "virtual_hid_keyboard": {
+ "caps_lock_delay_milliseconds": 0,
+ "keyboard_type": "ansi"
+ }
+ }
+ ]
+}
diff --git a/karabiner/private.xml b/karabiner/private.xml
deleted file mode 100644
index 91b49b0c..00000000
--- a/karabiner/private.xml
+++ /dev/null
@@ -1,742 +0,0 @@
-
-
-
-
- KeyCode::VK_OPEN_URL_APP_Atom
- /Applications/Atom Beta.app
-
-
- KeyCode::VK_OPEN_URL_APP_Chrome
- /Applications/Google Chrome.app
-
-
- KeyCode::VK_OPEN_URL_APP_iTerm
- /Applications/iTerm.app
-
-
- KeyCode::VK_OPEN_URL_APP_Mailplane
- /Applications/Mailplane 3.app
-
-
- KeyCode::VK_OPEN_URL_APP_Slack
- /Applications/Slack.app
-
-
- KeyCode::VK_OPEN_URL_APP_Remember_The_Milk
- /Applications/Remember The Milk.app
-
-
-
- KEYBOARD_KARABINER_EXT_PATH
- {{ ENV_HOME }}/Library/Application\ Support/Karabiner/ext
-
-
- VERIFY_AND_EXECUTE_EXTENSION
-
-
-
-
-
- -
-
- F19 to Escape/Control
- Tap F19 for Escape; Hold F19 for Control
- (Recommendation: Use Seil to remap Caps Lock to F19.)
- com.jasonrudolph.f192f19_escape_or_control
-
- --KeyOverlaidModifier--
- KeyCode::F19,
- KeyCode::CONTROL_L,
- KeyCode::ESCAPE
-
-
-
- -
- Double-tap Left Shift for CapsLock
- com.jasonrudolph.double_lshift_to_caps
- __DoublePressModifier__ KeyCode::SHIFT_L, KeyCode::SHIFT_L, KeyCode::CAPSLOCK
-
-
- -
-
- Hyper Mode
-
-
- OS X doesn't have a native Hyper key. Let's define Hyper as Control+Shift+Option+Command.
- With a new modifier key defined, we open a whole world of possibilities.
-
-
-
- -
- Right Option to Hyper
- com.jasonrudolph.right_option_hyper
-
- __KeyToKey__
- KeyCode::OPTION_R, ModifierFlag::OPTION_R | ModifierFlag::NONE,
- KeyCode::COMMAND_L, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L
-
-
-
- -
- Hyper+A to open iTunes ("A" for "Apple Music")
- com.jasonrudolph.hyper_a
-
- __KeyToKey__
- KeyCode::A, ModifierFlag::COMMAND_L, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L,
- KeyCode::VK_OPEN_URL_APP_iTunes,
-
-
-
- -
- Hyper+B to open Chrome ("B" for "Browser")
- com.jasonrudolph.hyper_b
-
- __KeyToKey__
- KeyCode::B, ModifierFlag::COMMAND_L, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L,
- KeyCode::VK_OPEN_URL_APP_Chrome,
-
-
-
- -
- Hyper+C to open Slack ("C" for "Chat")
- com.jasonrudolph.hyper_c
-
- __KeyToKey__
- KeyCode::C, ModifierFlag::COMMAND_L, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L,
- KeyCode::VK_OPEN_URL_APP_Slack,
-
-
-
- -
- Hyper+D to open Remember The Milk ("D" for "Do!" ... or Done!")
- com.jasonrudolph.hyper_d
-
- __KeyToKey__
- KeyCode::D, ModifierFlag::COMMAND_L, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L,
- KeyCode::VK_OPEN_URL_APP_Remember_The_Milk,
-
-
-
- -
- Hyper+E to open Atom ("E" for "Editor")
- com.jasonrudolph.hyper_e
-
- __KeyToKey__
- KeyCode::E, ModifierFlag::COMMAND_L, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L,
- KeyCode::VK_OPEN_URL_APP_Atom,
-
-
-
- -
- Hyper+F to open Finder ("F" for "Finder")
- com.jasonrudolph.hyper_f
-
- __KeyToKey__
- KeyCode::F, ModifierFlag::COMMAND_L, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L,
- KeyCode::VK_OPEN_URL_APP_Finder,
-
-
-
- -
- Hyper+G to open Mailplane ("G" for "Gmail")
- com.jasonrudolph.hyper_g
-
- __KeyToKey__
- KeyCode::G, ModifierFlag::COMMAND_L, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L,
- KeyCode::VK_OPEN_URL_APP_Mailplane,
-
-
-
- -
- Hyper+T to open iTerm ("T" for "Terminal")
- com.jasonrudolph.hyper_t
-
- __KeyToKey__
- KeyCode::T, ModifierFlag::COMMAND_L, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L,
- KeyCode::VK_OPEN_URL_APP_iTerm,
-
-
-
-
-
- KeyCode::VK_OPEN_URL_SHELL_open_selected_url
- yy
-
-
-
-
- -
- Option+O to open currently-selected text as URL
- com.jasonrudolph.option_with_o_to_open_selected_url
-
- __KeyToKey__
- KeyCode::O, ModifierFlag::OPTION_L | ModifierFlag::NONE,
- KeyCode::VK_OPEN_URL_SHELL_open_selected_url
-
-
-
- -
-
- Control+; to delete to end of line
- com.jasonrudolph.control_with_semicolon_to_delete_to_end_of_line
-
- TERMINAL
-
- __KeyToKey__
- KeyCode::SEMICOLON, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_CONTROL | ModifierFlag::NONE,
- KeyCode::CURSOR_RIGHT, ModifierFlag::COMMAND_L | ModifierFlag::SHIFT_L, KeyCode::FORWARD_DELETE
-
-
-
- TERMINAL
-
- __KeyToKey__
- KeyCode::SEMICOLON, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_CONTROL | ModifierFlag::NONE,
- KeyCode::K, ModifierFlag::CONTROL_L,
- Option::NOREPEAT
-
-
-
-
- -
- Option+H/L to delete previous/next word in iTerm 2 (and Terminal)
- com.jasonrudolph.terminal.option_with_h_or_l_to_delete_previous_word_or_next_word
- TERMINAL
-
-
-
- __KeyToKey__
- KeyCode::H, ModifierFlag::OPTION_L | ModifierFlag::NONE,
- KeyCode::W, ModifierFlag::CONTROL_L
-
-
- __KeyToKey__
- KeyCode::L, ModifierFlag::OPTION_L | ModifierFlag::NONE,
- KeyCode::ESCAPE,
- KeyCode::D
-
-
-
- -
- Option+H/L to delete previous/next word
- com.jasonrudolph.option_with_h_or_l_to_delete_previous_word_or_next_word
-
-
-
- __KeyToKey__
- KeyCode::H, ModifierFlag::OPTION_L | ModifierFlag::NONE,
- KeyCode::DELETE, ModifierFlag::OPTION_L
-
-
- __KeyToKey__
- KeyCode::L, ModifierFlag::OPTION_L | ModifierFlag::NONE,
- KeyCode::FORWARD_DELETE, ModifierFlag::OPTION_L
-
-
-
- -
- Control+dash/pipe to split iTerm2 panes horizontally/vertically
- com.jasonrudolph.iterm.control_with_dash_or_pipe_to_split_pane
- TERMINAL
-
- __KeyToKey__
- KeyCode::MINUS, ModifierFlag::CONTROL_L,
- KeyCode::D, ModifierFlag::COMMAND_L | ModifierFlag::SHIFT_L
-
-
- __KeyToKey__
- KeyCode::BACKSLASH, ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L,
- KeyCode::D, ModifierFlag::COMMAND_L | ModifierFlag::NONE
-
-
-
- -
- Control+H/J/K/L to move left/up/down/right by one pane in iTerm 2
- com.jasonrudolph.iterm.control_with_h_or_j_or_k_or_l_to_move_between_panes
- TERMINAL
-
- __KeyToKey__
- KeyCode::H, ModifierFlag::CONTROL_L,
- KeyCode::CURSOR_LEFT, ModifierFlag::COMMAND_L | ModifierFlag::OPTION_L
-
-
- __KeyToKey__
- KeyCode::J, ModifierFlag::CONTROL_L,
- KeyCode::CURSOR_DOWN, ModifierFlag::COMMAND_L | ModifierFlag::OPTION_L
-
-
- __KeyToKey__
- KeyCode::K, ModifierFlag::CONTROL_L,
- KeyCode::CURSOR_UP, ModifierFlag::COMMAND_L | ModifierFlag::OPTION_L
-
-
- __KeyToKey__
- KeyCode::L, ModifierFlag::CONTROL_L,
- KeyCode::CURSOR_RIGHT, ModifierFlag::COMMAND_L | ModifierFlag::OPTION_L
-
-
-
-
- -
- (S)uper (D)uper Mode
-
-
- What's (S)uper (D)uper Mode?
- notsave.com.jasonrudolph.simultaneouskeypresses_vimode
- __ShowStatusMessage__ (S)uper (D)uper Mode
-
- To activate, push S and D keys simultaneously and hold them down.
- Now you're in (S)uper (D)uper mode. It's like a secret keyboard _inside_ your keyboard. (Whoa.)
- It's optimized for keeping you on the home row, or very close to it.
- ---
- Now you can:
- - Use H/J/K/L for Left/Down/Up/Right
- - Use F for Command
- - Use A for Option (AKA Alt)
- - Use Space for Shift
- - Use M to copy
- - Use , to paste
- - Use MM to copy current line
- - Use A+J/K for Page Down/Up
- - Use I/O to move left/right between tabs
- - Use U/P to go to the first/last tab (in most apps)
- - Use A+H/L to move to previous/next word in all apps (including iTerm 2)
-
- __KeyToKey__ KeyCode::A, KeyCode::OPTION_L
-
-
- TERMINAL
-
- --KeyToKey--
- {{VI_H}}, VK_OPTION | ModifierFlag::NONE,
- KeyCode::ESCAPE,
- KeyCode::B
-
-
- --KeyToKey--
- {{VI_L}}, VK_OPTION | ModifierFlag::NONE,
- KeyCode::ESCAPE,
- KeyCode::F
-
-
-
-
-
- com.jasonrudolph.simultaneouskeypresses_vimode.option.slack_jk
- Slack
-
- __KeyToKey__
- {{VI_J}}, VK_OPTION | ModifierFlag::NONE,
- KeyCode::CURSOR_DOWN, ModifierFlag::OPTION_L,
-
-
- --KeyToKey--
- {{VI_K}}, VK_OPTION | ModifierFlag::NONE,
- KeyCode::CURSOR_UP, ModifierFlag::OPTION_L,
-
-
-
-
- __KeyToKey__
- {{VI_J}}, VK_OPTION | ModifierFlag::NONE,
- KeyCode::PAGEDOWN
-
-
- __KeyToKey__
- {{VI_K}}, VK_OPTION | ModifierFlag::NONE,
- KeyCode::PAGEUP
-
-
- __KeyToKey__ {{VI_H}}, KeyCode::CURSOR_LEFT
- __KeyToKey__ {{VI_J}}, KeyCode::CURSOR_DOWN
- __KeyToKey__ {{VI_K}}, KeyCode::CURSOR_UP
- __KeyToKey__ {{VI_L}}, KeyCode::CURSOR_RIGHT
-
- __KeyToKey__ KeyCode::F, KeyCode::COMMAND_L
-
- __KeyToKey__ KeyCode::SPACE, KeyCode::SHIFT_L
-
-
- KeyCode::M
- Millisecond::RawValue::200
-
- __KeyToKey__
- KeyCode::M,
- KeyCode::CURSOR_LEFT, ModifierFlag::COMMAND_L,
- KeyCode::CURSOR_DOWN, ModifierFlag::SHIFT_L,
- KeyCode::C, ModifierFlag::COMMAND_L
-
-
-
- __KeyToKey__
- KeyCode::M,
- KeyCode::C, ModifierFlag::COMMAND_L
-
-
-
- __KeyToKey__
- KeyCode::COMMA,
- KeyCode::V, ModifierFlag::COMMAND_L
-
-
-
- __KeyToKey__
- KeyCode::I,
- KeyCode::BRACKET_LEFT, ModifierFlag::COMMAND_L | ModifierFlag::SHIFT_L
-
-
- __KeyToKey__
- KeyCode::O,
- KeyCode::BRACKET_RIGHT, ModifierFlag::COMMAND_L | ModifierFlag::SHIFT_L
-
-
-
- __KeyToKey__
- KeyCode::U,
- KeyCode::KEY_1, ModifierFlag::COMMAND_L
-
-
- __KeyToKey__
- KeyCode::P,
- KeyCode::KEY_9, ModifierFlag::COMMAND_L
-
-
- -
- Simultaneous Key Presses [S+D] turns on "(S)uper (D)uper mode"
- remap.com_jasonrudolph_simultaneouskeypresses_vimode_sd
-
- __SimultaneousKeyPresses__
- KeyCode::D, KeyCode::S,
- KeyCode::VK_CONFIG_SYNC_KEYDOWNUP_notsave_com_jasonrudolph_simultaneouskeypresses_vimode
-
-
- - ──────────────────────────────
- -
- [Option] Use A+J/K to move to previous/next channel in Slack
- com.jasonrudolph.simultaneouskeypresses_vimode.option.slack_jk
-
-
-
- -
- SizeUp Mode
-
-
- Control SizeUp using keyboard shortcuts that are on the home row, or very close to it.
- Use Control+S to turn on SizeUp mode. Then, use any shortcut below to perform a SizeUp action.
- For example, to send the window left, hit Control+S, and then H.
- ---
- Note: These settings assume that SizeUp is configured with its default keyboard shortcuts.
- Before enabling this mode, you should click "Restore Defaults" in SizeUp's Shortcuts tab.
- ---
- notsave.com_jasonrudolph_sizeup_prefix_mode_core
- __ShowStatusMessage__ SizeUp Mode (Control-s)
-
- - Use H/J/K/L to send window left/down/up/right
-
- __KeyToKey__
- KeyCode::H, ModifierFlag::NONE,
- KeyCode::CURSOR_LEFT, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L | ModifierFlag::COMMAND_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- __KeyToKey__
- KeyCode::J, ModifierFlag::NONE,
- KeyCode::CURSOR_DOWN, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L | ModifierFlag::COMMAND_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- __KeyToKey__
- KeyCode::K, ModifierFlag::NONE,
- KeyCode::CURSOR_UP, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L | ModifierFlag::COMMAND_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- __KeyToKey__
- KeyCode::L, ModifierFlag::NONE,
- KeyCode::CURSOR_RIGHT, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L | ModifierFlag::COMMAND_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- - Use I to send window upper right
-
- __KeyToKey__
- KeyCode::I, ModifierFlag::NONE,
- KeyCode::CURSOR_LEFT, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- - Use O to send window upper right
-
- __KeyToKey__
- KeyCode::O, ModifierFlag::NONE,
- KeyCode::CURSOR_UP, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- - Use , to send window lower left
-
- __KeyToKey__
- KeyCode::COMMA, ModifierFlag::NONE,
- KeyCode::CURSOR_DOWN, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- - Use . to send window lower right
-
- __KeyToKey__
- KeyCode::DOT, ModifierFlag::NONE,
- KeyCode::CURSOR_RIGHT, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- - Use Space to send window center
-
- __KeyToKey__
- KeyCode::SPACE, ModifierFlag::NONE,
- KeyCode::C, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L | ModifierFlag::COMMAND_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- - Use Return to make window full screen
-
- __KeyToKey__
- KeyCode::RETURN, ModifierFlag::NONE,
- KeyCode::M, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L | ModifierFlag::COMMAND_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- - Use Control+H to send window to the previous monitor
-
- __KeyToKey__
- KeyCode::H, ModifierFlag::CONTROL_L | ModifierFlag::NONE,
- KeyCode::CURSOR_LEFT, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core,
- Option::NOREPEAT
-
-
- - Use Control+L to send window to the next monitor
-
- __KeyToKey__
- KeyCode::L, ModifierFlag::CONTROL_L | ModifierFlag::NONE,
- KeyCode::CURSOR_RIGHT, ModifierFlag::CONTROL_L | ModifierFlag::OPTION_L, KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core,
- Option::NOREPEAT
-
-
- - Use Control+S to turn off SizeUp Mode
-
- __KeyToKey__
- KeyCode::S, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_CONTROL | ModifierFlag::NONE,
- KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
- -
- Control+S turns on SizeUp mode
- option.com_jasonrudolph_sizeup_prefix_mode
-
- __KeyToKey__
- KeyCode::S, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_CONTROL | ModifierFlag::NONE,
- KeyCode::VK_CONFIG_FORCE_ON_notsave_com_jasonrudolph_sizeup_prefix_mode_core
-
-
-
-
-
- KeyCode::VK_OPEN_URL_SHELL_markdown_em
-
-
-
-
-
- KeyCode::VK_OPEN_URL_SHELL_markdown_strong
-
-
-
-
-
- KeyCode::VK_OPEN_URL_SHELL_markdown_strikethrough
-
-
-
-
-
- KeyCode::VK_OPEN_URL_SHELL_markdown_inline_link
-
-
-
-
-
- KeyCode::VK_OPEN_URL_SHELL_markdown_reference_link_label_1
-
-
-
-
-
- KeyCode::VK_OPEN_URL_SHELL_markdown_reference_link_label_2
-
-
-
-
-
- KeyCode::VK_OPEN_URL_SHELL_markdown_reference_link_label_3
-
-
-
-
-
- KeyCode::VK_OPEN_URL_SHELL_markdown_reference_link_label_4
-
-
-
-
-
- -
- Markdown Mode
-
-
- Perform common Markdown-formatting tasks anywhere that you're editing text.
- Use Control+M to turn on Markdown mode. Then, use any shortcut to perform an action.
- For example, to wrap the selected text in double asterisks, hit Control+M, and then B.
- ---
- notsave.com_jasonrudolph_markdown_prefix_mode_core
- __ShowStatusMessage__ Markdown Mode (Control-m)
-
- - Use I to wrap the currently-selected text in single asterisks ("I" for "Italic")
- : Example => *selection*
-
- __KeyToKey__
- KeyCode::I, ModifierFlag::NONE,
- KeyCode::VK_OPEN_URL_SHELL_markdown_em,
- KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_markdown_prefix_mode_core,
-
-
- - Use B to wrap the currently-selected text in double asterisks ("B" for "Bold")
- : Example => **selection**
-
- __KeyToKey__
- KeyCode::B, ModifierFlag::NONE,
- KeyCode::VK_OPEN_URL_SHELL_markdown_strong,
- KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_markdown_prefix_mode_core,
-
-
- - Use S to wrap the currently-selected text in double tildas ("S" for "Strikethrough")
- : Example => ~~selection~~
-
- __KeyToKey__
- KeyCode::S, ModifierFlag::NONE,
- KeyCode::VK_OPEN_URL_SHELL_markdown_strikethrough,
- KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_markdown_prefix_mode_core,
-
-
- - Use L to convert the currently-selected text to an inline link, using a URL from the clipboard
- : Example => [selection](clipboard)
-
- __KeyToKey__
- KeyCode::L, ModifierFlag::NONE,
- KeyCode::VK_OPEN_URL_SHELL_markdown_inline_link,
- KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_markdown_prefix_mode_core,
-
-
- - Use 1 to convert the currently-selected text to a reference link, using a URL from the clipboard
- : Also works with 2, 3, or 4
- : Example => [selection][1]
-
- __KeyToKey__
- KeyCode::KEY_1, ModifierFlag::NONE,
- KeyCode::VK_OPEN_URL_SHELL_markdown_reference_link_label_1,
- KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_markdown_prefix_mode_core,
-
-
- __KeyToKey__
- KeyCode::KEY_2, ModifierFlag::NONE,
- KeyCode::VK_OPEN_URL_SHELL_markdown_reference_link_label_2,
- KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_markdown_prefix_mode_core,
-
-
- __KeyToKey__
- KeyCode::KEY_3, ModifierFlag::NONE,
- KeyCode::VK_OPEN_URL_SHELL_markdown_reference_link_label_3,
- KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_markdown_prefix_mode_core,
-
-
- __KeyToKey__
- KeyCode::KEY_4, ModifierFlag::NONE,
- KeyCode::VK_OPEN_URL_SHELL_markdown_reference_link_label_4,
- KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_markdown_prefix_mode_core,
-
-
- - Use Control+M to turn off Markdown Mode
-
- __KeyToKey__
- KeyCode::M, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_CONTROL | ModifierFlag::NONE,
- KeyCode::VK_CONFIG_FORCE_OFF_notsave_com_jasonrudolph_markdown_prefix_mode_core
-
-
- -
- Control+M turns on Markdown mode
- option.com_jasonrudolph_markdown_prefix_mode
-
- __KeyToKey__
- KeyCode::M, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_CONTROL | ModifierFlag::NONE,
- KeyCode::VK_CONFIG_FORCE_ON_notsave_com_jasonrudolph_markdown_prefix_mode_core
-
-
-
-
-
diff --git a/screenshots/accessibility-permissions-for-hammerspoon.png b/screenshots/accessibility-permissions-for-hammerspoon.png
new file mode 100644
index 00000000..2a06ba42
Binary files /dev/null and b/screenshots/accessibility-permissions-for-hammerspoon.png differ
diff --git a/screenshots/karabiner-change-key-config-01.png b/screenshots/karabiner-change-key-config-01.png
deleted file mode 100644
index 976fe918..00000000
Binary files a/screenshots/karabiner-change-key-config-01.png and /dev/null differ
diff --git a/screenshots/karabiner-change-key-config-02.png b/screenshots/karabiner-change-key-config-02.png
deleted file mode 100644
index a475eef7..00000000
Binary files a/screenshots/karabiner-change-key-config-02.png and /dev/null differ
diff --git a/screenshots/karabiner-change-key-config-03.png b/screenshots/karabiner-change-key-config-03.png
deleted file mode 100644
index b9b63326..00000000
Binary files a/screenshots/karabiner-change-key-config-03.png and /dev/null differ
diff --git a/screenshots/karabiner-change-key-config-04.png b/screenshots/karabiner-change-key-config-04.png
deleted file mode 100644
index a5038f0f..00000000
Binary files a/screenshots/karabiner-change-key-config-04.png and /dev/null differ
diff --git a/screenshots/karabiner-key-repeat-config.png b/screenshots/karabiner-key-repeat-config.png
deleted file mode 100644
index 639d0cf1..00000000
Binary files a/screenshots/karabiner-key-repeat-config.png and /dev/null differ
diff --git a/screenshots/login-items-for-karabiner-and-hammerspoon.png b/screenshots/login-items-for-karabiner-and-hammerspoon.png
new file mode 100644
index 00000000..3022bd1e
Binary files /dev/null and b/screenshots/login-items-for-karabiner-and-hammerspoon.png differ
diff --git a/screenshots/seil-config.png b/screenshots/seil-config.png
deleted file mode 100644
index ce8b2a1b..00000000
Binary files a/screenshots/seil-config.png and /dev/null differ
diff --git a/script/karabiner-export b/script/karabiner-export
deleted file mode 100755
index d7484b64..00000000
--- a/script/karabiner-export
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-# Exports all the settings that are configured in the Karabiner UI (e.g., which
-# remappings are enabled, key repeat settings, etc.).
-
-# Get path to the directory where this script resides
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-# Export Karabiner configuration
-PATH_TO_IMPORT_SCRIPT=$DIR/karabiner-import
-/Applications/Karabiner.app/Contents/Library/bin/karabiner export > $PATH_TO_IMPORT_SCRIPT
diff --git a/script/karabiner-import b/script/karabiner-import
deleted file mode 100755
index fa2f8fdf..00000000
--- a/script/karabiner-import
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/bin/sh
-
-cli=/Applications/Karabiner.app/Contents/Library/bin/karabiner
-
-$cli set com.jasonrudolph.hyper_f 1
-/bin/echo -n .
-$cli set com.jasonrudolph.simultaneouskeypresses_vimode.terminal.previous_next_word 1
-/bin/echo -n .
-$cli set com.jasonrudolph.iterm.control_with_h_or_j_or_k_or_l_to_move_between_panes 1
-/bin/echo -n .
-$cli set com.jasonrudolph.hyper_g 1
-/bin/echo -n .
-$cli set parameter.keyoverlaidmodifier_timeout 300
-/bin/echo -n .
-$cli set com.jasonrudolph.control_with_semicolon_to_delete_to_end_of_line 1
-/bin/echo -n .
-$cli set private.option.simultaneouskeypresses_vimode_commadot_to_optionleftright 1
-/bin/echo -n .
-$cli set com.jasonrudolph.f192f19_escape_or_control 1
-/bin/echo -n .
-$cli set repeat.initial_wait 400
-/bin/echo -n .
-$cli set com.jasonrudolph.slack.shift_and_command_with_left_or_right_bracket_to_go_to_previous_or_next_channel 1
-/bin/echo -n .
-$cli set com.jasonrudolph.terminal.option_with_h_or_l_to_delete_previous_word_or_next_word 1
-/bin/echo -n .
-$cli set private.double_lshift_to_caps 1
-/bin/echo -n .
-$cli set repeat.wait 40
-/bin/echo -n .
-$cli set option.com_jasonrudolph_sizeup_prefix_mode 1
-/bin/echo -n .
-$cli set space_cadet.fix_opt_arrows 1
-/bin/echo -n .
-$cli set option.com_jasonrudolph_markdown_prefix_mode 1
-/bin/echo -n .
-$cli set remap.com_jasonrudolph_simultaneouskeypresses_vimode_sd 1
-/bin/echo -n .
-$cli set com.jasonrudolph.right_option_hyper 1
-/bin/echo -n .
-$cli set com.jasonrudolph.size_up.left 1
-/bin/echo -n .
-$cli set com.jasonrudolph.hyper_m 1
-/bin/echo -n .
-$cli set private.remap.simultaneouskeypresses_vimode_sd 1
-/bin/echo -n .
-$cli set option.jremacsmode_ex_controlX 1
-/bin/echo -n .
-$cli set private.appdef 1
-/bin/echo -n .
-$cli set remap.simultaneouskeypresses_jvimode_sd 1
-/bin/echo -n .
-$cli set com.jasonrudolph.hyper_c_hyper_c 1
-/bin/echo -n .
-$cli set com.jasonrudolph.option_with_o_to_open_selected_url 1
-/bin/echo -n .
-$cli set com.jasonrudolph.iterm.control_with_dash_or_pipe_to_split_pane 1
-/bin/echo -n .
-$cli set passthrough.escapetab 1
-/bin/echo -n .
-$cli set option.jasonrudolph_sizeup_prefix_mode 1
-/bin/echo -n .
-$cli set com.jasonrudolph.hyper_a 1
-/bin/echo -n .
-$cli set com.jasonrudolph.option_up_down_to_pageup_pagedown 1
-/bin/echo -n .
-$cli set com.jasonrudolph.hyper_b 1
-/bin/echo -n .
-$cli set remap.simultaneouskeypresses_custom_vimode_sd 1
-/bin/echo -n .
-$cli set com.jasonrudolph.option_with_h_or_l_to_delete_previous_word_or_next_word 1
-/bin/echo -n .
-$cli set option.emacsmode_ex_controlU_forwarddelete 1
-/bin/echo -n .
-$cli set private.optionDtoescapeD_term 1
-/bin/echo -n .
-$cli set private.right_command_d 1
-/bin/echo -n .
-$cli set com.jasonrudolph.hyper_c 1
-/bin/echo -n .
-$cli set remap.launchpad2dashboard 1
-/bin/echo -n .
-$cli set com.jasonrudolph.double_lshift_to_caps 1
-/bin/echo -n .
-$cli set option.simultaneouskeypresses_jvimode_commadot_to_optionleftright 1
-/bin/echo -n .
-$cli set com.jasonrudolph.simultaneouskeypresses_vimode.previous_next_work_in_terminal 1
-/bin/echo -n .
-$cli set com.jasonrudolph.hyper_r 1
-/bin/echo -n .
-$cli set com.jasonrudolph.hyper_d 1
-/bin/echo -n .
-$cli set com.jasonrudolph.hyper_e 1
-/bin/echo -n .
-$cli set private.f192f19_escape_or_control 1
-/bin/echo -n .
-$cli set com.jasonrudolph.hyper_t 1
-/bin/echo -n .
-$cli set com.jasonrudolph.simultaneouskeypresses_vimode.option.slack_io 1
-/bin/echo -n .
-/bin/echo