由于我在平日的学习与工作中会经常用到Cygwin中的Emacs,很自然地想到应该将emacsclient作为指定文件类型在Windows explorer中的默认打开程序。这样,便可以直接双击文件后在Emacs中编辑,从而省去了在Cygwin命令行下手动输入路径与文件名的麻烦,亦可以用方便快捷的Windows explorer替代Emacs Dired mode。要实现这样的功能,需要解决两个问题:
- 从Windows文件路径格式到Cygwin路径格式的转换。
- 对于XP操作系统,中文文件名为GBK编码,而Cygwin使用的是UTF-8编码。为此需要对(包含中文的)文件路径进行编码转换。
我的解决办法是:创建一个Windows批处理文件emacsclient.bat,将指定文件类型的默认打开程序与之关联。该批处理文件获取在Windows explorer中被双击的文件路径名,用UTF-8编码存入临时文件。然后,从该文件中提取出路径字符串,将其作为emacsclient的参数调用执行。该批处理文件emacsclient.bat的内容如下:
@echo off touch "/cygdrive/c/.emacsclient_gbk.tmp" cygpath %1 > C:\.emacsclient_gbk.tmp iconv -f GBK -t UTF-8 -o "/cygdrive/c/.emacsclient_utf8.tmp" "/cygdrive/c/.emacsclient_gbk.tmp" for /f "usebackq delims=:" %%f in ("C:\.emacsclient_utf8.tmp") do emacsclient-w32.exe "%%f" @echo on
其中,
touch "/cygdrive/c/.emacsclient_gbk.tmp"
调用Cygwin的touch命令生成临时文件.emacsclient_gbk.tmp,用于存放GBK编码的待打开文件路径名。需要注意,由于touch是Cygwin命令,作为其参数的临时文件路径名应采用Cygwin格式。 然后,调用cygpath命令,将待打开文件路径名(以%1参数传入emacsclient.bat)作为标准输出重定向到C:\.emacsclient_gbk.tmp。需要注意,由于此时的标准输出重定向是在Windows批处理文件中做的,所以临时文件.emacsclient_gbk.tmp的路径应采用Windows格式。值得一提的是,在首次调用emacsclient.bat前,临时文件.emacsclient_gbk.tmp尚未生成,而Windows批处理命令并不支持标准输出重定向到一个不存在的文件。所以,在这之前调用touch命令生成该临时文件是必须的。 再调用iconv命令进行编码转换,将UTF-8编码的路径名存入.emacsclient_utf8.tmp文件。
iconv -f GBK -t UTF-8 -o "/cygdrive/c/.emacsclient_utf8.tmp" "/cygdrive/c/.emacsclient_gbk.tmp"
最后,从.emacsclient_utf8.tmp文件中提取出文件路径名,交由emacsclient-w32程序打开。