** <2022-06-15 Wed> Do not require popup in pyim-page.el popup 是一个非 gnu elpa 包,pyim-page.el 不应该 require 它,需要用户自己手动 require, 使用 popup tooltip 的用户需要在配置中添加:
(require 'popup)
** <2022-06-13 Mon> pyim-dcache-backend 所需的 package 需要用户手工加载了。
以前 pyim 可以根据 pyim-dcache-backend 的取值自动加载需要的 package, 这样做虽然 方便,但代码特别容易出现问题,考虑到 pyim 未来支持的后端不会有太大变化,我删除了 这个功能,为了向后兼容,pyim 目前会自动加载 pyim-dregcache 包, 但这个兼容代码未 来可能会删除,所以使用 pyim-dregcache 的用户,建议给自己的配置中添加:
(require 'pyim-dregcache)
** <2022-05-29 Sun> pyim-cregexp-utils, pyim-cstring-utils 和 pyim-dict-manager 需要用户手动 require.
为降低 pyim 代码的复杂度,减少 pyim 依赖包的数量,下面三个包不会自动加载,需要用 户手动 require.
** <2021-04-28 Wed> 五笔输入法和仓颉输入法的不兼容更新
五笔输入法和仓颉输入法原来使用一个标点符号作为 code-prefix, 现在使用 "wubi/" 和 "cangjie/" 这种形式的 code-prefix, 这样可以减少不同输入法误用同一个 code-prefix 带来的词库冲突。
五笔输入法的 scheme 设置已经移到 pyim-wbdict 包,仓颉输入法的 scheme 设置已经移 到 pyim-cangjie5dict 包。
使用上述两个包的用户,此次变更不受影响,因为两个包使用新的 code-prefix.
受影响的是自己维护五笔和仓颉词库用户,这些用户需要做以下更新:
截图 [[file:./snapshots/pyim-linux-x-with-toolkit.png]]
简介 pyim 是 Emacs 环境下的一个中文输入法,最初这个输入法只支持全拼输入,后来根据同学 的提议,添加了五笔等输入法的支持,“pyim” 现在可以理解为:
(Peng You input method)
Emacs-eim 是 Emacs 环境下的一个中文输入法框架, 支持拼音,五笔,仓颉,二笔等多种 输入法,但遗憾的是,2008 年之后它就停止了开发。
虽然外部输入法功能强大,但不能和 Emacs 默契的配合,这一点极大的损害了 Emacs 那种 行云流水 的感觉。而本人在使用 Emacs-eim 的过程中发现:
于是我 fork 了 Emacs-eim 输入法的部分代码, 创建了新项目:pyim。
特点
安装
(require 'pyim) (require 'pyim-basedict) ; 拼音词库设置,五笔用户 不需要 此行设置 (pyim-basedict-enable) ; 拼音词库,五笔用户 不需要 此行设置 (setq default-input-method "pyim")
配置
** 配置实例 对 pyim 感兴趣的同学,可以看看本人的 pyim 配置,但要注意不要乱抄探针配置。
(require 'pyim) (require 'pyim-basedict) (require 'pyim-cregexp-utils)
;; 如果使用 popup page tooltip, 就需要加载 popup 包。 ;; (require 'popup nil t) ;; (setq pyim-page-tooltip 'popup)
;; 如果使用 pyim-dregcache dcache 后端,就需要加载 pyim-dregcache 包。 ;; (require 'pyim-dregcache) ;; (setq pyim-dcache-backend 'pyim-dregcache)
;; 加载 basedict 拼音词库。 (pyim-basedict-enable)
;; 将 Emacs 默认输入法设置为 pyim. (setq default-input-method "pyim")
;; 显示 5 个候选词。 (setq pyim-page-length 5)
;; 金手指设置,可以将光标处的编码(比如:拼音字符串)转换为中文。 (global-set-key (kbd "M-j") 'pyim-convert-string-at-point)
;; 按 "C-
;; 设置 pyim 默认使用的输入法策略,我使用全拼。 (pyim-default-scheme 'quanpin) ;; (pyim-default-scheme 'wubi) ;; (pyim-default-scheme 'cangjie)
;; 设置 pyim 是否使用云拼音 ;; (setq pyim-cloudim 'baidu)
;; 设置 pyim 探针 ;; 设置 pyim 探针设置,这是 pyim 高级功能设置,可以实现 无痛 中英文切换 :-) ;; 我自己使用的中英文动态切换规则是: ;; 1. 光标只有在注释里面时,才可以输入中文。 ;; 2. 光标前是汉字字符时,才能输入中文。 ;; 3. 使用 M-j 快捷键,强制将光标前的拼音字符串转换为中文。 ;; (setq-default pyim-english-input-switch-functions ;; '(pyim-probe-dynamic-english ;; pyim-probe-isearch-mode ;; pyim-probe-program-mode ;; pyim-probe-org-structure-template))
;; (setq-default pyim-punctuation-half-width-functions ;; '(pyim-probe-punctuation-line-beginning ;; pyim-probe-punctuation-after-punctuation))
;; 开启代码搜索中文功能(比如拼音,五笔码等) (pyim-isearch-mode 1)
* 添加词库文件 pyim 默认使用 pyim-basedict 词库, 这个词库的词条量8万左右,是一个 非常小* 的拼 音词库,源于:libpinyin 项目
如果 pyim-basedict 不能满足需求,用户可以使用其他方式为 pyim 添加拼音词库,具体 方式请参考 [[#如何添加自定义拼音词库][如何添加自定义拼音词库]] 小结。
** 激活 pyim
(setq default-input-method "pyim") (global-set-key (kbd "C-\") 'toggle-input-method)
(setq pyim-cloudim 'baidu) ;; (setq pyim-cloudim 'google)
** 使用双拼模式 pyim 支持双拼输入模式,用户可以通过变量 `pyim-default-scheme' 来设定:
(pyim-default-scheme 'pyim-shuangpin)
注意:
** 使用 rime 输入法 具体安装和使用方式请查看 pyim-liberime 包的 Commentary 部分。
** 使用型码输入法
如果用户在使用型码输入法的过程中,忘记了某个字的编码,可以按 TAB 键临时切换到辅 助输入法来输入,辅助输入法可以通过 `pyim-assistant-scheme' 来设置。
* 让选词框跟随光标 用户可以通过下面的设置让 pyim 在 光标处* 显示一个选词框:
使用 popup 或者 popon 包来绘制选词框 (emacs overlay 机制)
(require 'popup) (setq pyim-page-tooltip 'popup)
(require 'popon) (setq pyim-page-tooltip 'popon)
使用 posframe 来绘制选词框
(require 'posframe) (setq pyim-page-tooltip 'posframe)
注意:pyim 不会自动安装 posframe, 用户需要手动安装这个包,
按照优先顺序自动选择一个可用的 tooltip
(setq pyim-page-tooltip '(posframe popup minibuffer))
* 调整 tooltip 选词框的显示样式 pyim 的选词框默认使用 双行显示 的样式,在一些特殊的情况下(比如:popup 显示的 菜单错位),用户可以使用 单行显示*的样式:
(setq pyim-page-style 'one-line)
** 设置模糊音 可以通过设置 `pyim-pinyin-fuzzy-alist' 变量来自定义模糊音。
** 使用魔术转换器 用户可以将待选词 “特殊处理” 后再 “上屏”,比如 “简体转繁体” 或者 “输入中文,上屏 英文” 之类的。
用户需要设置 `pyim-outcome-magic-converter', 比如:下面这个例子实现,输入 “二呆”, “一个超级帅的小伙子” 上屏 :-)
(defun my-converter (string) (if (equal string "二呆") "“一个超级帅的小伙子”" string)) (setq pyim-outcome-magic-converter #'my-converter)
** 切换全角标点与半角标点
第一种方法:使用命令 pyim-punctuation-toggle',全局切换。这个命令主要用来设 置变量:
pyim-punctuation-translate-p', 用户也可以手动设置这个变量, 比如:
(setq-default pyim-punctuation-translate-p '(yes)) ;使用全角标点。 (setq-default pyim-punctuation-translate-p '(no)) ;使用半角标点。 (setq-default pyim-punctuation-translate-p '(auto)) ;中文使用全角标点,英文使用半角标点。
第二种方法:使用命令 `pyim-punctuation-translate-at-point' 只切换光标处标点的 样式。
第三种方法:设置变量 `pyim-outcome-trigger' ,输入变量设定的字符会切换光标处 标点的样式。
** 手动加词和删词
** pyim 输入状态指示器 pyim 输入状态指示器可以帮助用户快速了解当前 pyim 是处于英文输入状态还是中文输入 状态,因为 pyim probe 探针功能可以让中英文输入状态动态切换,所以快速了解当前中英 文输入状态有时候显得很重要。
pyim 当前内置两种指示器实现方式:
设置默认启用的指示器有两个,用户可以使用下面的变量调整:
(setq pyim-indicator-list (list #'pyim-indicator-with-cursor-color #'pyim-indicator-with-modeline))
注意事项:
pyim-indicator-with-cursor-color 这个 indicator 很容易和其它设置 cursor 颜色 的包冲突,因为都调用 set-cursor-color,遇到这种情况后,用户需要自己解决冲突, pyim-indicator 提供了一个简单的机制:
(setq pyim-indicator-list (list #'my-pyim-indicator-with-cursor-color #'pyim-indicator-with-modeline))
(defun my-pyim-indicator-with-cursor-color (input-method chinese-input-p) (if (not (equal input-method "pyim")) (progn ;; 用户在这里定义 pyim 未激活时的光标颜色设置语句 (set-cursor-color "red")) (if chinese-input-p (progn ;; 用户在这里定义 pyim 输入中文时的光标颜色设置语句 (set-cursor-color "green")) ;; 用户在这里定义 pyim 输入英文时的光标颜色设置语句 (set-cursor-color "blue"))))
** pyim 高级功能
注意:上述两个功能使用不同的变量设置, 千万不要搞错 。
*** 根据环境自动切换到英文输入模式
| 探针函数 | 功能说明 | |-----------------------------------+-----------------------------------------------------------------------------------| | pyim-probe-program-mode | 如果当前的 mode 衍生自 prog-mode,那么仅仅在字符串和 comment 中开启中文输入模式 | |-----------------------------------+-----------------------------------------------------------------------------------| | pyim-probe-org-speed-commands | 解决 org-speed-commands 与 pyim 冲突问题 | | pyim-probe-isearch-mode | 使用 isearch 搜索时,强制开启英文输入模式 | | | 注意:想要使用这个功能,pyim-isearch-mode 必须激活 | |-----------------------------------+-----------------------------------------------------------------------------------| | pyim-probe-org-structure-template | 使用 org-structure-template 时,关闭中文输入模式 | |-----------------------------------+-----------------------------------------------------------------------------------| | | 1. 当前字符为中文字符时,输入下一个字符时默认开启中文输入 | | pyim-probe-dynamic-english | 2. 当前字符为其他字符时,输入下一个字符时默认开启英文输入 | | | 3. 使用命令 pyim-convert-string-at-point 可以将光标前的拼音字符串强制转换为中文。 | |-----------------------------------+-----------------------------------------------------------------------------------|
激活方式:
(setq-default pyim-english-input-switch-functions '(probe-function1 probe-function2 probe-function3))
注意事项:
*** 根据环境自动切换到半角标点输入模式
| 探针函数 | 功能说明 | |------------------------------------------+----------------------------| | pyim-probe-punctuation-line-beginning | 行首强制输入半角标点 | |------------------------------------------+----------------------------| | pyim-probe-punctuation-after-punctuation | 半角标点后强制输入半角标点 | |------------------------------------------+----------------------------|
激活方式:
(setq-default pyim-punctuation-half-width-functions '(probe-function4 probe-function5 probe-function6))
注:上述函数列表中,任意一个函数的返回值为 t 时,pyim 切换到半角标点输入模式。
开发 请参考 [[file:Development.org][Development.org]] 文档
试用 在pyim项目根目录运行shell命令 `make runemacs' 试用最新的pyim。
只有pyim和其依赖的包被载入。用户自己的emacs配置不会被载入。
指定运行的Emacs版本用以下命令,
EMACS=~/my-whatever-directory/bin/emacs make runemacs
Emacs启动后 "M-x toggle-input-method" 或按 "C-\" 打开输入法。
** pyim 有时候会出现卡顿,如何处理。 可以将云搜词和当前 buffer 搜词功能关闭试试看。
(setq pyim-cloudim nil) (setq pyim-candidates-search-buffer-p nil)
** 如何快速切换 scheme
可以试试 pyim-default-scheme 命令。
** 关闭输入联想词功能 (默认开启)
(setq pyim-enable-shortcode nil)
** 形码输入法如何微调候选词序
(setq pyim-candidates-xingma-words-function #'my-func)
** 如何将个人词条相关信息导入和导出?
** pyim 出现错误时,如何开启 debug 模式
(setq debug-on-error t)
** 将光标处的拼音或者五笔字符串转换为中文 (与 vimim 的 “点石成金” 功能类似)
(global-set-key (kbd "M-i") 'pyim-convert-string-at-point)
** 如何使用其它字符翻页
(define-key pyim-mode-map "." 'pyim-page-next-page) (define-key pyim-mode-map "," 'pyim-page-previous-page)
** 如何用 ";" 来选择第二个候选词
(define-key pyim-mode-map ";" (lambda () (interactive) (pyim-select-word-by-number 2)))
** 如何添加自定义拼音词库 pyim 默认没有携带任何拼音词库,用户可以使用下面几种方式,获取质量较好的拼音词库:
*** 第一种方式 (Windows 用户推荐使用)
使用词库转换工具将其他输入法的词库转化为 pyim 使用的词库:这里只介绍 windows 平 台下的一个词库转换软件:
使用方式:
[[file:snapshots/imewlconverter-basic.gif]]
如果生成的词库词频不合理,可以按照下面的方式处理(非常有用的功能):
[[file:snapshots/imewlconverter-wordfreq.gif]]
生成词库后,
(require 'pyim-dict-manager)
然后运行 pyim-dicts-manager' ,按照命令提示,将转换得到的词库文件的信息添加到
pyim-dicts' 中,完成后运行命令 `pyim-restart' 或者重启emacs。
*** 第二种方式 (Linux & Unix 用户推荐使用) E-Neo 同学编写了一个词库转换工具: [[https://github.com/E-Neo/scel2pyim][scel2pyim]] , 可以将一个搜狗词库转换为 pyim 词库。
*** 第三种方式
可以了解:https://github.com/redguardtoo/pyim-tsinghua-dict
** 如何手动安装和管理词库 这里假设有两个词库文件:
在 ~/.emacs 文件中添加如下一行配置。
(setq pyim-dicts '((:name "dict1" :file "/path/to/pyim-dict1.pyim") (:name "dict2" :file "/path/to/pyim-dict2.pyim")))
注意事项:
** Emacs 启动时加载 pyim 词库
(add-hook 'emacs-startup-hook (lambda () (pyim-restart-1 t)))
** 将汉字字符串转换为拼音字符串 下面两个函数可以将中文字符串转换的拼音字符串或者列表,用于 emacs-lisp 编程。
** 中文分词 pyim-cstring-utils 包含了一个简单的分词函数:`pyim-cstring-split-to-list', 可以 将一个中文字符串分成一个词条列表,比如:
(require 'pyim-cstring-utils) (pyim-cstring-split-to-list "我爱北京天安门")
: (("天安" 4 6) ("天安门" 4 7) ("北京" 2 4) ("我爱" 0 2))
其中,每一个词条列表中包含三个元素,第一个元素为词条本身,第二个元素为词条相对于 字符串的起始位置,第三个元素为词条结束位置。
另一个分词函数是 `pyim-cstring-split-to-string', 这个函数将生成一个新的字符串, 在这个字符串中,词语之间用空格或者用户自定义的分隔符隔开。
注意,上述两个分词函数使用暴力匹配模式来分词,所以,不能检测出 pyim 词库中不存 在的中文词条。
* 获取光标处的中文词条 pyim-cstring-utils 包含了一个简单的命令:`pyim-cstring-words-at-point', 这个命令 可以得到光标处的 英文 或者 中文 词条的 列表*,这个命令依赖分词函数: `pyim-cstring-split-to-list'。
** 让 forward-word' 和
back-backward’ 在中文环境下正常工作
中文词语没有强制用空格分词,所以 Emacs 内置的命令 forward-word' 和
backward-word' 在中文环境不能按用户预期的样子执行,而是 forward/backward “句子”
,pyim自带的两个命令可以在中文环境下正常工作:
用户只需将其绑定到快捷键上就可以了,比如:
(require 'pyim-cstring-utils) (global-set-key (kbd "M-f") 'pyim-forward-word) (global-set-key (kbd "M-b") 'pyim-backward-word)
** 为 isearch 相关命令添加拼音搜索支持 pyim 安装后,可以通过下面的设置开启拼音搜索功能:
(require 'pyim-cregexp-utils) (pyim-isearch-mode 1)
注意:这个功能有一些限制,搜索字符串中只能出现 “a-z” 和 “'”,如果有其他字符(比 如 regexp 操作符),则自动关闭拼音搜索功能。
开启这个功能后,一些 isearch 扩展有可能失效,如果遇到这种问题, 只能禁用这个 Minor-mode,然后联系 pyim 的维护者,看有没有法子实现兼容。
用户激活这个 mode 后,可以使用下面的方式 强制关闭 isearch 搜索框中文输入(即使 在 pyim 激活的时候)。
(setq-default pyim-english-input-switch-functions '(pyim-probe-isearch-mode))
** 创建一个搜索中文的 regexp
(pyim-cregexp-build ".nihao.")
: (?:.(?:nihao|[㒟㖏㖕㖖㖻㘈㘝㘨㘿㙞㚔㜤㜦㜵㜸㝕㞋㞙㞾㟧㠜㠡㡪㣇㣷㤛㥾㦐㧱㩘㩶㪒㭤㮆㮏㮞㮟㲡㲰㲻㲽㳮㴪㵫㸎㹸㺲㼭㽱㿦䀑䀔䁥䂇䂼䃵䄒䄭䄹䆨䇣䋴䋻䌜䌰䍲䏔䐁䒜䔭䕥䖆䗿䘌䘦䘽䙚䚓䚾䛏䛘䜆䜓䝚䞕䟢䡾䤔䦊䦵䧇䧔䩞䬯䭃䭢䭲䮍䮗䮘䯀䯅䯵䰯䳖䴴䵑䵒乜伱伲佞你侫倪儗儜儞兒凝匿卄呢咛唸啮喦嗫噛嚀嚙囁囐囓囜圼坭埝埿堄妞妮妳姩娘婗嫋嫟嬝嬢嬣嬲嬺孃孨孴孼孽宁寍寕寗寜寧尼尿屔屰峊嵲嶭巕帇年廿念忸怓怩恁您惄惗愵慝懝扭抐抝抳拈拗拟拧拰捏捻掜揑摂摄摰撚撵擜擬擰攆敜旎昵晲暱杻枿柅柠棿榐槷樢橣檷檸櫱氼氽汼沑泞泥涅涊淣淰湼溓溺濘炄牛牜狃狋狔狞猊獰甯疌疒痆眤睨矃碾祢禰秊秜秥篞簐籋籾粘糱糵紐縌纽聂聍聶聹聻胒脲腝腻膩臡臬臲艌苧苨苶茑茮莥菍蔦蔫薴薿蘖蘗蚭蚴蛪蜺蠥衂衵袅裊褭褹觬誽諗譺讘貎跈跜踂踗蹍蹑蹨躎躡輗輦輾辇辗迡逆郳酿醸釀鈕鈢鈮鉨鉩銸鋷錜鎳鑈鑏鑷钀钮铌镊镍闑陧隉隬霓靵顳颞馜鬡鬤鮎鯓鯢鯰鲇鲵鲶鳥鶂鷊鸋鸟鸮鹝鹢麑黏鼰齞齧齯][㕺㘪㙱㚪㝀㞻㠙㩝㬔㬶㵆䒵䚽䝞䝥䧚䧫䪽䬉䯫侾傐儫勂号呺哠嗥嘷噑嚆嚎壕好峼恏悎昊昦晧暠暤暭曍椃毫浩淏滈澔濠瀥灏灝狢獆獋獔皓皜皞皡皥秏竓籇耗聕茠蒿薃薅薧藃號虠蚝蠔諕譹诐豪貉郝鄗鎬镐顥颢鰝鶴鸮]).)
** 让 ivy 支持拼音搜索候选项功能
(require 'pyim-cregexp-utils) (setq ivy-re-builders-alist '((t . pyim-cregexp-ivy)))
** 让 avy 支持拼音搜索
(with-eval-after-load 'avy (defun my-avy--regex-candidates (fun regex &optional beg end pred group) (let ((regex (pyim-cregexp-build regex))) (funcall fun regex beg end pred group))) (advice-add 'avy--regex-candidates :around #'my-avy--regex-candidates))
** 让 vertico, selectrum 等补全框架,通过 orderless 支持拼音搜索候选项功能。
(defun my-orderless-regexp (orig-func component) (let ((result (funcall orig-func component))) (pyim-cregexp-build result)))
(advice-add 'orderless-regexp :around #'my-orderless-regexp)
** 让 pyim 在 Termux Emacs 中正常工作
Pyim 在 Termux Emacs 中,可能遇到类似下面的报错:
error in process sentinel: End of file during parsing
这可能是 Termux Emacs 中的 emacs-async 包运行不正常导致的,全拼和双拼的用户可以 使用 pyim-dregcache 后端,因为这个后端不需要 emacs-async 提供的功能。
(require 'pyim-dregcache) (setq pyim-dcache-backend 'pyim-dregcache)
形码用户暂时没有什么好办法,可以将其他设备上的 ~/.emacs.d/pyim/dcache 目录拷贝到 Termux Emacs 对应的目录,然后设置:
(setq pyim-dcache-auto-update nil)