ããããæ°ããMacBook欲ãã⦠ãã© El Capitan ãã Sierra ã«ãªãã¨Karabinerã使ããªããªãã£ã¦è©±ã ã⦠ã¨ãè²ã ä¸å®ãããèºèºãã¦ããã 代æ¿ãã¨ãããã¡ããã¨è¨å®ããã°ä»£æ¿ã§ããããªHammerspoonãè¯ããã ã£ãã®ã§ ããã使ã£ã¦Karabinerããã®è±å´ã試ã¿ã¦ã¿ãã
Hammerspoon
Mac OSã®æ§ã ãªæä½ãèªååããããã®ãã¼ã«ã§ãã¦ã¼ã¶ãLuaã®ã¹ã¯ãªããã§è¨å®ãæ¸ããã¨ã§OSã®æ§ã ãªæ©è½ã使ããããã«ããªãã¸ãã¦ãããã
Key Remap
åºæ¬ç㫠以ä¸ã®è¨äºã®ã³ããã§å¤§ä¸å¤«ããã
èªåã¯ä»¥ä¸ã®ããã«æ¸ããã
local function keyStroke(mods, key) return function() hs.eventtap.keyStroke(mods, key, 0) end end local function remap(mods, key, fn) return hs.hotkey.bind(mods, key, fn, nil, fn) end -- global remap({'ctrl'}, 'h', keyStroke({}, 'delete')) remap({'ctrl'}, '[', keyStroke({}, 'escape')) remap({'ctrl'}, 'j', keyStroke({}, 'return')) remap({'ctrl', 'cmd'}, 'j', keyStroke({'cmd'}, 'return')) -- disable when a specific application is active local remapKeys = { remap({'ctrl'}, 'b', keyStroke({}, 'left')), remap({'ctrl'}, 'f', keyStroke({}, 'right')), remap({'ctrl'}, 'n', keyStroke({}, 'down')), remap({'ctrl'}, 'p', keyStroke({}, 'up')), remap({'ctrl'}, 'y', keyStroke({'cmd'}, 'v')) } local function handleGlobalAppEvent(name, event, app) if event == hs.application.watcher.activated then if name == 'iTerm2' or name == 'Code' then for i, key in ipairs(remapKeys) do key:disable() end else for i, key in ipairs(remapKeys) do key:enable() end end end end appsWatcher = hs.application.watcher.new(handleGlobalAppEvent) appsWatcher:start()
hs.hotkey.bind
ã§æå®ãããã¼æä½æã®æ¯ãèããæå®ã§ããã®ã§ãhs.eventtap.keyStroke
ã§ç½®ãæããããã¼æä½ãæå®ãã¦ãããemitãããfunctionãã»ãããããpressedfn
, releasedfn
, repeatfn
ã¨3種é¡ã®æ¯ãèããå®ç¾©ã§ããã®ã§æ³¨æããªãããã¯åºæ¬çã«pressedfn
, repeatfn
ãåãkeyStroke
ãèµ·ããfunctionã«ãã¦ããã°è¯ãããã
ãã¨ä¸è¿°è¨äºã«ãããéãiTermãVSCodeãªã©ã®ã¿ã¼ããã«ãã¨ãã£ã¿ã§ã¯ããããç¬èªã«ãã¼ãã¤ã³ãè¨å®ã§ãããããã ãªãããã«ããå¤æãããã¨éã«ãããç½ããã¦æå¾
ããåä½ã«ãªããªãã£ããããã®ã§ãapplicationã®åãæ¿ãæã«ã¤ãã³ããåå¾ãã¦disable()
/enable()
ããããã«ã
å¥ã«ãã¹ã¦ã®ãªããããç¡å¹ã«ããå¿ è¦ã¯ç¡ãã£ãããããã®ã§ã常ã«æå¹ã«ãã¦ãããããã®ã¨ã¯å¥ã«åãæ¿ã対象ã®ãªãããã®keybindã ããä¿æãã¦ãã㦠ãããã ããæå¹å/ç¡å¹åã®å¯¾è±¡ã«ããã
Sticky Shift
Karabinerã§ããä¸ã¤ãä¸è©±ã«ãªã£ã¦ããã®ããæè¬sticky-shiftçãªãã®ãã»ãã³ãã³;
ã§è¡ããã¨ãããã®ã
ã»ãã³ãã³;
ãæ¼ããå¾ã«ãã¼ãæ¼ããã¨ããæä½ã§Shiftãã¼æ¼ããªããã®æä½ã代æ¿ããã(å¥ã«ä½¿ãã®ã¯ã»ãã³ãã³ãããªãã¦ãããã®ã ãã© æãä¸è¬çãªã®ãããããªã®ããª)
AquaSKKã使ã£ã¦ããã¨å¤æä½ç½®ã®æå®ã®éã«Shiftãã¼ãå¤ç¨ãããã¨ã«ãªãã¤ããã®ã§ããã£ã¨ãã®æ¹æ³ã«ãä¸è©±ã«ãªã£ã¦ãããããã£ããããã«æ £ãã¦ãã¾ã£ã¦ããã
Karabinerã§ã¯ AquaSKK で ; (セミコロン) を Sticky Shift に使う - Qiita ã®ããã«è¨å®ãã¦ä½¿ã£ã¦ããã®ã ãã©ããããHammerspoonã§ã©ãã«ãã
local stickyShift = false local targets = {} for i = 96, 122 do targets[hs.keycodes.map[string.char(i)]] = true end hs.hotkey.bind({}, ';', function() if hs.keycodes.currentMethod():find('AquaSKK') then stickyShift = true else hs.eventtap.keyStrokes(';') end end) keyTap = hs.eventtap.new({hs.eventtap.event.types.keyDown}, function(event) if stickyShift and targets[event:getKeyCode()] then event:setFlags({shift = true}) end stickyShift = false end):start()
stickyShift
ã¨ããå¤æ°ãæã£ã¦ããã¦ãå
¥åã½ã¼ã¹ãAquaSKKã®ã¨ãã«;
ãæ¼ãããããã©ã°ãç«ã¦ãããã以å¤ã®ã¨ãã¯æ®éã«ãã®ã¾ã¾;
ã®keyStroke
ãemitããã ãã
keyDown
ã¤ãã³ããç£è¦ããstickyShift
ãã©ã°ãç«ã£ã¦ã㦠ãã¤target
ã®keyCode(æ¯é³ã¨ä¸»ãªåé³ã ãã§è¯ãã®ã ãã© ã¨ããããå
¨ã¢ã«ãã¡ãããã対象ã«ãã¦ãã)ã ã£ãããsetFlags
ã使ã£ã¦shift
ãæ¼ããã¦ããç¶æ
ã«ã¤ãã³ããæ¸ãæãããstickyShift
ãã©ã°ã¯ç¶ç¶ãããå¿
è¦ãªãã®ã§å¼·å¶çã«false
ã«æ»ãã
ããã§ä»ã¾ã§éãã«;
ã使ã£ãsticky-shiftã§ã®æ¥æ¬èªå
¥åãã§ããããã«ãªã£ãã
ã²ãããªã¢ã¼ãã®ã¨ãã ããã©ã°ãå¤ã㦠ASCIIã¢ã¼ããªã;
ã¯ãã®ã¾ã¾éããã¨ããåºæ¥ãã°è¯ãã®ã ãã©ãå
¥åã½ã¼ã¹ã®å¤å¥ã¾ã§ã¯åºæ¥ã¦ã ç¾å¨ã®å
¥åã¢ã¼ããä½ããã¾ã§ã¯åãæ¹æ³ãåãããªãã£ã(ç¡ãï¼)ã®ã§;
ãæ®éã«æã¡ããå ´åã¯æ®éã«è±åå
¥åã«åãæ¿ãããããªãã
ã¾ãããã¯Karabinerã®ã¨ããããã ã£ããä»æ¹ãªãã
ã㨠ã©ãããããããSierraã ã¨Visual Studio Codeä¸ã§AquaSKKãã¾ã£ããå¹ããªãã¦ãã²ãããªã¢ã¼ãã«å ¥ããã¨ããã§ããªãããã ããã¼è¨å®ã¨ãããããåé¡ãããªããã㧠ã©ãã«ããªããªããã ãã©ããä»ã®äººã¯æ®éã«ä½¿ãã¦ããã®ã ãããâ¦ï¼
ã¾ãVSCodeã¯ã³ã¼ãæ¸ããã®ã ãæ¥æ¬èªã®æç« æ¸ãããã¨ãã¯ä»ã®ã¢ããªã±ã¼ã·ã§ã³ã使ãã°ãããâ¦ã¨ãããã¨ã§å²ãåã(ãã®è¨äºã®ä¸æ¸ãã¯Atomã§æ¸ãã¦ã)ã
Launcher
ãã¨ãã使ã£ã¦ããã®ãhotkeyã§ã®ã¢ããªåãæ¿ããcmd
+ctrl
+å·¦æã§æã¦ããã¼ ã®çµã¿åããã§ã¿ã¼ããã«/ã¨ãã£ã¿/ãã©ã¦ã¶/ãã£ãã/ãã¤ãã¿ã¼ ãªã©ããµã¯ãµã¯åãæ¿ããã㦠以åã¯SlateãPhoenixããããã¯ææã¢ããªã®Shortcutsãªããã使ã£ã¦ãããããããã©ããããHammerspoonã§è§£æ±ºã§ããããã«ãªã£ãã®ã§Launcherã¢ããªã¯ä¸è¦ã«ãªã£ãã
local function launcher(mods, key, appname) hs.hotkey.bind(mods, key, function() hs.application.launchOrFocus('/Applications/' .. appname .. '.app') end) end launcher({'cmd', 'ctrl'}, 'q', 'iTerm') launcher({'cmd', 'ctrl'}, 'w', 'Visual Studio Code') launcher({'cmd', 'ctrl'}, 'e', 'Google Chrome') launcher({'cmd', 'ctrl'}, 't', 'Twitter') launcher({'cmd', 'ctrl'}, 's', 'Slack')
Key Repeat
ãã¨ããããã°karabinerã§ä¾¿å©ã ã£ãã®ããã¼ãªãã¼ãééã®è¨å®ã ã£ãã®ã ãã©ã
ã·ã¹ãã ç°å¢è¨å®ã§ã®è¨å®å¯è½ç¯å²ãè¶
ããå ´åã¯defaults
ã³ãã³ãã§è¨å®ããã°è¯ãã ããã¨ããã®ãã°ã°ã£ã¦ç¥ã£ãã®ã§ åé¡ãªãã£ãã
$ defaults write -globalDomain KeyRepeat -int 1 $ defaults write -globalDomain InitialKeyRepeat -int 10
ã¨ããã£ã¦åèµ·åããã°åæ ããã(ã·ã¹ãã ç°å¢è¨å®ã§ã®å¤æ´ã§ã¯KeyRepeat
ã¯2
ãInitialKeyRepeat
ã¯15
ãæå°å¤ã£ã½ã)
éæ
ã¨ããããKarabinerãç¡ãã¦ãå°ããªãç¨åº¦ã®è¨å®ã¯åºæ¥ãã£ã½ããä»ã«ãã«ã¹ã¿ãã¤ãºããããã°init.lua
ãé å¼µã£ã¦æ¸ãã°è²ã
ã§ãããã§ã¯ããã
ãããã¾ãKarabinerãSierraã§ãåãã¦ãããã®ãä½ããã ã ãã®Hammerspoonã ã£ã¦ ãã¤ã¾ãMac OSã®å¤åã§ä½¿ããªããªã£ã¦ãã¾ããåãããªãã
ãããã¦Macã®å¤æ´ã«æ¯ãåããã¦è²ã ã¨è¦å´ããªãã¨ãããã®ã¯ã©ãã«ãããªããªãããããªããã¨æã£ã¦ãã¾ã