7

命令行下光标颜色随输入法改变的尝试

 4 years ago
source link: https://zhuanlan.zhihu.com/p/35559878
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

命令行下光标颜色随输入法改变的尝试

开源开发者,vimer

之前有在 vim 中文输入解决方案 中介绍过在 electron 中我们可以借助

组件让光标颜色随输入法的变化而变化。 最近突然冒出个想法,在命令行下是否也能让光标颜色随着输入法改变来改变, 这样在命令行下使用中文会更容易一点。

首先,我使用的 iTerm2 是支持通过 applescript 获取和设置光标颜色的,代码如下:

tell application "iTerm"
	tell current session of current window
		get cursor color
	end tell
end tell


tell application "iTerm"
	tell current session of current window
		set cursor color {65535, 65535, 65535, 1}
	end tell
end tell

使用命令行方式调用 osascript 可以很容易的完成获取和设置光标颜色的任务。

接下来的问题是如何监听到输入法改变的事件?首先尝试的就是

这个组件,

然后经过尝试发现这个组件使用 nodejs 调用是不会收到任何回调事件的。 起初我以为这是这个 node 的问题,于是用 objective-c 写原生,然后编译调用, 结果还是一样,回调压根不会触发! 但是在 app 里面确是可以触发的,所以得出结论,CFNotificationCenterAddObserver 以及类似的 api 是只能在 app 里面使用的。

命令行的方式不行于是就想到了另一种办法:修改 iTerm2 的源码,事实证明这个办法是可行的,iTerm2 本身就在 PTYSession 文件中对部分系统事件进行了监听,而且也可以支持直接设置光标颜色,以下就是修改的 patch:

diff --git a/sources/PTYSession.m b/sources/PTYSession.m
index 699f5697..c2de773d 100644
--- a/sources/PTYSession.m
+++ b/sources/PTYSession.m
@@ -474,6 +474,8 @@ static const NSUInteger kMaxHosts = 100;
     iTermMetalGlue *_metalGlue NS_AVAILABLE_MAC(10_11);
 
     int _updateCount;
+
+    NSString *_defaultCursorColor;
 }
 
 + (void)registerSessionInArrangement:(NSDictionary *)arrangement {
@@ -615,6 +617,11 @@ static const NSUInteger kMaxHosts = 100;
                                                  selector:@selector(annotationVisibilityDidChange:)
                                                      name:iTermAnnotationVisibilityDidChange
                                                    object:nil];
+        [[NSDistributedNotificationCenter defaultCenter] addObserver:self
+                                                 selector:@selector(inputMethodDidChange:)
+                                                     name:(NSString *)kTISNotifySelectedKeyboardInputSourceChanged
+                                                   object:nil];
+
         [self updateVariables];
 
         if (!synthetic) {
@@ -3165,6 +3172,12 @@ ITERM_WEAKLY_REFERENCEABLE
     }
     _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE
                                                               inProfile:_profile];
+
+    NSColor *color = [_colorMap colorForKey:kColorMapCursor];
+
+    _defaultCursorColor = [NSString stringWithFormat:@"#%02X%02X%02X",
+                        (int) (color.redComponent * 0xFF), (int) (color.greenComponent * 0xFF),
+                        (int) (color.blueComponent * 0xFF)];
 }
 
 - (NSColor *)tabColorInProfile:(NSDictionary *)profile
@@ -4418,6 +4431,21 @@ ITERM_WEAKLY_REFERENCEABLE
     }
 }
 
+- (void)inputMethodDidChange:(NSNotification *)notification {
+    TISInputSourceRef source = TISCopyCurrentKeyboardInputSource();
+    NSString *sourceId = (NSString *) TISGetInputSourceProperty(source, kTISPropertyInputSourceID);
+
+    NSColor *cursorColor;
+
+    if (YES == [sourceId isEqualToString:@"com.apple.keylayout.US"]) {
+        cursorColor = [NSColor colorFromHexString:_defaultCursorColor];
+    } else {
+        cursorColor = [NSColor colorFromHexString:@"#ffd700"];
+  }
+
+  [_screen terminalSetCursorColor:cursorColor];
+}
+
 // Metal is disabled when any note anywhere is visible because compositing NSViews over Metal
 // is a horror and besides these are subviews of PTYTextView and I really don't
 // want to invest any more in this little-used feature.

不过可惜 iTerm2 这里有个 bug,就是每次设置颜色后光标形状会恢复成方块,如果你使用 neovim 这种输入状态下光标会变竖线的编辑器,那就有点蛋疼了。

已向 Term2 提出了这个问题,现在 master 分支已经修复了。

本文基于 CC BY-NC-ND 4.0 发布。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK