├── settings.png ├── settings-elements.png ├── karabiner.json ├── private.xml ├── install.sh ├── README.md └── DefaultKeyBinding.dict /settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnarf/osx-compose-key/HEAD/settings.png -------------------------------------------------------------------------------- /settings-elements.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnarf/osx-compose-key/HEAD/settings-elements.png -------------------------------------------------------------------------------- /karabiner.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": [ 3 | { 4 | "name": "Default profile", 5 | "selected": true, 6 | "simple_modifications": { 7 | "right_option": "non_us_backslash" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /private.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Send § for Right Option 4 | private.send_section_sign_for_ropt 5 | --KeyToKey-- KeyCode::OPTION_R, KeyCode::DANISH_DOLLAR 6 | 7 | 8 | Send § for Right Command 9 | private.send_section_sign_for_rcmd 10 | --KeyToKey-- KeyCode::COMMAND_R, KeyCode::DANISH_DOLLAR 11 | 12 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | OSX_VERSION="$(sw_vers -productVersion | sed -E "s/^[0-9]+\.([0-9]+)/\\1/")" 4 | 5 | # Install Karabiner if it isn't installed, but homebrew and cask are. 6 | if [[ "$(type -P brew)" && "$(brew tap | awk '/cask/')" ]]; then 7 | if [[ ! "$(brew cask list 2>/dev/null | grep karabiner)" ]]; then 8 | echo "Installing Karabiner..." 9 | if [[ $OSX_VERSION -ge 12 ]]; then 10 | brew cask install karabiner-elements 11 | else 12 | brew cask install karabiner 13 | fi 14 | fi 15 | echo "Karabiner installed." 16 | else 17 | echo "Homebrew and Homebrew Cask not detected. Not installing Karabiner." 18 | echo "If you intended for this script to install Karabiner, install" 19 | echo "Homebrew and Homebrew Cask:" 20 | echo 21 | echo "http://brew.sh/" 22 | echo "http://caskroom.io/" 23 | echo 24 | fi 25 | 26 | # Copy Karabiner settings. 27 | echo "Copying Karabiner settings..." 28 | if [[ $OSX_VERSION -ge 12 ]]; then 29 | mkdir -p ~/.karabiner.d/configuration 30 | cp karabiner.json ~/.karabiner.d/configuration/karabiner.json 31 | else 32 | mkdir -p ~/Library/Application\ Support/Karabiner 33 | cp private.xml ~/Library/Application\ Support/Karabiner/private.xml 34 | fi 35 | 36 | # Copy DefaultKeyBinding.dict 37 | mkdir -p ~/Library/KeyBindings 38 | echo "Copying DefaultKeyBinding.dict..." 39 | cp DefaultKeyBinding.dict ~/Library/KeyBindings/DefaultKeyBinding.dict 40 | 41 | echo 42 | echo "Done." 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What is a compose key? 2 | 3 | A "compose" key is an input method used for complex characters. It allows you to press your compose key (I bind mine to right-alt on my mac keyboard), and then type something, for instance: 4 | 5 | * `[Compose]`, `+`, `1` = `👍` 6 | * `[Compose]`, `s`, `h`, `r`, `u`, `g` = `¯\_(ツ)_/¯` 7 | 8 | This repo contains my compose key setup but should easily allow you to create your own powerful compositions. The [`DefaultKeyBinding.dict`](DefaultKeyBinding.dict) file contains a tree of "composition". I entertain pull requests to add new shortcuts you feel are important to your day to day. 9 | 10 | You can read more about it on the [blog that inspired this setup](http://lolengine.net/blog/2012/06/17/compose-key-on-os-x). 11 | 12 | # Setting up a "Compose Key" in Mac OS X 13 | 14 | ```bash 15 | git clone https://github.com/gnarf/osx-compose-key.git 16 | ./install.sh 17 | ``` 18 | 19 | You can also install it manually, if you prefer: 20 | 21 | ## For all versions of OS X 22 | 23 | ```bash 24 | mkdir -p ~/Library/KeyBindings 25 | curl 'https://raw.githubusercontent.com/gnarf/osx-compose-key/master/DefaultKeyBinding.dict' -o ~/Library/KeyBindings/DefaultKeyBinding.dict 26 | ``` 27 | 28 | Note: changes to `~/Library/KeyBindings/DefaultKeyBinding.dict` require quitting and restarting any apps you want to test them in. 29 | 30 | ## For OS X 10.12 Sierra 31 | 32 | Install [Karabiner-Elements](https://github.com/tekezo/Karabiner-Elements) for remapping keys support, and download these files into the correct places: 33 | 34 | ```bash 35 | brew cask install karabiner-elements 36 | mkdir -p ~/.karabiner.d/configuration 37 | curl 'https://raw.githubusercontent.com/gnarf/osx-compose-key/master/karabiner.json' -o ~/.karabiner.d/configuration/karabiner.json 38 | ``` 39 | 40 | In Karabiner-Elements under the Simple Modifications tab, click "Add item". Set the "From key" to "right_option" (or "right_command" if you use right alt) and "To key" to "non_us_backslash": 41 | 42 | ![screenshot](/settings-elements.png) 43 | 44 | ## For OS X 10.11 and below 45 | 46 | Install [Karabiner](https://pqrs.org/osx/karabiner/) for remapping keys support, and download these files into the correct places: 47 | 48 | ```bash 49 | brew cask install karabiner 50 | mkdir -p ~/Library/Application\ Support/Karabiner 51 | curl 'https://raw.githubusercontent.com/gnarf/osx-compose-key/master/private.xml' -o ~/Library/Application\ Support/Karabiner/private.xml 52 | ``` 53 | 54 | In Karabiner, enable "Send § for Right Option" (or right command if you use right alt): 55 | 56 | ![screenshot](settings.png) 57 | 58 | Note: changes to `~/Library/KeyBindings/DefaultKeyBinding.dict` require quitting and restarting any apps you want to test them in. 59 | -------------------------------------------------------------------------------- /DefaultKeyBinding.dict: -------------------------------------------------------------------------------- 1 | { 2 | /* The Compose Key: § - use Karabiner to bind to Right-Option 3 | Reference: 4 | http://github.com/gnarf/osx-compose-key 5 | http://lolengine.net/blog/2012/06/17/compose-key-on-os-x 6 | http://heisencoder.net/2008/04/fixing-up-mac-key-bindings-for-windows.html 7 | https://gist.github.com/gnarf/0d29c05b189a51894399 8 | http://osxnotes.net/keybindings.html 9 | */ 10 | "§" = { 11 | "$\UF700" = ("insertText:", "↑"); /* (Shift) Up arrow */ 12 | "$\UF701" = ("insertText:", "↓"); /* (Shift) Down arrow */ 13 | "$\UF702" = ("insertText:", "←"); /* (Shift) Left arrow */ 14 | "$\UF703" = ("insertText:", "→"); /* (Shift) Right arrow */ 15 | "$~\UF700" = ("insertText:", "⇈"); /* (Shift-opt) Double-up arrow */ 16 | "$~\UF701" = ("insertText:", "⇊"); /* (Shift-opt) Double-down arrow */ 17 | "$~\UF702" = ("insertText:", "⇇"); /* (Shift-opt) Double-left arrow */ 18 | "$~\UF703" = ("insertText:", "⇉"); /* (Shift-opt) Double-right arrow */ 19 | "\$" = ("insertText:", "💰"); 20 | "*" = ("insertText:", "★"); 21 | " " = { 22 | " " = ("insertText:", "\U00A0"); /* Non-breaking space */ 23 | }; 24 | "+" = { 25 | "1" = ("insertText:", "👍"); 26 | }; 27 | "-" = { 28 | "1" = ("insertText:", "👎"); 29 | ">" = ("insertText:", "→"); 30 | }; 31 | "!" = { 32 | "?" = ("insertText:", "‽"); 33 | }; 34 | "?" = { 35 | "!" = ("insertText:", "⸘"); 36 | }; 37 | "1" = { 38 | "1" = { 39 | "0" = ("insertText:", "⅒"); 40 | }; 41 | "2" = ("insertText:", "½"); 42 | "3" = ("insertText:", "⅓"); 43 | "4" = ("insertText:", "¼"); 44 | "5" = ("insertText:", "⅕"); 45 | "6" = ("insertText:", "⅙"); 46 | "7" = ("insertText:", "⅐"); 47 | "8" = ("insertText:", "⅛"); 48 | "9" = ("insertText:", "⅑"); 49 | "s" = ("insertText:", "¹"); 50 | }; 51 | "2" = { 52 | "3" = ("insertText:", "⅔"); 53 | "5" = ("insertText:", "⅖"); 54 | "s" = ("insertText:", "²"); 55 | }; 56 | "3" = { 57 | "4" = ("insertText:", "¾"); 58 | "5" = ("insertText:", "⅗"); 59 | "8" = ("insertText:", "⅜"); 60 | "s" = ("insertText:", "³"); 61 | }; 62 | "4" = { 63 | "5" = ("insertText:", "⅘"); 64 | }; 65 | "5" = { 66 | "6" = ("insertText:", "⅚"); 67 | "8" = ("insertText:", "⅝"); 68 | }; 69 | "7" = { 70 | "8" = ("insertText:", "⅞"); 71 | }; 72 | ":" = { 73 | "(" = ("insertText:", "☹"); /* Frowny face */ 74 | ")" = ("insertText:", "☺"); /* Smiley face */ 75 | }; 76 | "<" = { 77 | "\"" = ("insertText:", "“"); 78 | "'" = ("insertText:", "‘"); 79 | "3" = ("insertText:", "♥"); /* Heart */ 80 | "<" = ("insertText:", "«"); 81 | "=" = ("insertText:", "≤"); 82 | "-" = ("insertText:", "←"); 83 | }; 84 | ">" = { 85 | "\"" = ("insertText:", "”"); 86 | "'" = ("insertText:", "’"); 87 | ">" = ("insertText:", "»"); 88 | "=" = ("insertText:", "≥"); 89 | }; 90 | "_" = { 91 | "0" = ("insertText:", "₀"); /* Subscript 0 */ 92 | "1" = ("insertText:", "₁"); /* Subscript 1 */ 93 | "2" = ("insertText:", "₂"); /* Subscript 2 */ 94 | "3" = ("insertText:", "₃"); /* Subscript 3 */ 95 | "4" = ("insertText:", "₄"); /* Subscript 4 */ 96 | "5" = ("insertText:", "₅"); /* Subscript 5 */ 97 | "6" = ("insertText:", "₆"); /* Subscript 6 */ 98 | "7" = ("insertText:", "₇"); /* Subscript 7 */ 99 | "8" = ("insertText:", "₈"); /* Subscript 8 */ 100 | "9" = ("insertText:", "₉"); /* Subscript 9 */ 101 | }; 102 | "b" = { 103 | "u" = { 104 | "m" = { 105 | "p" = ("insertText:", "👊"); 106 | }; 107 | "r" = { 108 | "r" = { 109 | "i" = { 110 | "t" = { 111 | "o" = ("insertText:", "🌯"); 112 | }; 113 | }; 114 | }; 115 | }; 116 | }; 117 | }; 118 | "c" = { 119 | "h" = { 120 | "e" = { 121 | "c" = { 122 | "k" = ("insertText:", "✓"); 123 | }; 124 | }; 125 | }; 126 | "l" = { 127 | "o" = { 128 | "u" = { 129 | "d" = ("insertText:", "☁️"); 130 | }; 131 | }; 132 | }; 133 | }; 134 | "d" = { 135 | "a" = { 136 | "n" = { 137 | "c" = { 138 | "e" = ("insertText:", "💃"); 139 | }; 140 | }; 141 | }; 142 | }; 143 | "e" = { 144 | "y" = { 145 | "e" = { 146 | "s" = ("insertText:", "👀"); 147 | }; 148 | }; 149 | }; 150 | "f" = { 151 | "l" = { 152 | "i" = { 153 | "p" = ("insertText:", "(╯‵Д′)╯彡┻━┻"); 154 | }; 155 | }; 156 | }; 157 | "k" = { 158 | "e" = { 159 | "y" = { 160 | " " = ("insertText:", "␣"); /* Space */ 161 | "s" = ("insertText:", "⇧"); /* Shift */ 162 | "o" = ("insertText:", "⌥"); /* Option */ 163 | "c" = ("insertText:", "⌘"); /* Cmd */ 164 | "r" = ("insertText:", "⏎"); /* Return */ 165 | "e" = ("insertText:", "⎋"); /* Escape */ 166 | "b" = ("insertText:", "⌫"); /* Backspace */ 167 | "d" = ("insertText:", "⌦"); /* Delete */ 168 | "t" = ("insertText:", "⇥"); /* Tab */ 169 | }; 170 | }; 171 | "i" = { 172 | "s" = { 173 | "s" = ("insertText:", "😘"); 174 | }; 175 | }; 176 | }; 177 | "l" = { 178 | "i" = { 179 | "p" = { 180 | "s" = ("insertText:", "💋"); 181 | }; 182 | }; 183 | }; 184 | "m" = { 185 | "u" = { 186 | "s" = { 187 | "i" = { 188 | "c" = ("insertText:", "♫┗(^0^)┓♫"); 189 | }; 190 | }; 191 | }; 192 | }; 193 | "p" = { 194 | "a" = { 195 | "r" = { 196 | "t" = { 197 | "y" = ("insertText:", "🎉"); 198 | }; 199 | }; 200 | }; 201 | "e" = { 202 | "a" = { 203 | "c" = { 204 | "e" = ("insertText:", "☮"); 205 | }; 206 | }; 207 | }; 208 | "o" = { 209 | "o" = ("insertText:", "💩"); 210 | }; 211 | "l" = { 212 | "a" = { 213 | "n" = { 214 | e = ("insertText:", "✈"); 215 | }; 216 | }; 217 | }; 218 | }; 219 | "r" = { 220 | "o" = { 221 | "o" = { 222 | "s" = { 223 | "t" = ("insertText:", "🐓"); 224 | }; 225 | }; 226 | }; 227 | }; 228 | "s" = { 229 | "h" = { 230 | "r" = { 231 | "u" = { 232 | "g" = ("insertText:", "¯\\_(ツ)_/¯"); 233 | }; 234 | }; 235 | }; 236 | "i" = { 237 | "n" = { 238 | "g" = ("insertText:", "🎶"); 239 | }; 240 | }; 241 | }; 242 | "u" = { 243 | "n" = { 244 | "f" = { 245 | "l" = { 246 | "i" = { 247 | "p" = ("insertText:", "┬─┬ノ(ಠ_ಠノ)"); 248 | }; 249 | }; 250 | }; 251 | }; 252 | }; 253 | "y" = { 254 | "a" = { 255 | "y" = ("insertText:", "\(`0´)/"); 256 | }; 257 | "u" = { 258 | "n" = { 259 | "o" = ("insertText:", "(屮'Д')屮"); 260 | }; 261 | }; 262 | }; 263 | "z" = { 264 | "a" = { 265 | "l" = { 266 | "g" = { 267 | "o" = ("insertText:", "H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ"); 268 | }; 269 | }; 270 | }; 271 | }; 272 | }; 273 | } 274 | 275 | --------------------------------------------------------------------------------