gvimext.dll 是一个为 Windows 里任意文件的右键菜单 (context menu) 添加“用 Vim 编辑”菜单项的 shell 扩展,随 gVim 一起安装。

但是无论是官方的安装版本,还是我自己编译的版本,在使用 UTF-8 locale 时 (比如设置环境变量 LANG 为 zh_CN.UTF-8) 这个右键菜单项都会显示乱码。其实原因很简单,Windows 并不原生支持 UTF-8 编码,所以直接使用 TextOut() 之类的 API 输出 UTF-8 编码的消息文本肯定会显示乱码。

曾经尝试修改 gvimext.cpp,在里面覆盖环境变量 LANG 的值,去掉末尾的 .UTF-8,但这样做的结果是导致 gvimext.dll 寄生进程 explorer.exe 或 TotalCmd.exe (如果是在 Total Commander 中使用右键菜单的话) 的 LANG 也被修改,造成由 explorer 启动的 gVim 的 LANG 也成了被去掉 .UTF-8 的值 (因为子进程默认会继承父进程的环境变量)。后来又想起了 Cygwin 里的 OUTPUT_CHARSET 环境变量,可以在 gvimext 里将获取到的 UTF-8 消息文本使用 iconv() 转换为 OUTPUT_CHARSET 设定的编码,这样问题就可以圆满的解决了。

直到今天打算来实施这个想法时,又回头去看了一下以前 Google 到的这篇 The Unicode HOWTO: Locale setup,才发现原来 glibc 本来就有这样的自动编码转换能力,并且 2.2 以后的版本也不再需要设定 OUTPUT_CHARSET 了。偶太无知无畏了……

那么 gVim 安装版里的 libintl.dll 肯定不是 gcc 编译的,所以没有自动编码转换能力导致乱码,用 PEiD 看了一下果然是 MS VC 6.0 编译。接下来就简单了,去 GnuWin32LibIntl 页面下载 Binaries 和 Dependencies 两个压缩包,取得其中的 libintl3.dll 和 libiconv2.dll,前者改名为 libintl.dll (gVim 被硬编码为只尝试载入 libintl.dll 这个文件,想了想没必要改源代码,因为以后 LibIntl 出了新版本 libintl3.dll 里的 3 还会变化)。然后将这两个文件放到 PATH 环境变量中列出的任意一个目录里,最后删掉 gVim 安装目录下的 libintl.dll,OK,一切都是那么完美了。:p

标签:, , ,

5 Responses to “解决 gvimext 在 UTF-8 locale 下乱码的问题”

  1. 量子公民No Gravatar Says:

    The Unicode HOWTO 0.18?版本太旧啦……

    其他大.org站上有2001年新版的: http://www.faqs.org/docs/Linux-HOWTO/Unicode-HOWTO.html http://www.linux.org/docs/ldp/howto/Unicode-HOWTO.html http://www.ibiblio.org/pub/Linux/docs/HOWTO/Unicode-HOWTO

  2. RainuxNo Gravatar Says:

    狂汗一地……

    还好偶只看了 3.4 小节,新版没什么变化。谢谢楼上的朋友。PS: 貌似你的 blog 更新频率跟偶的有得一拼。:p

  3. tooNo Gravatar Says:

    多谢楼主, 我只会提问不懂解决... 经测试, 解决方案完美. 赞一个.

  4. auxoNo Gravatar Says:

    你好,想私下請教一下關於右鍵選單訊息的問題,不知道方便嗎?

  5. RainuxNo Gravatar Says:

    @auxo 你好,我的 Email 是 rainux # gmail.com。

Leave a Reply