星期二, 8月 04, 2009

readline callback, key binding bug

今天發現readline 的bug, 是因為在 vi-mode (callback) 我不管怎麼 bind pageup/down (\e[5~, \e[6) 都不成功,trace 了一下,發現是 _rl_dispatch_callback 裡面有個 bug (應該是bug .. :p)

readline 的 callback 為了要避免block,可是又要能夠吃 key sequence 的 binding ,所以設計了一個類似 stack 的結構,模仿一個 non-blocking 的 recursive call.

裡面一樣是呼叫 _rl_dispatch_keyseq 但因為有設定 RL_STATE_CALLBACK,做完一次的 dispatch 就會直接回傳,等下一次 rl_callback_read_key() 被呼叫才會再來 dispatch。 這時候 _rl_dispaych_keyseq 的回傳值有4 種 -3 ~ 0 分別是指下面這幾種意思:

0: 成功 match 到 key sequence
-1: key 沒有match, 所以最後一個之前有match 到的 keyseq 會被執行
-2: match, 但是是 keymap 裡的 ANYOTHERKEY, 也就是說大概還有同個長度的keyseq 存在,不過總而言之就是有match 到
-3: 「還」沒有match,還要看後續讀入的key

bug 是在,當回傳是 -3 的時候,readline 會看上上一個有沒有被 match (當輸入到 \e[6 的時候,會看 \e 有沒有match),為什麼會這樣設計我不清楚,不過bug 就在這邊了。解法呢.. 很簡單,只要在 r == -3 的時候跳過 _rl_keyseq_result 的檢查就行了。下面附上非長短的 patch,手動改就可以了 :p

http://moon.cse.yzu.edu.tw/~s961449/readline-callback.patch

使用方法:
到readline 的 source directory 裡面, 用patch
cd readline-6.0 && wget http://moon.cse.yzu.edu.tw/~s961449/readline-callback.patch && patch -p1 < readline-callback.patch


寫的好亂 XDDD

沒有留言: