pull/8156/merge
Evan Sosenko 2026-04-08 05:04:24 +00:00 committed by GitHub
commit 5f2b1a46da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 7 deletions

View File

@ -52,6 +52,7 @@ export const { use: useKeybind, provider: KeybindProvider } = createSimpleContex
useKeyboard(async (evt) => {
if (!store.leader && result.match("leader", evt)) {
evt.preventDefault()
leader(true)
return
}
@ -74,10 +75,6 @@ export const { use: useKeybind, provider: KeybindProvider } = createSimpleContex
return store.leader
},
parse(evt: ParsedKey): Keybind.Info {
// Handle special case for Ctrl+Underscore (represented as \x1F)
if (evt.name === "\x1F") {
return Keybind.fromParsedKey({ ...evt, name: "_", ctrl: true }, store.leader)
}
return Keybind.fromParsedKey(evt, store.leader)
},
match(key: string, evt: ParsedKey) {

View File

@ -21,15 +21,22 @@ export namespace Keybind {
* Convert OpenTUI's ParsedKey to our Keybind.Info format.
* This helper ensures all required fields are present and avoids manual object creation.
*/
export function fromParsedKey(key: ParsedKey, leader = false): Info {
return {
name: key.name === " " ? "space" : key.name,
export function fromParsedKey(
key: Pick<ParsedKey, "name" | "ctrl" | "meta" | "shift" | "super">,
leader = false,
): Info {
const info = {
name: key.name,
ctrl: key.ctrl,
meta: key.meta,
shift: key.shift,
super: key.super ?? false,
leader,
}
if (key.name === "\x00") return { ...info, name: "space", ctrl: true }
if (key.name === "\x1F") return { ...info, name: "_", ctrl: true }
if (key.name === " ") return { ...info, name: "space" }
return info
}
export function toString(info: Info | undefined): string {

View File

@ -1,4 +1,5 @@
import { describe, test, expect } from "bun:test"
import type { ParsedKey } from "@opentui/core"
import { Keybind } from "../src/util/keybind"
describe("Keybind.toString", () => {
@ -54,6 +55,17 @@ describe("Keybind.toString", () => {
expect(Keybind.toString(info)).toBe("pgup")
})
test("should convert space key to string", () => {
const info: Keybind.Info = {
ctrl: false,
meta: false,
shift: false,
leader: false,
name: "space",
}
expect(Keybind.toString(info)).toBe("space")
})
test("should handle empty name", () => {
const info: Keybind.Info = { ctrl: true, meta: false, shift: false, leader: false, name: "" }
expect(Keybind.toString(info)).toBe("ctrl")
@ -175,6 +187,44 @@ describe("Keybind.match", () => {
})
})
describe("Keybind.fromParsedKey", () => {
test("should parse ' ' as space", () => {
const result = Keybind.fromParsedKey({ name: " ", ctrl: false, meta: false, shift: false, super: false })
expect(result).toEqual({
ctrl: false,
meta: false,
shift: false,
super: false,
leader: false,
name: "space",
})
})
test("should parse \x1F as ctrl+_", () => {
const result = Keybind.fromParsedKey({ name: "\x1F", ctrl: false, meta: false, shift: false, super: false })
expect(result).toEqual({
ctrl: true,
meta: false,
shift: false,
super: false,
leader: false,
name: "_",
})
})
test("should parse \x00 as ctrl+space", () => {
const result = Keybind.fromParsedKey({ name: "\x00", ctrl: false, meta: false, shift: false, super: false })
expect(result).toEqual({
ctrl: true,
meta: false,
shift: false,
super: false,
leader: false,
name: "space",
})
})
})
describe("Keybind.parse", () => {
test("should parse simple key", () => {
const result = Keybind.parse("f")