自己写了一个输入法, Windows下的五笔
这是我很多年前写的一篇文章,发表在 linuxsir 上,现在把他重新整理一下, 贴到自己的博客上。
在我的前一篇老博客里,我以为自己的脑子进水了,所有的标点都采用了英文标 点,看完这一篇才明白,自己当时的输入法不支持中文标点。所以抱歉,但我还 是懒得改:-)
后来又折腾折腾,最后搞出来Linux/Win32/Emacs下都可以用了,名字也取成 SDIM(Shadow Dance Input Method,影舞笔),然后到水木清华bbs的Emacs版了 广告了一下,在 这里。
==============
嗯, Windows的, 还是五笔? 有病吧? 脑残吧? Windows下那么多输入法了, 五笔 的也有很多, 什么极点, 万能, 甚至还有启程之星, 最后这个还是部分开源的五 笔输入法呢. 我为什么还要自己写一个呢?
哎, 说来话长啊. 因为我觉得, 输入法就是个很个性化的软件, 每个人都应该有 一个他自己的输入法. 如果Suzhe写的scim不够好, 如果Yuking写的fcitx不够好, 我就把他们俩的捏一块儿, 叫做scim-fcitx:-)
后来我不怎么用Linux了, 在公司一直用Windows XP + Cygwin. scim-fcitx肯定 是没法再用了, 就琢磨着, 自己写一个吧. 拿Windows DDK下的区位输入法的例子 源代码看啊看, 改啊改, 失败, 看不懂, 改不了… 不搞了, 忍一忍算了, 我用 极点吧.
这一忍, 就是两三年的时间. 极点这个键跟fcitx不一样, 那个键也不一样, 算了 啦, 忍了啦, 我也没有极点的源代码, 我就改变自己的习惯吧, 从了极点的快捷 键设置吧. 谁让我看不懂区位输入法的代码呢.
最后让我忍无可忍的是, Cygwin下的X的窗口不能用Windows本地的输入法! 按一 下Windows的输入法切换键, 输入法的窗口是切出来的, 但是按什么键都还是打英 文. 其它的也就罢了, Emacs也没有! 这让我很受不了, 因为我大部分时间都要用 Emacs的, 而Emacs自带的输入法又不是很好用(这是当然的啦, 因为Emacs的键绑 定都是"怪怪"的啦, 比如, 候选词向下翻页人家默认的键是C-n, 也就是 Control + n哎. 又比如, 我用过的所有输入法里, 取消你当前的输入都是按 Escape, Emacs里是按C-g哎).
怎么办? 忍! 极点我都忍了, 这个也忍了吧! 我找来fcitx里的wubi86码表, 倒腾 到Emacs的quail里, 有一些gb18030的字quail还不认, 我只好一个一个的删掉, 为了删它们我还专门学习了emacs里的宏, 要不然每删一个"怪"字我都得敲键盘若 干下, 还不能敲错…
后来在网上看了海峰五笔的码表, 哇, 好全啊, 囧这个字算什么, 那个表连 ㍥ 都 能打出来! 给emacs整上, 极点怎么整不会. 嗯, 忍忍吧…
几年过去了. 我已经爱上了Emacs下打中文的快捷键, 我再也受不了极点了. 我要 再试一次! 我又找来Windows的DDK, 打开区位输入法的代码, 看啊看, 改啊改, 嗯, 看来我这几年阅读源代码的功力还是有长的, 这回大概看懂了, 再加上网上 尤其是启程之星作者(破除封建迷信, 崇尚科学算命)的一篇文章, 我终于把代码 给写出来了.
区位输入法是用C写的, 我用了C++. C++的功力又长了不少, 嘿嘿, 窃喜. 很多以 前没用过, 不知道有什么用的东西都懂一点了…
慢, 这还不算完. 写输入法有多痛苦写过的人才知道. 就一台机器, 出bug了你好 多程序都嘎嘣嘎嘣的崩溃, 用C/C++语言每次改一点代码都还得重新编译, 编出来 的程序(就一个dll)还不能直接安装, 在Windows下你得把所有用过了你的输入法 的进程统统干掉. 我写了一个C#的程序, 能把系统中所有进程load了哪些dll全部 打印, 然后我grep, 然后我用python (Windows自带的) + pywin32写一个脚本, 把那些load了我输入法的进程全部咔嚓… 这个程序还满有用的, 在我更新 cygwin的时候需要把所有load了cygwin1.dll的程序全部咔嚓, 或者哪天我想把所 有notepad的进程全部咔嚓…
扯远了, 最后要说的是, 因为c/c++调试困难, 我的程序有两个版本, 一个是纯 c++写的, 另一个是后来用c++写了一个客户端, 用python3.1写了一个服务端, 模 仿了一下scim的代码组织. 这样组织带来一个显而易见的好处是调试更方便了, 客户与服务之间的协议采用纯文本, 我可以用telnet/nc来调试我的输入法服务 端:
$(echo 'keyed C \'; #这个是我的输入法激活键, 模仿emacs的quail > echo keyed a; #模仿输入a > echo keyed space #模仿输入空格 > )|nc localhost 12345 active: Y #激活了 end: #应答结束 comp: a #编辑串为"a" hint: [abcdefghijklmnopqrstuvwxy] #后续跟这些字符还可能有候选词, 也是模仿quail cands: 工 #候选词为"工" active: Y #状态还是激活 end: active: Y commit: 工 #最后一个"空格"表示要提交这个候选词"工" end:
最后还有一点, 我的输入法极其简陋, 这个是故意的, 不喜欢很多花哨的东西. 只有一点花哨的地方: 它的状态显示条只有一个图标, 是半透明的, 输入法为中 文输入时透明度下降, 图标看得更清楚, 为英文输入状态时图标变得更透明, 呵 呵. 这个图标用的是当前在使用这个输入法窗口的Windows图标. 见我附上的图.
纯c++的代码在这里, c++ + python的代码在这里, 你看出来了, 我的输入法名字 也叫scim哎, 估计suzhe不能答应, 我以后得改…
事实上, 我给自己的输入法起了个名字, 叫做"影舞笔"! 哈哈哈… 意思是用自 己写的输入法, 那简直, 跟佛山无影腿似的, 又跟跳舞似的…
最后, 以上全是用自己的输入法写的… 它不支持中文标点, 你肯定也看出来了 吧:-) 以后我也不一定让它支持, 我忍!