← 部落格

使用 useKeymap 設定鍵盤快速鍵

用 useKeymap 宣告一次按鍵綁定,Text.js 就會分派按鍵事件、在 ? 說明畫面中列出、顯示於頁尾,並加入 Ctrl+K 命令面板。

Adam

在此之前,Text.js 應用程式在 useInput 中處理按鍵,再手動於 <KeyHint> 頁尾列出一次。useKeymap 用一個宣告取代這兩項工作。

import { CommandPalette, KeyHelp, KeyHints, StatusBar, Text, useKeymap } from "@textjs/react";export default function Sessions() {  useKeymap(    {      "j, down": { label: "Next", run: next, hint: true },      "k, up": { label: "Previous", run: previous },      "g g": { label: "Go to top", run: top },      "ctrl+s": { label: "Save", run: save, hint: true },    },    { group: "Navigation" },  );  return (    <>      <StatusBar right={<Text color="subtle">main</Text>}>        <KeyHints />      </StatusBar>      <CommandPalette commands={commands} />      <KeyHelp />    </>  );}

按下 j 會執行 next。在 macOS 上,<KeyHints> 會在頁尾顯示 j/↓ Next 和 ⌃S Save,因為這些綁定設定了 hint。? 會開啟說明畫面,列出全部四個綁定,歸在「導覽」群組下,而 Ctrl+K 會開啟可搜尋這些綁定的命令選單。

按鍵語法

語法意義
ctrl+k修飾鍵:ctrl、alt、shift、meta 和 mod
mod+k⌘ 或 Ctrl,依實際按住的鍵而定
j, down替代按鍵
g g按鍵序列,按鍵之間最多間隔 1 秒
G大寫隱含 Shift
?可列印按鍵依字元比對

綁定可以是處理函式,也可以是帶有 label、group、hint、command、disabled 和 noRepeat 的物件。command: false 會讓有標籤的綁定不顯示在命令選單中。沒有標籤的綁定仍可運作,但不會出現在說明畫面或命令選單中。

路由

每個按鍵對應會註冊一個 useInput 處理函式,因此既有的輸入規則仍適用。取得焦點的 <Input> 會優先處理按鍵,因為編輯器的監聽優先順序是 10,按鍵對應則是 0。比對成功的按鍵會停止傳播。開啟的 <Modal> 會停用外部的綁定,除非按鍵對應傳入 global: true。

序列在該處理函式內比對。啟動序列的按鍵會保留為待處理狀態,並停止傳播;如果下一個按鍵在超過 sequenceTimeout(預設為 1000 ms)後才到達,序列就會重設:

if (p.events.length > 0 && now - p.at > sequenceTimeout) p.events = [];

每個根節點各有一個登錄表

有標籤的綁定會發布到屬於主控台根節點的登錄表。<KeyHelp>、<KeyHints> 和 <CommandPalette> 會從中讀取資料,你自己的元件也可以透過 useKeymapBindings() 讀取。當互動視窗開啟時,登錄表只會回傳其中的綁定,因此說明畫面列出的都是當下可用的按鍵。

按鍵對應通常以行內方式撰寫,每次渲染都會建立新物件。為了降低成本,按鍵對應只會在標籤的可見形式改變時重新發布標籤:

// Publish labels only when the visible shape changes (inline keymap objects are fine).const signature = compiled  .map((c) => `${c.keys}\u0000${c.binding.label ?? ""}\u0000${c.binding.group ?? ""}\u0000${c.binding.hint ? 1 : 0}${c.binding.command === false ? 0 : 1}\u0000${c.binding.disabled ? 1 : 0}`)  .join("\u0001");

按鍵到達時,處理函式會從 ref 讀取,因此每次渲染產生的新閉包都不會過時。

說明畫面與命令選單

按下 ? 會開啟 <KeyHelp>,依群組列出所有目前有效且有標籤的綁定。keys 和 title 可變更觸發按鍵與標題。

按下 Ctrl+K 或 Ctrl+P 會開啟 <CommandPalette>。它會對你的 commands 和所有有標籤的綁定做模糊比對,並醒目標示符合的字母。它會先關閉再執行命令,因此命令可以開啟自己的互動視窗。

formatKeys 會將綁定渲染為顯示格式。formatKeys("ctrl+shift+p") 在 macOS 上回傳 ⌃⇧P,在其他平台回傳 ctrl+shift+P,而 <Kbd> 會以相同格式渲染單一按鍵。

useKeymap、<KeyHelp>、<KeyHints>、<StatusBar> 和 <CommandPalette> 隨 Text.js 1.0 提供。參考文件請見鍵盤。