分享Karabiner配置,让Mac键盘更配emacs

先说一下自己的使用习惯,我即不evil,也不space,喜欢原生键位,而且必须左右开弓,也就是左边右边都要有control和alt,位置对称。

平时在工位只用外接键盘和外接鼠标,去开会的时候就全拔掉,只用内置键盘和触控板。

我用的Mac内置键盘没有right control,所以把left arrow改成right control,只在组合按时生效。

外接键盘的alt在空格旁边,用着更习惯,所以打开emacs时把内置键盘的option和command互换一下。

配置分享一下:

{
  "title": "My Config",
  "rules": [
    {
      "description": "Left arrow to control if pressed with other keys, to left arrow if pressed alone(builtin-keyboard)",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "left_arrow",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "key_code": "right_control"
            }
          ],
          "to_if_alone": [
            {
              "key_code": "left_arrow"
            }
          ],
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1452,
                  "product_id": 630
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "description": "Exchange option and command(emacs/iterm2 builtin-keyboard)",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "left_option",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "key_code": "left_command"
            }
          ],
          "conditions": [
            {
              "type": "frontmost_application_if",
              "bundle_identifiers": [
                "^org\\.gnu\\.Emacs$",
                "^com\\.googlecode\\.iterm2$"
              ]
            },
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1452,
                  "product_id": 630
                }
              ]
            }
          ]
        },
        {
          "type": "basic",
          "from": {
            "key_code": "right_option",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "key_code": "right_command"
            }
          ],
          "conditions": [
            {
              "type": "frontmost_application_if",
              "bundle_identifiers": [
                "^org\\.gnu\\.Emacs$",
                "^com\\.googlecode\\.iterm2$"
              ]
            },
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1452,
                  "product_id": 630
                }
              ]
            }
          ]
        },
        {
          "type": "basic",
          "from": {
            "key_code": "left_command",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "key_code": "left_option"
            }
          ],
          "conditions": [
            {
              "type": "frontmost_application_if",
              "bundle_identifiers": [
                "^org\\.gnu\\.Emacs$",
                "^com\\.googlecode\\.iterm2$"
              ]
            },
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1452,
                  "product_id": 630
                }
              ]
            }
          ]
        },
        {
          "type": "basic",
          "from": {
            "key_code": "right_command",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "key_code": "right_option"
            }
          ],
          "conditions": [
            {
              "type": "frontmost_application_if",
              "bundle_identifiers": [
                "^org\\.gnu\\.Emacs$",
                "^com\\.googlecode\\.iterm2$"
              ]
            },
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1452,
                  "product_id": 630
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

使用方法: 存到~/.config/karabiner/assets/complex_modifications/xxxx.json,打开Karabiner -> Complex Modifications -> Add rule

触控板习惯用natural的方向,鼠标习惯用反方向,可是Mac对鼠标和触控板的方向设置是绑定的,用ScrollReverser也挺好,但是已经有Hammerspoon了,总觉得多开个进程浪费资源,所以写了个脚本翻转鼠标和触控板方向:

-- 翻转USB鼠标
-- 不能做到鼠标/触摸板单一翻转,只能随鼠标插拔自动翻转两者
-- 不如scrollReverser彻底
local function hasUSBDevice(target)
	devs = {}
    for x, dev in pairs(hs.usb.attachedDevices()) do
    	for k, v in pairs(dev) do
    		if k == 'productName' then
    			if v == target then
    				return true
    			end
    		end
    	end
    end
    return false
end

local has_usb_mouse = hasUSBDevice('Lenovo USB Optical Mouse')

hs.eventtap.new({hs.eventtap.event.types.scrollWheel}, function(e)
	if has_usb_mouse then
	    local dy = e:getProperty(hs.eventtap.event.properties.scrollWheelEventDeltaAxis1)
	    local dx = e:getProperty(hs.eventtap.event.properties.scrollWheelEventDeltaAxis2)
	    local scroll = hs.eventtap.event.newScrollEvent({dx, -dy}, {})
		return true, {scroll}
	else
		return false
	end
end):start()

hs.usb.watcher.new(function(e)
	if e.productName == 'Lenovo USB Optical Mouse' then
		if e.eventType == 'added' then
			has_usb_mouse = true
		else
			has_usb_mouse = false
		end
	end
end):start()
5 个赞