目标
用 elisp 跨行检测光标前面两个单词,判断是否有中文,并统计空格出现次数。
目的是把检测结果传递给 pyim/sis 用于智能切换中英文。
问题
- 不知道怎么写成 elisp
- 能初步检测两个单词是否有中文了,但不知道有哪些逻辑漏洞。
- 不知道怎么统计空格数量
当前进度
(([\u2e80-\u9fff]+)([\n\r]{1,2})?([\s\t])?(([\u2e80-\u9fff]+)|(\w)+)([\s\t])?)
用 elisp 跨行检测光标前面两个单词,判断是否有中文,并统计空格出现次数。
目的是把检测结果传递给 pyim/sis 用于智能切换中英文。
(([\u2e80-\u9fff]+)([\n\r]{1,2})?([\s\t])?(([\u2e80-\u9fff]+)|(\w)+)([\s\t])?)
不要指望一条正则干完所有的活,拆开实现更简单。
大概思路:
(let* ((word-pos
(save-excursion
(re-search-backward "\\b[\n\t\s]" nil t 2))) ;; 往回查找,直到第二个单词尾部
(zh-pos
(save-excursion
(re-search-backward "\\cc" word-pos t 1))))
zh-pos)
无法从逻辑上找到漏洞,就多写测试。
应该丢掉一切关于自动切换的设置,丢掉任何精神负担。关于切换输入法无非是就是不清楚手指下到底是什么输入法,要不要抬头看一眼输入法状态(虽然macOS有showyEdge.app可以视觉辅助,emacs可以绑定modeline颜色和当前输入法视觉辅助),但任何眼睛看的东西都是耗能的。于是应该反过来解决这个问题:无时不刻把输入法状态切为英文状态,需要输入中文的时候再切中文,脑子最清楚什么时候需要中文输入。
于是问题就变成怎么把默认状态变为英文:
我确实一直开着 ShowyEdge 但每次都需要抬眼看一下。
切换的关键是如何记住之前的状态,这一点 KM 的开发者只跟我说 noted 但还没做好,目前只能 set Input Method 不能 read Input Method。
我先尝试给 Emacs 默认全局英文试试,感谢建议。
目前在用 sis 和 pyim,还没搞懂怎么让它俩配合起来。
既然使用 pyim ,不需要 sis ,看看 pyim/pyim-probe.el at master · tumashu/pyim · GitHub ,比如 pyim-probe-auto-english 的代码实现。我看你开的 issue 里面也有解答。
看来还是要回到只用空格检测来判断切换输入法的方案了。
我研究一下怎么让 pyim 实现 sis 一样的输入两个空格切换输入法
pyim-probe-auto-english
(setq-default pyim-english-input-switch-functions
'(
pyim-probe-auto-english
pyim-probe-program-mode
pyim-probe-dynamic-english
pyim-probe-isearch-mode
pyim-probe-org-structure-template
pyim-probe-org-speed-commands
))
我基本不看,我知道我的输入法只要不打字就必然是英文。打英文就直接敲,需要中文就切换一下中文。
切换中文的按键也必须足够简单,要不肯定也没动力使用这个方案: 我个人设置:left_command 点按是 f18, 绑定到“切换上一个输入法”,长按还是left_command。如果emacs最前,left_command自动绑到到"s-;" (emacs好像不认f18) s-; 是toggle-input-method。以上都是通过karabiner+goku实现。
我研究一下怎么用 goku 让一个键的 click 绑定到一个组合键上。
主要是不太想动系统设置,万一更新系统或者重装啥的都需要鼠标找来找去,翻来翻去,点来点去
话说 Ctrl+Space 不就是切换到上一个输入法吗,为什么要选 f18 啊?
能用一个手指完成的,绝不用两只手。能用轻松按cmd就绝不按opton。更正:应该是f17 ,对应left_command, 它的使命。
我自定义了一圈,点按变成以下,hold住还是原来的键。
left_shift to f13
fn to f14
left_control to f15
left_option to f16
left_command to f17
right_command to f18
right_option to f19
right_shift to f20
我的一个观察:一般到了f18以上很多app都不认了,尤其是小众app。
我goku里实际配置更复杂一些,上面是为了方便阐述。以下是一些还没整理但我还能用的陈旧的配置:实际情况是left_command点按f17, 短按 simlayer 为left_command+left_shift, 长按才是left_command本身。如果前置app是emacs, 那就是点按就是"s-;"。(以下配置直接抄是没法用的,因为有些:km :emacsclient, :ecc, :emacs, :yabai, 都要另外写,但如果你用过karabiner和goku, 应该能看明白一丢丢吧? )
;; Hold Keys -------------------------------------------------------------------------------------------------------------------- Hold Keys
;;; app-specific
{:des "Emacs"
:rules [:Emacs
[:##left_command nil ["multitouch_extension_finger_count_total" 0] {:alone :!Csemicolon :held {:key :!Cleft_shift :repeat true :halt true}}]
;; [:spacebar nil nil {:alone :spacebar :held :escape :repeat false}]
;; [:spacebar nil nil {:alone :spacebar :held [:emacsclient "(one-key-menu-triggered-with-held-spacebar)"] :repeat false}] ; meow & one-key in emacs
;; [:period nil nil {:alone :period :held [:emacsclient "(one-key-menu-triggered-with-held-spacebar)"] :repeat false}] ; meow & one-key in emacs
;; [:slash nil nil {:alone :slash :held [:emacsclient "(execute-extended-command t)"]}]
[:slash nil nil {:alone :slash :held [:ecc "(hyperbole)"] :repeat false :halt true}]
;; [:caps_lock nil nil {:alone [:ecc "(meow-last-buffer)"] :held {:key :!Cleft_control :repeat true :halt true}}]
]}
;;; general
{:des "hold keys"
:rules [
[:##escape nil nil {:alone :escape :held {:key :!COescape :repeat false :halt true} :params {:alone 119 :held 999}}]
[:##f1 nil nil {:alone :f1 :held {:key :display_brightness_decrement :repeat true :halt true}}]
[:##f2 nil nil {:alone :f2 :held {:key :display_brightness_increment :repeat true :halt true}}]
[:##f3 nil nil {:alone :f3 :held {:key :mission_control :repeat false :halt true} :params {:alone 150 :held 150}}]
[:##f4 nil nil {:alone :f4 :held {:key :launchpad :repeat false :halt true} :params {:alone 150 :held 150}}]
[:##f5 nil nil {:alone :f5 :held {:key :illumination_decrement :repeat true :halt true}}]
[:##f6 nil nil {:alone :f6 :held {:key :illumination_increment :repeat true :halt true}}]
[:##f7 nil nil {:alone :f7 :held {:key :rewind :repeat false :halt true}}]
[:##f8 nil nil {:alone :f8 :held {:key :play_or_pause :repeat false :halt true}}]
[:##f9 nil nil {:alone :f9 :held {:key :fastforward :repeat false :halt true}}]
[:##f10 nil nil {:alone :f10 :held {:key :mute :repeat false :halt true}}]
[:##f11 nil nil {:alone :f11 :held {:key :volume_decrement :repeat true :halt true}}]
[:##f12 nil nil {:alone :f12 :held {:key :volume_increment :repeat true :halt true}}]
[:grave_accent_and_tilde nil nil {:alone :grave_accent_and_tilde :held {:key :!CTOleft_shift :repeat false :halt true}}]
[:##1 nil nil {:alone :1 :held {:key :!COleft_shift :repeat false :halt true}}]
[:##2 nil nil {:alone :2 :held {:key :!CTleft_shift :repeat false :halt true}}]
[:##3 nil nil {:alone :3 :held {:key :!TOleft_shift :repeat false :halt true}}]
[:##4 nil nil {:alone :4 :held {:key :!CTleft_option :repeat false :halt true}}]
[:##5 nil nil {:alone :5 :held {:key :5 :repeat false :halt true}}]
[:##6 nil nil {:alone :6 :held {:key :6 :repeat false :halt true}}]
[:##7 nil nil {:alone :7 :held {:key :!CTleft_option :repeat false :halt true}}]
[:##8 nil nil {:alone :8 :held {:key :!TOleft_shift :repeat false :halt true}}]
[:##9 nil nil {:alone :9 :held {:key :!CTleft_shift :repeat false :halt true}}]
[:##0 nil nil {:alone :0 :held {:key :!COleft_shift :repeat false :halt true}}]
[:hyphen nil nil {:alone :hyphen :held {:key :!Shyphen :repeat false :halt true}}]
[:equal_sign nil nil {:alone :equal_sign :held {:key :!Sequal_sign :repeat false :halt true}}]
[:tab nil nil {:alone :tab :held {:key :!Cleft_option :repeat true :halt true}}]
[:open_bracket nil nil {:alone :open_bracket :held {:key :!Sopen_bracket :repeat false :halt true}}]
[:close_bracket nil nil {:alone :close_bracket :held {:key :!Sclose_bracket :repeat false :halt true}}]
[:backslash nil nil {:alone :backslash :held {:key :!Sbackslash :repeat false :halt true}}]
[:caps_lock nil ["multitouch_extension_finger_count_total" 0] {:alone [:km "Activate Last Application"] :held {:key :!Cleft_control :repeat true :halt true}}]
[:caps_lock nil ["multitouch_extension_finger_count_total" 1] {:alone :escape :held {:key :caps_lock :repeat true :halt true}}]
[:semicolon nil nil {:alone :!Ssemicolon :held {:key :semicolon :repeat false :halt true}}]
[:quote nil nil {:alone :quote :held {:key :!Squote :repeat false :halt true}}]
[:##left_shift nil ["multitouch_extension_finger_count_total" 0] {:alone :f13 :held {:key :!Tleft_option :repeat true :halt true}}]
[:##left_shift nil ["multitouch_extension_finger_count_total" 1] {:alone :f13 :held {:key :left_shift :repeat true :halt true}}]
[:comma nil nil {:alone :comma :held [:km "open: Chromium"] :repeat false :halt true}]
;; [:period nil nil {:alone :period :held {:key :!Speriod :repeat false :halt true}}]
;; [:period nil nil {:alone :period :held [:km "open: Emacs"] :repeat false :halt true}]
[:period nil nil {:alone :period :held [:km "open: Emacs (trigger: period)"] :repeat false :halt true}]
;; [:slash nil nil {:alone :slash :held {:key :!QEright_shift :repeat true :halt true}}]
[:slash nil nil {:alone :slash :held [:km "open: Finder"] :repeat false :halt true}]
;; [:slash nil nil {:alone :slash :held [:ecc "(hyperbole)"] :repeat false :halt true}]
[:##right_shift nil ["multitouch_extension_finger_count_total" 0] {:alone :f20 :held {:key :!QWright_option :repeat true :halt true}}]
[:##right_shift nil ["multitouch_extension_finger_count_total" 1] {:alone :f20 :held {:key :right_shift :repeat true :halt true}}]
[:fn nil nil {:alone :f14 :held {:key :!CTOleft_shift :repeat true :halt true}}]
[:##left_control nil ["multitouch_extension_finger_count_total" 0] {:alone :f15 :held {:key :!Tleft_shift :repeat true :halt true}}]
[:##left_control nil ["multitouch_extension_finger_count_total" 1] {:alone :f15 :held {:key :left_control :repeat true :halt true}}]
[:##left_option nil ["multitouch_extension_finger_count_total" 0] {:alone :f16 :held {:key :!Oleft_shift :repeat true :halt true}}]
[:##left_option nil ["multitouch_extension_finger_count_total" 1] {:alone :f16 :held {:key :left_option :repeat true :halt true}}]
[:##left_command nil ["multitouch_extension_finger_count_total" 0] {:alone :f17 :held {:key :!Cleft_shift :repeat true :halt true}}]
[:##left_command nil ["multitouch_extension_finger_count_total" 1] {:alone :f17 :held {:key :left_command :repeat true :halt true}}]
;; [:spacebar nil nil {:alone :spacebar :held [:km "open: Emacs (trigger: spacebar)"] :params {:alone 150 :held 150}}]
[:spacebar nil nil {:alone :spacebar :held {:key :escape :repeat false :halt true} :params {:alone 150 :held 150}}]
[:##right_command nil ["multitouch_extension_finger_count_total" 0]
{:alone "/usr/local/bin/yabai -m window --focus stack.next || /usr/local/bin/yabai -m window --focus stack.first"
:held {:key :!WEright_shift :repeat true :halt true}}]
;; [:##right_command nil ["multitouch_extension_finger_count_total" 0] {:alone "/usr/local/bin/yabai -m window --focus stack.prev || /usr/local/bin/yabai -m window --focus stack.last" :held {:key :!WEright_shift :repeat true :halt true}}]
;; [:##right_command nil ["multitouch_extension_finger_count_total" 0] {:alone [:km "YG/MW/UD/Forvo - with no clipboard"] :held {:key :!WEright_shift :repeat true :halt true}}]
[:##right_command nil ["multitouch_extension_finger_count_total" 1] {:alone :!Ctab :held {:key :right_command :repeat true :halt true}}]
[:##right_option nil ["multitouch_extension_finger_count_total" 0] {:alone :!Otab :held {:key :!QWright_shift :repeat true :halt true}}]
;; [:##right_option nil ["multitouch_extension_finger_count_total" 0] {:alone [:km "YG/MW/UD/Forvo - with clipboard"] :held {:key :!QWright_shift :repeat true :halt true}}]
[:##right_option nil ["multitouch_extension_finger_count_total" 1] {:alone :f19 :held {:key :right_option :repeat true :halt true}}]
]}
我把 left_command click 切换输入法写出来了。
{:des "Command to Ctrl+Space (click) for toggle Input Method"
:rules [[:##left_command {:key :left_command} nil {:alone :!Tspacebar}]]
}
算是求 A 得 B 了,虽然还是手动挡,不过比设计一套自动挡要轻松多了。
还是决定放弃折腾了,我的水平还不足以搞一个智能的切换工具出来。
我列了一个表格,考虑到输入法状态、光标前文本状态、光标前空格/制表符数量,计算量比单纯判断空格大很多。
最后还是用 Goku 把 click 左 Command 映射为 Ctrl+Space 作为系统切换方案,弃用 sis 只用 pyim 并开启所有内置探针作为内置方案。 手动+自动混合