【求助】 跨行检测光标前两个单词是否有中文以及空格数量,求正则大佬帮忙改善一下,如果能写成 elisp 就更好了,感谢感谢

目标

用 elisp 跨行检测光标前面两个单词,判断是否有中文,并统计空格出现次数。

目的是把检测结果传递给 pyim/sis 用于智能切换中英文。

问题

  1. 不知道怎么写成 elisp
  2. 能初步检测两个单词是否有中文了,但不知道有哪些逻辑漏洞。
  3. 不知道怎么统计空格数量

当前进度

(([\u2e80-\u9fff]+)([\n\r]{1,2})?([\s\t])?(([\u2e80-\u9fff]+)|(\w)+)([\s\t])?)

相关讨论

可能是我想的太复杂了,把自己都绕晕了。中英文需要切换的场景太多了,不如用 sis 的空格切换简单粗暴效率也可能更高。

不要指望一条正则干完所有的活,拆开实现更简单。

大概思路:

(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)

无法从逻辑上找到漏洞,就多写测试。

1 个赞

应该丢掉一切关于自动切换的设置,丢掉任何精神负担。关于切换输入法无非是就是不清楚手指下到底是什么输入法,要不要抬头看一眼输入法状态(虽然macOS有showyEdge.app可以视觉辅助,emacs可以绑定modeline颜色和当前输入法视觉辅助),但任何眼睛看的东西都是耗能的。于是应该反过来解决这个问题:无时不刻把输入法状态切为英文状态,需要输入中文的时候再切中文,脑子最清楚什么时候需要中文输入。

于是问题就变成怎么把默认状态变为英文:

  1. 系统(非emacs): 全部的默认起始输入状态都为英文,既然你使用了km, 那就超级好办:
  • a. 窗口焦点变化都自动设为英文状态: km trigger: focused window changes,基本通杀。
  • b. 额外设置km trigger: 一分钟后自动切为英文
  • c. 唤起alfred时自动切为英文
  1. emacs内: a. 设一个timer, idle 1 分钟就切为英文; b. focus-out-hook 时切为英文
1 个赞

我确实一直开着 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 里面也有解答。

1 个赞

看来还是要回到只用空格检测来判断切换输入法的方案了。

我研究一下怎么让 pyim 实现 sis 一样的输入两个空格切换输入法 :rofl:

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实现。

1 个赞

我研究一下怎么用 goku 让一个键的 click 绑定到一个组合键上。

主要是不太想动系统设置,万一更新系统或者重装啥的都需要鼠标找来找去,翻来翻去,点来点去 :rofl:

话说 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。

1 个赞

我goku里实际配置更复杂一些,上面是为了方便阐述。以下是一些还没整理但我还能用的陈旧的配置:实际情况是left_command点按f17, 短按 simlayer 为left_command+left_shift, 长按才是left_command本身。如果前置app是emacs, 那就是点按就是"s-;"。(以下配置直接抄是没法用的,因为有些:km :emacsclient, :ecc, :emacs, :yabai, 都要另外写,但如果你用过karabiner和goku, 应该能看明白一丢丢吧? :rofl:

           ;; 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}}]
                    ]}

1 个赞

我把 left_command click 切换输入法写出来了。

        {:des "Command to Ctrl+Space (click) for toggle Input Method"
         :rules [[:##left_command {:key :left_command} nil {:alone :!Tspacebar}]]
         }

算是求 A 得 B 了,虽然还是手动挡,不过比设计一套自动挡要轻松多了。

1 个赞

:rofl: 还是决定放弃折腾了,我的水平还不足以搞一个智能的切换工具出来。

我列了一个表格,考虑到输入法状态、光标前文本状态、光标前空格/制表符数量,计算量比单纯判断空格大很多。

最后还是用 Goku 把 click 左 Command 映射为 Ctrl+Space 作为系统切换方案,弃用 sis 只用 pyim 并开启所有内置探针作为内置方案。 手动+自动混合 :laughing:

输入法不应该同时占有ctrl+spc 和left_command,毕竟ctrl+spc是黄金键位,应该出让给其他软件/设置。所以我把系统级输入法的按键绑定换到f17这种一般软件不会使用的按键,再把left_command绑到f17。