2016-10-11 67 views
2

我試圖綁定使用GNU Readline library箭頭鍵用C。我已經打印出rl_bind_key的ASCII(0-255)鍵值的所有可能組合,但箭頭鍵似乎未被檢測到。結合方向鍵Readline庫

我該如何綁定他們?

static int readline_func(int count, int key) { 
    printf("key pressed\n"); 
    return 0; 
} 

int i = 0; 
for (; i < 255; i++) { 
    rl_bind_key(i, readline_func); 
} 

感謝您的幫助!

回答

5

綁定箭頭鍵並不那麼簡單。

首先,箭頭鍵​​不是單個字符;他們是字符序列。每個箭頭鍵發送的精確字符序列將取決於你的終端仿真器,但如果你使用的是Linux與xterm類似的終端模擬器,你可能會發現,方向鍵發送序列:

  • ↑   ESC[
  • ↓   ESC[
  • ESC[Ç
  • ESC[d

(你可以在由托馬斯·迪基保持useful compendium of control sequences更多信息。請注意,CSI是「控制序列啓動子」ESC[)。

要綁定這些序列,您需要使用rl_bind_keyseq,指定readline樣式的「keyseq」(請參閱​​man readline;搜索keyseq)。例如,要右箭頭結合於函數時,你可以調用:

rl_bind_keyseq("\\e[C", right_arrow_function); 

初始readline的綁定包括用於所有標準鍵綁定,使用各種不同的可能的密鑰對keyseq映射的情況下,所述終端仿真器正在使用其他仿真。

您可能認爲使用rl_bind_key綁定轉義鍵(0x1B)會覆蓋該鍵序列(因爲它以轉義開頭),但這不是readline的工作原理。

Readline使用鏈接的鍵盤映射的鍵綁定多字符序列,其中序列中的每個鍵依次綁定到下一個鍵盤映射。確切的機制並不重要 - readline會處理它 - 但你需要知道綁定鍵綁定的前綴是不可能的,因爲前綴將綁定到子鍵映射,子鍵鍵映射綁定優先於任何其他類型的綁定。

因此,任何嘗試重新綁定綁定keyseq的前綴將失敗沒有任何錯誤指示; rl_bind_key(或rl_bind_keyseq)將返回0,即使綁定沒有效果。因此,對所有可能的8位字符進行循環試圖綁定ESC,並且對rl_bind_key的調用將會成功,但轉義鍵仍將綁定到子鍵映射。 (我個人覺得缺乏一個錯誤返回刺激性的,那將是很好的得到一個錯誤指示。)

rl_command_function被調用時,順便說一下,在key參數將包含的代碼在最後的關鍵序列。 (這是由於它是實際保存綁定信息的最後一個鍵,因此在相應的子鍵映射中)。對於箭頭鍵來說,這是正確的,但是對於綁定大量鍵(包括PageUp和PageDown ,其碼序列具有形式ESC[p其中p是一些(可能是多位)數識別的關鍵,但在所有的序列的最後一個字符是

+0

這是一個很好的答案!我很驚訝沒有更多的文件。非常感謝! –

+0

@rici這真是一個很好的答案!我幾乎整天都在尋找這個東西......我會試試這個 – hrushi

0

ASCII encoding character set,你可以看到,有沒有像箭頭鍵特殊鍵的概念,你的徑流式的磨鍵盤提供。

其您的平臺鍵盤驅動程序發送字節序列到您的程序,所以回答將取決於平臺。在Linux上,例如termcap提供了這些信息,您可以通過C程序中的ncurses library訪問此信息。

檢查this article