rg.el 无法在 windows 上搜索中文是一个已知问题:
Cannot search for Non-Ascii characters (ex. å) #101
Chinese character search results not show on rg result buffer #117
一个比较流行的解决方案是使用 locale-coding-system
,比如:
(setq-default default-process-coding-system `(utf-8-dos . ,locale-coding-system))
该方法的缺陷在于,它仅仅把 charset 从 ASCII 扩展到 GBK(尽管 GBK 在很多情况下也够用)。然而,随着近几年 Unicode 的普及,对 Unicode character 搜索的需求越来越大。特别是某些编程语言可能会使用罕见数学符号。rg.el 在 Windows 上仍不支持 Unicode。
最近对这个问题做了一些研究,发现其根本原因是:NTEmacs 在创建子进程时,文件名和参数被限制在当前 ANSI Codepage。
Running subprocesses in non-ASCII directories and with non-ASCII file arguments is limited to the current codepage (even though Emacs is perfectly capable of finding an executable program file in a directory whose name cannot be encoded in the current codepage). This is because the command-line arguments are encoded before they get to the w32-specific level, and the encoding is not known in advance (it doesn’t have to be the current ANSI codepage), so w32proc.c functions cannot re-encode them in UTF-16. This should be fixed, but will also require changes in cmdproxy. The current limitation is not terribly bad anyway, since very few, if any, Windows console programs that are likely to be invoked by Emacs support UTF-16 encoded command lines.
For similar reasons, server.el and emacsclient are also limited to the current ANSI codepage for now.
Emacs itself can only handle command-line arguments encoded in the current codepage.
换句话说,NTEmacs 创建子进程调用的是 CreateProcessA 而非 CreateProcessW (当前没有很好的方法在 Emacs 源码里 fix)。
这里提供一个解决方案:
不直接传递 ripgrep 的 UTF-8 参数,而是在每次搜索时生成一个临时 .bat 脚本,把 UTF-8 字符包在 .bat 脚本里面。真正传递给 cmdproxy 的是一个 ASCII 文件名。
我已经给 rg.el 提交了 PR Fix the issue where rg.el couldn't search Unicode characters. by chansey97 · Pull Request #167 · dajva/rg.el · GitHub
打上该补丁后,Emacs 在 Windows 上支持搜索完整 Unicode planes(包含罕见文字和 Emoji)。需设置 (setq rg-w32-unicode t)
。