说明
我的Emacs一直无法支持用helm-ag搜索中文。在用Emacs做主力编辑时,要用到ag搜索时,只能在cygwin下进行。 一年前就想把印象笔记迁到org了,但快速的中文搜索是必要的,也因为这个原因不能迁。
直到最近看到这样的软文,太不严谨了,难道要学锤子…
而且前段时间,某版本的印象笔记,竟然有无法同步的bug,官方给的解决方案是手工降版本。 不靠谱啊… 是时候加速逃跑计划了,希望能在国内版代码被改得越来越糟之前。
中文搜索,是个劝退力相当强的问题。这个问题会出现在新手阶段,一般能搜索到的解决办法都是:尝试改10几个encoding相关的函数和变量。在过去1年里,自己也常常突然起兴,改一组encoding试试,然而都GG了。好在我还没有被劝退… 昨天又折腾了一次,总算是解决了这个问题。
下面的内容,会对以下问题有所帮助:
- 任何系统的任何语言下(Windows/OSx/Linux/Android…)使用helm-ag搜索中文,无结果或显示乱码
- 使用helm-ag搜索时,出现emacs卡死
我自己目前只在Windows7上折腾好了。其他系统的思路是一样的。
误区: helm-ag的搜索问题,与shell的选择和设置有关
打开helm-ag.el源码,能找到调用ag.exe的语句:
(apply #'start-file-process "helm-do-ag" nil cmd-args)
Emacs提供了几个起子进程的函数:
- shell-command-to-string
- start-process-shell-command
- start-process
- start-file-process
- call-process
- …
这些函数名字里,带有“shell”的,是与当前设置的shell有关的;而其他的都和shell没任何关系。
helm-ag用的start-file-process,和shell无关。
如果你和我一样,在cmd cmdproxy zsh bash 之间换了又换,那现在可以停下来了,往下看。
继续往下看,你会发现helm-ag的编码问题,只与一个encoding配置有关…
ag rg pt 的选择
在windows下,有ag ag(cygwin) rg pt,这几个选择。
从大家的评价看,Windows下用rg是最好的,而用cygwin的ag,我自己测下来一定会卡很久。
用Windows的同学,可以去下载rg.exe,然后加入PATH了。如果用的其他系统,也建议装下rg,后续说明都是以rg为例。
快速修正编码设置
M-x list-buffers
切换到 scratch
M-x emacs-elisp-mode
启用elisp mode
写这么一行:
(call-process "rg" nil t nil "中文")
然后在你的HOME目录下,放一个带有"中文"两个字的文本文件。
把光标放在这行,按M-x lisp-state-eval-sexp-end-of-line
可以看到在这行的后面,或者没有追加任何搜索结果,或者追加了错误信息,或者搜索结果中应该是中文的,显示为了乱码。
再写这么一行
(modify-coding-system-alist 'process "rg" '(utf-8 . chinese-gbk-dos))
其中:
- rg 表示只修改"rg"进程的编码
- '(utf-8 . chinese-gbk-dos)里的chinese-gbk-dos表示: 从Emacs向rg进程提供文本参数时,编码为gbk
- '(utf-8 . chinese-gbk-dos)里的utf-8表示: 从rg获取进程输出到Emacs时,解码为utf-8
为什么要这么设置呢? call-process 函数不通过shell启动进程,而是由操作系统直接启动。而Windows7中文版本的系统编码为gbk。
… 这里的表述不够准确,但且先这么理解
而Emacs内处理所有文本,都是utf-8的
通过这行配置,即可解决Emacs和rg之间对接时的编码问题了
光标移动到这行,M-x lisp-state-eval-sexp-end-of-line
执行一下
而后再回头执行下call-process
那一行,顺利的话,就能看到中文搜索结果被追加且正常显示了。
如果还是不行,请把chinese-gbk-dos换成你的系统的默认编码
最终配置
请把下面两行加入 **dotspacemacs/user-config()**函数:
(modify-coding-system-alist 'process "rg" '(utf-8 . chinese-gbk-dos))
(custom-set-variables '(helm-ag-base-command "rg --vimgrep --no-heading --smart-case"))
加第二行是因为,最近发现修改了dotspacemacs-search-tools '("rg")
不起作用,helm-ag时,还是用的ag,而非rg。
顺带一提
- 这几个都是一样的,互为本体和别名的关系 chinese-gbk-dos gbk-dos windows-cp936-dos
- 可随时用
M-x describe-current-coding-system
,翻到Process I/O部分,来检查对rg进程的编码设置
遗留问题
helm-ag的搜索结果里,多一行: .\nul: 函数不正确。 (os error 1)
但是没什么影响,如果有人知道的话,请解答下~