Categories

Calendar

August 2017
M T W T F S S
« Jun    
 123456
78910111213
14151617181920
21222324252627
28293031  

解决 ibus 在 gVim/Emacs 下不能使用的问题

ibus 是 Linux 下一个比较新的输入法框架,其下的 ibus-pinyin 也是比较不错的一个输入法,不过整个项目相对来说还是比较新,所以偶尔也还会有一些小问题,并不是诡异的 bug 或者是开发难度上不可行,只是大概还有跟多优先级更高的模块需要处理,比如之前说过的用 Ctrl 切换中英文状态的问题。事实上如果只是自己用的话,做一点小小的 dirty hack 也是非常方便的事情,因为 ibus 是用 Python 写的,直接修改系统中对应的文件即可,甚至都不用重新编译。

如题目所说,今天要解决的问题是 ibus 在 gVim 和 Emacs 下不能使用的问题。先说 Emacs 吧,这个似乎是一个老问题了,症状就是在 Emacs 里不能激活输入法,好像从数年前开始就一直都有类似的问题,包括 scim、 fcitx 等众多输入法在内都有过类似的问题,似乎是一部分 Gnome 用户会遇到,在 Emacs 里无法激活输入法,但是也有另外一些人正常使用,所以后来似乎也没弄明白原因,这里的问题我也不确定是不是同一个,但是症状确实挺像。

事实上,在 en_US 的 locale 下要使用输入法的话,通常需要修改一下 /etc/gtk-2.0/gtk.immodules (不同的发行版该文件的位置可能不太一样),把如下的一行

"xim" "X Input Method" "gtk20" "/usr/share/locale" "ko:ja:th:zh"

加进去一个 en 变成:

"xim" "X Input Method" "gtk20" "/usr/share/locale" "en:ko:ja:th:zh"

这样就可以在 en_US 的 locale 下使用输入法了,不过,在 Emacs 里还是无法激活,经过在论坛上的讨论,我被告知可以通过把 LC_CTYPE 设置为 zh_CN 才可以在 Emacs 里使用输入法,例如,可以通过如下方式启动 Emacs :

LC_CTYPE=zh_CN.utf8 emacs

至于具体为什么必须要这样才行,我也没有再去深究,毕竟问题得到解决就可以了。

再就是 gVim 里的问题,症状和 Emacs 里不一样,输入法可以激活,但是输入了一两个字母之后输入法立马就被关掉了。目测因该是由于嵌入式编辑和 gVim 起了冲突的缘故。

preedit嵌入式编辑我也不知道用一个什么名字来称呼它好,就是在输入拼音的时候在编辑框内直接填上现在已经确定了的汉字,我最早见到这种输入方式是在微软拼音中,后来 SCIM 也支持这种方式,但是由于对它深恶痛绝,从来都是关掉的,因为待输入的文本框可能的样式千奇百怪,输入法并不能完全去适应,既然已经可以在一个输入条中显示出中文了,为什么还要嵌入到编辑框中去呢?如图所示,下面的光标如果在词 english 前面想要输入中文,那么嵌入式的预编辑的文本会直接“覆盖”掉单词 english 的前半部分,当然这只是显示上的“覆盖”,实际的文本并没有被修改,但是我觉得也是不太友好的,既然没法做好,而且也有在输入条里的很直观的显示,为何还要这么多此一举呢?当然,最关键的问题是它在某些情况下似乎会和 gVim 发生冲突。

说是在某些情况下,是因为我在两个机器上一个可以正常使用一个却不可以,不太确定是不是程序版本的问题,不过我现在可以通过关闭这个叫做 preedit 的东西来解决这个问题。原本因该像 SCIM 那样可以有一个选项选择关闭的,不过 ibus 的选项面板里还没有加入这个选项,于是我就直接暴力地修改一下好了,打开 /usr/share/ibus-pinyin/engine/pinyin.py ,找到 update_preedit 函数的定义:

def update_preedit(self, preedit_string, preedit_attrs, cursor_pos, visible):
    if preedit_attrs == None:
        preedit_attrs = ibus.AttrList()
        attr = ibus.AttributeUnderline(ibus.ATTR_UNDERLINE_SINGLE, 0, len(preedit_string))
        preedit_attrs.append(attr)
 
    super(PinYinEngine, self).update_preedit_text(ibus.Text(preedit_string, preedit_attrs), cursor_pos, visible)

废掉它,比如,在第一行加一个 return 或者把最后一行的 super 调用注释掉。保存之后在 ibus 的托盘图标那里选择 restart 就可以了。

不过这样的暴力修改也是有一些副作用的,因为 ibus-pinyin 对于不合法的拼音片段并不会在面板上显示出来,比如 i ,关闭 preedit 之后在中文状态下输入 i 看不到任何反馈,不过这几乎不影响使用,而且我觉得这似乎是 ibus-pinyin 在显示的设计上需要修改的地方,对于一些习惯直接输入单词再回车上屏的人估计就不太方便了。

总的来说,ibus-pinyin 还是一个不错的输入法的,希望能好好发展,争取让 Linux 下的输入法不要再和 Windows 下差距那么大。

15 comments to 解决 ibus 在 gVim/Emacs 下不能使用的问题

  • 你提到的问题我现在都没重现出来 – -,我的环境变量中只有LC_CTYPE是zh_CN,在用过一段时间ibus-pinyin后感觉像是在贪心地匹配,比如”这个数如法”而不是”这个输入法”。
    陈华老师说以前有一个wineinput,顾名思义的,当时成功让紫光拼音在Linux下跑起来,不过在2006年后销声匿迹了 -.-b

  • @quark
    所以说这些问题都是相当看 RP 的啊,Emacs 下不能用输入法这个问题好多年了不好解决估计就是不能精确重现吧。

    ibus 这类的输入法的定位是词吧,以词为单位输入,而不是以句子为单位,以句子为单位的话还是微软拼音那种比较好吧,因为根据后面输入的东西还可以纠正前面的输入,不过我个人不太喜欢这种。当然 ibus-pinyin 内部的算法可能本身也比较简单,具体我也没有看过,不过肯定也是可以有不少改进的余地的,最近闲的时候也在看一些 sunpinyin 公布出来的文档,如果你也对输入法有兴趣的话,我们可以平时交流交流。 :)

  • @pluskid
    确实感兴趣~~
    先考完试要紧 -.-

  • imonyse

    我也是用英文的locale,不过在Fedora下只要运行一下im-chooser(GUI程序)就可以了,依稀记得debian还是ubuntu里有一个im-switch命令行工具,也可以很容易的在英文locale激活输入法,但是我已经很久不碰这2个发行版了。

    网上找答案的一个困扰是,‘优雅‘的解决办法总是被铺天盖地的‘肮脏’办法掩盖了。

  • 我这所有的LC都是”en_US.UTF-8″的, 没有碰到ibus不能在Emacs里用的问题. 倒是换了ibus之后, 在TC的Arena里输密码时总要点一下那个选服务器的框的问题解决了..

  • @imonyse
    是呀,Ubuntu 里面的 im-switch 很好用,不过 ArchLinux 里面没有这个工具。

  • @Ai.Freedom
    恩,所以这个问题似乎相当难重现,不知道都有哪些因素在作怪。

  • @quark
    momo 考试加油吧,你暑假还在学校的吧?

  • nil

    gtk.immodule 里头我改的 im-ibus.so 那一栏,这个是跟 export GTK_IMMODULE=ibus 对应的否?

  • @nil
    要改 xim 那一行,加入 en :

    "/usr/lib/gtk-2.0/2.10.0/immodules/im-xim.so" 
    "xim" "X Input Method" "gtk20" "/usr/share/locale" "en:ko:ja:th:zh"

    不过我还看到一行 ibus ,就一起改了,不太清楚是哪行生效的。

  • 以前用的好好的,最近换到gentoo上,竟然在gvim里遇到这么个问题

  • Yunhui Liu

    学长,我想问你一下,emacs编C/C++代码的问题,怎么就能将一个设置绑定到在打开.cpp/.c文件的时候才加载,在.emacs里应该怎么写?打开代码文件的时候,怎么才能用上CEDET的功能?我在网上看了很长时间,没有头绪啊

  • 在 ibus-table 上也关闭了 preedit 的更新,这个功能真是太不爽了,谢谢!

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>