システム環境設定にあるキーボードショートカットを設定するAppleScript

システム環境設定→キーボード→キーボードショートカットのアプリケーションで、JSONからアプリのショートカットを設定するAppleScript。要[JSON Helper](https://itunes.apple.com/jp/app/json-helper-for-applescript/id453114608?mt=12)

## 使い方

1. [JSON Helper](https://itunes.apple.com/jp/app/json-helper-for-applescript/id453114608?mt=12)をインストールする。
2. 更に下記にあるJSONを元に、ショートカットの設定を書き保存する。
3. 下記のソースをAppleScript エディタにコピペし、実行する。
4. ファイルを選ぶようになるので、保存したJSONファイルを指定する。
5. あとは無事終わるまで眺める。

環境設定 → セキュリティとプライバシー → プライバシー の「アクセシビリティ」で、**スクリプトエディタ.app**を許可しておいてください。

## JSONを記述する上での注意など

### menu

アプリケーションが持つメニュー項目です。一字一句間違わずに入力してください。Sketch 2の一覧はこちらに作成しています→[text - Sketch.appのメニュー項目一覧 - Qiita [キータ]](http://qiita.com/littlebusters@github/private/3a3e044f46cd58caab41)

### key

後述のmodifier・Fn・return・tabなど以外の文字が打てるキーを指定できます。あと、矢印キーだけは、left / right / up / down で指定できるようにしています。

キーは大文字で指定すると、Shiftキーも併用されていると認識されるので、必ず小文字で！

### modifier

command / option / control / shiftです。見てもらったら分かると思いますが、modifierは配列なので同時に押すキーを複数指定できます。

指定する順番は、「command / option / control / shift」の順番です。optionとshiftを指定する場合は、```["option", "shift"]```です。

## その他

10.7.5（Thanks! @nabeoman さん） / 10.8.5 / 10.9 / 10.9.1 / 10.10.1 / 10.10.5 で動作確認しています。

あと、エラー処理などあまり考えてないので、えぇ、自己責任でお願いします。（ソースが酷いのでどなたか指摘していただけるとうれしい…）

## 参考

以下のサイトを参考にしました。ありがとうございます。

- [AS Hole（AppleScriptの穴） By Piyomaru Software](http://piyocast.com/as/)
- [鳶嶋工房 / AppleScript](http://tonbi.jp/AppleScript/)

## 以下ソース

```applescript
set json to readFile(choose file)
set minorV to system attribute "sys2"

tell application "System Preferences"
	activate
	set current pane to pane id "com.apple.preference.keyboard"
	reveal anchor "shortcutsTab" of pane id "com.apple.preference.keyboard"
end tell

tell application "System Events"
	tell process "System Preferences" to tell window "キーボード"
		repeat with i from 1 to 20
			set rowName to value of static text of row i of table 1 of scroll area 1 of splitter group 1 of tab group 1
			if {"アプリケーション"} is rowName then exit repeat
		end repeat
		select row i of table 1 of scroll area 1 of splitter group 1 of tab group 1
		repeat with shortcutSet in json
			set appName to shortcutSet's |appName|
			repeat with shortcutPair in shortcutSet's shortcut
				if 8 < minorV then
					click button 1 of group 1 of tab group 1
				else
					click button 2 of tab group 1
				end if
				tell sheet 1
					click menu item appName of menu 1 of (click pop up button 1)
					set value of text field "メニュータイトル：" to shortcutPair's |menu|
					keystroke tab
					set pressKeys to "key"
					if shortcutPair's |key| is "left" then
						my keyPressEvent(123, shortcutPair's modifier)
					else if shortcutPair's |key| is "right" then
						my keyPressEvent(124, shortcutPair's modifier)
					else if shortcutPair's |key| is "up" then
						my keyPressEvent(126, shortcutPair's modifier)
					else if shortcutPair's |key| is "down" then
						my keyPressEvent(125, shortcutPair's modifier)
					else
						my keyPressEvent(shortcutPair's |key|, shortcutPair's modifier)
					end if
					click button "追加"
					delay 0.1
				end tell
			end repeat
		end repeat
	end tell
end tell

-- Functions
on readFile(configFilePath)
	try
		open for access configFilePath
		set configFile to read configFilePath
	end try
	close access configFilePath
	tell application "JSON Helper"
		set parsed to read JSON from configFile
	end tell
	return parsed
end readFile

on keyPressEvent(key, modifiers)
	if key is 123 or key is 124 or key is 125 or key is 126 then
		if modifiers is {"command"} then
			tell application "System Events" to key code key using {command down}
		else if modifiers is {"command", "option"} then
			tell application "System Events" to key code key using {command down, option down}
		else if modifiers is {"command", "control"} then
			tell application "System Events" to key code key using {command down, control down}
		else if modifiers is {"command", "shift"} then
			tell application "System Events" to key code key using {command down, shift down}
		else if modifiers is {"command", "option", "control"} then
			tell application "System Events" to key code key using {command down, option down, control down}
		else if modifiers is {"command", "option", "control", "shift"} then
			tell application "System Events" to key code key using {command down, option down, control down, shift down}
		else if modifiers is {"command", "control", "shift"} then
			tell application "System Events" to key code key using {command down, control down, shift down}
		else if modifiers is {"command", "option", "shift"} then
			tell application "System Events" to key code key using {command down, option down, shift down}
		else if modifiers is {"option"} then
			tell application "System Events" to key code key using {option down}
		else if modifiers is {"option", "control"} then
			tell application "System Events" to key code key using {option down, option down}
		else if modifiers is {"option", "shift"} then
			tell application "System Events" to key code key using {option down, shift down}
		else if modifiers is {"option", "control", "shift"} then
			tell application "System Events" to key code key using {option down, control down, shift down}
		else if modifiers is {"control"} then
			tell application "System Events" to key code key using {control down}
		else if modifiers is {"control", "shift"} then
			tell application "System Events" to key code key using {control down, shift down}
		else if modifiers is {"shift"} then
			tell application "System Events" to key code key using {shift down}
		else
			tell application "System Events" to key code key using {command down}
		end if
	else
		if modifiers is {"command"} then
			tell application "System Events" to keystroke key using {command down}
		else if modifiers is {"command", "option"} then
			tell application "System Events" to keystroke key using {command down, option down}
		else if modifiers is {"command", "control"} then
			tell application "System Events" to keystroke key using {command down, control down}
		else if modifiers is {"command", "shift"} then
			log "hit"
			tell application "System Events" to keystroke key using {command down, shift down}
		else if modifiers is {"command", "option", "control"} then
			tell application "System Events" to keystroke key using {command down, option down, control down}
		else if modifiers is {"command", "option", "control", "shift"} then
			tell application "System Events" to keystroke key using {command down, option down, control down, shift down}
		else if modifiers is {"command", "control", "shift"} then
			tell application "System Events" to keystroke key using {command down, control down, shift down}
		else if modifiers is {"command", "option", "shift"} then
			tell application "System Events" to keystroke key using {command down, option down, shift down}
		else if modifiers is {"option"} then
			tell application "System Events" to keystroke key using {option down}
		else if modifiers is {"option", "control"} then
			log "hit"
			tell application "System Events" to keystroke key using {option down, option down}
		else if modifiers is {"option", "shift"} then
			tell application "System Events" to keystroke key using {option down, shift down}
		else if modifiers is {"option", "control", "shift"} then
			tell application "System Events" to keystroke key using {option down, control down, shift down}
		else if modifiers is {"control"} then
			tell application "System Events" to keystroke key using {control down}
		else if modifiers is {"control", "shift"} then
			tell application "System Events" to keystroke key using {control down, shift down}
		else if modifiers is {"shift"} then
			tell application "System Events" to keystroke key using {shift down}
		else
			tell application "System Events" to keystroke key using {command down}
		end if
	end if
end keyPressEvent
```

設定のJSONは下記の通り（私が設定しているショートカット）

```json
[
    {
        "appName": "Sketch.app",
        "shortcut": [
            {
                "menu": "Add Slices For Selection",
                "key": "u",
                "modifier": [ "command", "shift" ]
            },
            {
                "menu": "Scale...",
                "key": "s",
                "modifier": [ "control" ]
            },
            {
                "menu": "Set Style as Default",
                "key": "d",
                "modifier": [ "control" ]
            },
            {
                "menu": "Round to Nearest Pixel Edge",
                "key": "k",
                "modifier": [ "command" ]
            },
            {
                "menu": "Mask with Selected Shape",
                "key": "m",
                "modifier": [ "command", "shift"]
            },
            {
                "menu": "Tighten",
                "key": "left",
                "modifier": [ "option" ]
            },
            {
                "menu": "Loosen",
                "key": "right",
                "modifier": [ "option" ]
            }
        ]
    }
]
```