tig是一个基于ncurses库的git log、status的浏览器,看log的时候非常方便,可以非常简单的查看每次log的diff,同时方便的切换到其他视角例如diff、blame、tree等等。但是,tig有一个问题,不支持搜索中文。
检查了相关的issue以后,确认了链接时使用-lncursesw,支持中文这种宽字符的显示,实际应用中也可以显示,但就是没办法搜索中文。于是,我向作者报告了这个bug:https://github.com/jonas/tig/issues/99
似乎作者不太在意i18n的问题,等了好几天都没有给答复,只好自己动手了。遇到问题的是搜索,按search关键字查找,定位到REQ_SEARCH上面去,这应该是tig内部状态机的一个状态。在main函数里,是一个很清晰的状态机,用switch语句切换不同的状态。可以看到,REQ_SEARCH与REQ_SEARCH_BACK都调用到read_prompt,最终落到prompt_input读取输入。
看来prompt_input就是无法输入中文搜索的罪魁祸首了。得益于tig代码清晰的结构,定位这个bug还是比较容易的。为了确定用户输入的结束,prompt_input通过一个外部参数handler确定一个字符是否是可见字符,如果是不可见字符,则不加入到buf中来。由于utf8的字符是变长的,兼容ASCII码,剩下的都是两字节字符和三字节字符。区分字长,则由第一个字符(又称引导字符)决定。
关于utf8的字符是如何区分两个字节和三个字节,可以参考这篇文章:
http://blog.csdn.net/cscmaker/article/details/7986968 (囧,看完才发现我修复的不完美)
根据这篇文章,我做了一个小的修复:
https://github.com/spin6lock/tig/commit/159eff692b24aa05f766f76922b0f2515fbbf415#tig.c
这里将utf8字符单独处理了,但是没有处理utf8标准里4个字节字符的情况。
不过作者一直没有merge到主分支上,残念啊。