introduce opentui keymap as sole key/cmd engine (#26053)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/solid"
|
||||
import { useRenderer, useTerminalDimensions } from "@opentui/solid"
|
||||
import { batch, createContext, Show, useContext, type JSX, type ParentProps } from "solid-js"
|
||||
import { useTheme } from "@tui/context/theme"
|
||||
import { MouseButton, Renderable, RGBA } from "@opentui/core"
|
||||
@@ -6,6 +6,7 @@ import { createStore } from "solid-js/store"
|
||||
import { useToast } from "./toast"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import * as Selection from "@tui/util/selection"
|
||||
import { useBindings } from "../keymap"
|
||||
|
||||
export function Dialog(
|
||||
props: ParentProps<{
|
||||
@@ -47,7 +48,7 @@ export function Dialog(
|
||||
backgroundColor={RGBA.fromInts(0, 0, 0, 150)}
|
||||
>
|
||||
<box
|
||||
onMouseUp={(e) => {
|
||||
onMouseUp={(e: { stopPropagation(): void }) => {
|
||||
dismiss = false
|
||||
e.stopPropagation()
|
||||
}}
|
||||
@@ -73,23 +74,6 @@ function init() {
|
||||
|
||||
const renderer = useRenderer()
|
||||
|
||||
useKeyboard((evt) => {
|
||||
if (store.stack.length === 0) return
|
||||
if (evt.defaultPrevented) return
|
||||
if ((evt.name === "escape" || (evt.ctrl && evt.name === "c")) && renderer.getSelection()?.getSelectedText()) return
|
||||
if (evt.name === "escape" || (evt.ctrl && evt.name === "c")) {
|
||||
if (renderer.getSelection()) {
|
||||
renderer.clearSelection()
|
||||
}
|
||||
const current = store.stack.at(-1)!
|
||||
current.onClose?.()
|
||||
setStore("stack", store.stack.slice(0, -1))
|
||||
evt.preventDefault()
|
||||
evt.stopPropagation()
|
||||
refocus()
|
||||
}
|
||||
})
|
||||
|
||||
let focus: Renderable | null
|
||||
function refocus() {
|
||||
setTimeout(() => {
|
||||
@@ -108,6 +92,36 @@ function init() {
|
||||
}, 1)
|
||||
}
|
||||
|
||||
useBindings(() => ({
|
||||
enabled: store.stack.length > 0 && !renderer.getSelection()?.getSelectedText(),
|
||||
bindings: [
|
||||
{
|
||||
key: "escape",
|
||||
cmd: () => {
|
||||
if (renderer.getSelection()) {
|
||||
renderer.clearSelection()
|
||||
}
|
||||
const current = store.stack.at(-1)
|
||||
current?.onClose?.()
|
||||
setStore("stack", store.stack.slice(0, -1))
|
||||
refocus()
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "ctrl+c",
|
||||
cmd: () => {
|
||||
if (renderer.getSelection()) {
|
||||
renderer.clearSelection()
|
||||
}
|
||||
const current = store.stack.at(-1)
|
||||
current?.onClose?.()
|
||||
setStore("stack", store.stack.slice(0, -1))
|
||||
refocus()
|
||||
},
|
||||
},
|
||||
],
|
||||
}))
|
||||
|
||||
return {
|
||||
clear() {
|
||||
for (const item of store.stack) {
|
||||
@@ -155,13 +169,14 @@ export function DialogProvider(props: ParentProps) {
|
||||
const value = init()
|
||||
const renderer = useRenderer()
|
||||
const toast = useToast()
|
||||
|
||||
return (
|
||||
<ctx.Provider value={value}>
|
||||
{props.children}
|
||||
<box
|
||||
position="absolute"
|
||||
zIndex={3000}
|
||||
onMouseDown={(evt) => {
|
||||
onMouseDown={(evt: { button: number; preventDefault(): void; stopPropagation(): void }) => {
|
||||
if (!Flag.OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT) return
|
||||
if (evt.button !== MouseButton.RIGHT) return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user