日本語環境の iTerm で option キーを meta キーにする

February 22nd, 2007

iTerm での Meta キーの扱い解決策 : Hasta Pronto.org

ちょっと色々対策を考えて試してみたら Meta キーの扱いに関しては修正出来ちゃいました。誰かの役に立つかもしれないので設定方法を残しておきます。

CLON - 2006/05/31 - OSX

あとiTermつかっているとmetaキーのために入力モードをU.S.にする必要があるのだけど

どうも BK っぽくて嫌なので patch を書いてみた。

もとのソースは CVS 先端の iTerm です。zsh で M-x が効くことだけは確認。

Index: PTYSession.m
===================================================================
RCS file: /cvsroot/iterm/iTerm/PTYSession.m,v
retrieving revision 1.337
diff -p -u -8 -r1.337 PTYSession.m
--- PTYSession.m    21 Feb 2007 06:29:14 -0000  1.337
+++ PTYSession.m    22 Feb 2007 08:53:33 -0000
@@ -763,18 +763,20 @@ static NSImage *warningImage;
     //} else {
     //    char *fs_str = (char *)[mstring fileSystemRepresentation];
     //    data = [NSData dataWithBytes:fs_str length:strlen(fs_str)];
     //}

     data = [mstring dataUsingEncoding:[TERMINAL encoding]
                 allowLossyConversion:YES];

-    if (data != nil) 
+    if (data != nil) {
        [self writeTask:data];
+        [TEXTVIEW setIMInputInsert: [data length] > 0];
+    }

    // let the update thred update display if a key is being held down
    if([TEXTVIEW keyIsARepeat] == NO)
        [self updateDisplay];
 }

 - (void)insertNewline:(id)sender
 {
Index: PTYTextView.m
===================================================================
RCS file: /cvsroot/iterm/iTerm/PTYTextView.m,v
retrieving revision 1.302
diff -p -u -8 -r1.302 PTYTextView.m
--- PTYTextView.m   15 Feb 2007 03:23:05 -0000  1.302
+++ PTYTextView.m   22 Feb 2007 08:53:35 -0000
@@ -2335,24 +2335,29 @@ static int cacheSize;
         IM_INPUT_MARKEDRANGE = NSMakeRange(0, 0);
         [markedText release];
        markedText=nil;
     }

     if ([(NSString*)aString length]>0) {
         if ([_delegate respondsToSelector:@selector(insertText:)])
             [_delegate insertText:aString];
-        else
+        else {
             [super insertText:aString];
-
-        IM_INPUT_INSERT = YES;
+            IM_INPUT_INSERT = YES;
+        }
     }

 }

+- (void) setIMInputInsert: (BOOL) flag
+{
+    IM_INPUT_INSERT = flag;
+}
+
 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange
 {

 #if DEBUG_METHOD_TRACE
     NSLog(@"%s(%d):-[PTYTextView setMarkedText:%@ selectedRange:(%d,%d)]",
           __FILE__, __LINE__, aString, selRange.location, selRange.length);
 #endif
    [markedText release];
Index: Headers/iTerm/PTYTextView.h
===================================================================
RCS file: /cvsroot/iterm/iTerm/Headers/iTerm/PTYTextView.h,v
retrieving revision 1.66
diff -p -u -8 -r1.66 PTYTextView.h
--- Headers/iTerm/PTYTextView.h 10 Jan 2007 07:42:05 -0000  1.66
+++ Headers/iTerm/PTYTextView.h 22 Feb 2007 08:53:36 -0000
@@ -272,16 +272,17 @@ enum { SELECT_CHAR, SELECT_WORD, SELECT_
 - (NSRange)markedRange;
 - (NSRange)selectedRange;
 - (NSArray *)validAttributesForMarkedText;
 - (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange;
 - (void)doCommandBySelector:(SEL)aSelector;
 - (unsigned int)characterIndexForPoint:(NSPoint)thePoint;
 - (long)conversationIdentifier;
 - (NSRect)firstRectForCharacterRange:(NSRange)theRange;
+- (void)setIMInputInsert:(BOOL)flag;

    // service stuff
 - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType;
 - (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard types:(NSArray *)types;
 - (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard;    

 - (void)resetCharCache;

説明

option を meta に読み替えてどうこうという処理に行くには、PTYTextView#keyDown: のなかで [delegate keyDown:event]; が実行される必要がある。でも日本語環境では PTYTextView#keyDown: のなかの IMEnable は YES で、さらに option + なんとかがアクセント記号つきの文字を生成して PTYTextView#inserText で IM_INPUT_INSERT も YES になってしまう。

とりあえず IMEnable を NO にして試したら、バックスラッシュが入力できなくなる。円記号をバックスラッシュに読み替えるのもインプットメソッドがやっているっぽい。

結局、アクセント記号つきの文字が PTYSession#insertText で NSString を NSData に変換するときに [data length] == 0 で消えるのを利用して、そこで TEXTVIEW にはいっている PTYTextView の IM_INPUT_INSERT を NO にするようにした。