在終端中檢測 shift + keyup/down
我該怎麼做呢?我想要一個終端菜單,其中
shift+up
或shift+down
選擇多行。ncurses
似乎有問題。我不一定需要高級終端庫。我只想處理這個,除此之外我的 IO 應該非常簡單。
有什麼建議嗎?
終端傳輸字元,而不是密鑰。大多數字元都是可列印的,這樣就沒有太多空間來編碼功能鍵和鍵弦。
\e
功能鍵被編碼為轉義序列,即以轉義字元開頭的字節序列(字節值 27,可以像在許多程式語言中一樣寫出)。有關更多詳細資訊,請參閱鍵盤輸入和文本輸出如何工作?每個鍵或鍵弦發送的轉義序列沒有通用標準。curses 庫提供了一個對功能鍵進行解碼的抽象層。它在底層使用了termcap(舊式)或terminfo(現代)庫;如果不想與 curses 連結,可以直接使用 termcap/terminfo。
Up
或者,您可以對和的常用控制序列進行硬編碼Down
。雖然沒有標準,但幾乎每個終端都發送\eOA
or 或\e[A
forUp
和\eOB
or 或\e[B
forDown
,而且我從未見過為不同的密鑰發送這些序列的終端。keychords
Shift
是另一回事:它們發送的轉義序列更加多樣化,並且許多終端不區分Up
例如Shift
+Up
。除非您只支持一組受限制的配置,否則您不能依賴這些是不同的。有一些新興標準,但許多流行的終端仿真器仍然不支持它們。終端不發送按鍵事件。(不過,根據您的描述,您的案例不需要它們。)
除非您負擔得起需要特定的終端仿真器(例如最近的 xterm),否則不要依賴使用者能夠鍵入
Shift
+Up
。支持另一種方法,例如“開始多選”鍵後跟普通Up
/Down
。
從問題的上下文中,
shift+up
並shift+down
參考shift-cursor-up
andshift-cursor-down
(而不是,例如,shift-page-up
andshift-page-down
),因為問題詢問了關於選擇多行的問題。這其實不止一個問題:
- 首先,如何讓ncurses辨識
shift+up
等,以及- ncurses 菜單庫是否執行此操作,以及
- 如果沒有,如何獲得菜單。
首先,ncurses 為一組可移植的(更多/更少)特殊鍵提供預定義的(每個 X/Open Curses)定義。參考terminfo(5),您可能會注意到:
key_sf kind kF scroll-forward key key_sleft kLFT #4 shifted left-arrow key key_sr kri kR scroll-backward key key_sright kRIT %i shifted right-arrow key
但沒有任何標記為“向上移動的箭頭鍵”。只有事後諸葛亮,才能將 and 與和
kind
聯繫kri
起來。在 1999 年為 xterm 添加對修改後的特殊鍵的支持之前,幾乎沒有現有技術:kLFT``kRIT
更新檔 #94 - 1999/3/27 - XFree86 3.9Pf
將參數添加到功能鍵以指示是否設置了 shift、control 或 alt。這些程式碼基於 Jeffrey Altman 對帶有 PC 鍵盤的 DEC VT510 的描述。
後來,對該方案進行了修改,以減少應用程序的混亂。其他從 xterm 複製該功能的開發人員並沒有效仿修改他們的程序:
更新檔 #167 - 2002/8/24 - XFree86 4.2.0
添加
modifyCursorKeys
資源以控制如何使用 shift- 和類似的修飾符來製作游標轉義序列。預設情況下,修改後的轉義序列始終以 CSI 開頭,並將修飾符作為第二個參數,以避免混淆將第一個參數解釋為重複計數的應用程序。可以通過將資源設置為 0 來獲得原始行為(與 Stephen J Turnbull、Jeffrey Altman 的新聞組討論)。同時,在 ncurses 中,將這些合併到終端描述中似乎很有用(因為 ncurses 使用終端數據庫,而不是 tmux 使用的表)。這些依賴於ncurses 5.0引入的使用者定義功能的特性。在終端數據庫中,在2004 年提到了 xterm 的功能:
# 2004-07-17 # * add xterm-pc-fkeys -TD
其中(除了鞏固早在2001 年的早期工作之外)試圖處理可能與 xterm 資源的不同組合一起使用的修飾符編碼的變化——以及與 xterm 編碼方案在不同程度上不同的相似之處。
用於使用者定義功能的約定從將
kDN
和添加kUP
到列表(您的shift+down
和shift+up
)以及與 xterm 修飾符程式碼對應的數字開始。很久以後,很明顯,kind
並且kri
可能具有相同的含義。但結果是,您可能會發現終端描述帶有kDN
和kUP
(僅 ncurses 讀取——其他直接讀取終端數據庫的應用程序和庫已經忽略了這一點大約 16 年)。擴展功能匯總在終端數據庫中。
現在(從第二部分開始),ncurses 確實提供了一個菜單庫。這是 SVr4 菜單庫的重新實現(帶有一些擴展,例如支持多字節字元)。為此,請參閱手冊頁
menu_driver(3x)
,以及展示該庫的ncurses-examples中的程序。簡短的回答是菜單庫沒有預定義您所詢問的行為,但應用程序可以使用該庫來執行所要求的操作。首先看看如何使用這個細節:
REQ_TOGGLE_ITEM
選擇/取消選擇一個項目。
更大的問題是在此應用程序中使用使用者定義的功能引起的。大多數使用表單庫和菜單庫的應用程序都依賴於使用特殊鍵的預定義符號進行案例陳述。因為
shift+up
並且shift+down
你不會有那個(除非 和 的巧合kind
被kri
注意到和應用)。對於使用者定義的功能,沒有預定義的鍵碼(例如KEY_DOWN
incurses.h
)。相反,您擁有由key_defined
函式確定的執行時定義的值。因此,需要一些間接而不是簡單的 case 語句(沒有KEY_SDOWN
in )。curses.h