iTerm2でSwapOptCmdが使えるようにしてみた
2011/03/19追記
iTerm2-alpha17からModifierキーがカスタマイズできるようになったみたいです!
SwapOptCmdと同じ動作を実現するには
iTerm > Preferences… > Keyboard で Left Command Key を Left Option にして,Left Option Key を Left Command にして,Global Shortcut Keys で Do Not Remap Modifiers に Command + Space を追加します.
簡単ですねっ!!
Mac ユーザーで iTerm を使ってる人はちらほらいるんじゃないかと思うんですが,いつの間にか後継の iTerm2 がアルファ版でリリースされていたようですね.
使用メモリが少なくなったらしいですし(あまり気にしてないので未確認),ショートカットキーの割り当ての自由度も上がってるのでなかなか良いです.
なんちゃって Emacs ユーザーの私としては Command キーが Meta キーとして使えないと苦痛でしょうがないので iTerm では SwapOptCmd を使って Option キーと Command キーを入れ替えてました.
っで,iTerm と同じように iTerm2 にも SwapOptCmd を適用しようとしても Command キーが Meta キーとして認識されないんですね…
というのも,iTerm2 alpha14 から 左Option と 右Option を別に扱ってるからです.
そこで iTerm2 でも SwapOptCmd が使えるように patch を作成しました.
SOCPlugin.patch
--- SOCPlugin.m.org 2011-02-05 11:41:23.000000000 +0900
+++ SOCPlugin.m 2011-02-05 11:34:51.000000000 +0900
@@ -17,6 +17,8 @@
//
#import <objc/runtime.h>
+#define LEFT_OPTION 0x080120
+#define LEFT_COMMAND 0x100108
@interface NSApplication (Replace)
- (void)replace_sendEvent: (NSEvent*)event;
@@ -45,8 +47,8 @@
NSEventType type = [event type];
if (type == NSKeyDown || type == NSKeyUp) {
NSUInteger flags = [event modifierFlags];
- if ((flags & (NSAlternateKeyMask | NSCommandKeyMask)) ==
- NSCommandKeyMask) {
+ if ((flags & LEFT_COMMAND) ==
+ LEFT_COMMAND) {
#ifndef REPLACE_ALL_KEYS
if ([event keyCode] == 49) {
/* command+space */
@@ -54,16 +56,16 @@
return;
}
#endif
- flags &= ~NSCommandKeyMask;
- flags |= NSAlternateKeyMask;
+ flags &= ~LEFT_COMMAND;
+ flags |= LEFT_OPTION;
[self sendSwapEvent: event modifierFlags: flags];
return;
}
- if ((flags & (NSAlternateKeyMask | NSCommandKeyMask)) ==
- NSAlternateKeyMask) {
+ if ((flags & LEFT_OPTION) ==
+ LEFT_OPTION) {
NSUInteger flags = [event modifierFlags];
- flags &= ~NSAlternateKeyMask;
- flags |= NSCommandKeyMask;
+ flags &= ~LEFT_OPTION;
+ flags |= LEFT_COMMAND;
[self sendSwapEvent: event modifierFlags: flags];
return;
}
Modifier の種類のフラグとして modifierFlags (NSUint) の上位2バイトが与えられてるみたいなんで,このフラグをいじりたければ NSAlternateKeyMask や NSCommandKeyMask でいじれるんですが,左Option か 右Option かなどの情報が 下位2バイトに与えられてるのでここもいじる必要があります.ということでいじってます.
パッチを当ててSwapOptCmdを設置するまで
- まずSwapOptCmdのソース (SwapOptCmd-source.tar.gz) をダウンロードして展開します.
$ wget https://sites.google.com/a/yedo.com/www/swapoptcmd/SwapOptCmd-source.tar.gz -O SwapOptCmd-source.tar.gz $ tar xvf SwapOptCmd-source.tar.gz $ cd SwapOptCmd
- 次に先程のパッチを当てます
$ patch -p0 <SOCPlugin.patch
- Xcodeでビルドします.
$ open -a Xcode SwapOptCmd.xcodeproj
Build > Build や Command + B でビルドできます.
Active Configuration を Debug から Release にした方がいいのかもしれませんが,今回初めて Xcode を立ち上げたぐらいなんでよくわかりません…
とりあえず Release にしておきましょうか. - iTerm2で使えるように build/Release/SwapOptCmd.bundle/Contents/Info.plist の array に次の内容を追加します.(見ればわかると思います)
<dict> <key>BundleIdentifier</key> <string>com.googlecode.iterm2</string> </dict>
- SwapOptCmdを設置します.
$ cp -r build/Release/SwapOptCmd.bundle ~/Library/Application\ Support/SIMBL/Plugins/
補足1
SwapOptCmd は元々 Terminal.app のために作られたものなので iTerm2 での動作は保証していません.
SwapOptCmd は sendEvent を上書きすることでキーを入れ替えてるみたいですが,iTerm2 も sendEvent を上書きしてるみたいなんで,iTerm2 の所望の動作が得られなくなる可能性があります.
むしろソースコードをパッと見た感じ iTerm2 では Modifier の設定を変更できるみたいなので SwapOptCmd は必要ないかもしれません.
でも設定の変更の仕方はわかりません…
補足2
SwapOptCmdを使うと Ctrl と Meta (Command) の同時押しが認識されなくなります.
SwapOptCmdを使わずに Ctrl と Meta (Option) の同時押しをした場合と全く同じ modifierFlags を送るようにしてもダメだったので,一体どうすればいいんですかね…