mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-01 01:51:44 +00:00
fix(tui): restore clipboard hotkeys in clarify mode
This commit is contained in:
parent
8c9fdedaf5
commit
c3af012a35
4 changed files with 109 additions and 4 deletions
|
|
@ -5,6 +5,7 @@ import type { Theme } from '../theme.js'
|
|||
import type { ApprovalReq, ClarifyReq, ConfirmReq } from '../types.js'
|
||||
|
||||
import { TextInput } from './textInput.js'
|
||||
import { isMac } from '../lib/platform.js'
|
||||
|
||||
const OPTS = ['once', 'session', 'always', 'deny'] as const
|
||||
const LABELS = { always: 'Always allow', deny: 'Deny', once: 'Allow once', session: 'Allow this session' } as const
|
||||
|
|
@ -125,10 +126,12 @@ export function ClarifyPrompt({ cols = 80, onAnswer, onCancel, req, t }: Clarify
|
|||
|
||||
<Box>
|
||||
<Text color={t.color.label}>{'> '}</Text>
|
||||
<TextInput columns={Math.max(20, cols - 6)} onChange={setCustom} onSubmit={onAnswer} value={custom} />
|
||||
<TextInput columns={Math.max(20, cols - 6)} allowClipboardHotkeys={isMac} onChange={setCustom} onSubmit={onAnswer} value={custom} />
|
||||
</Box>
|
||||
|
||||
<Text color={t.color.dim}>Enter send · Esc {choices.length ? 'back' : 'cancel'} · Ctrl+C cancel</Text>
|
||||
<Text color={t.color.dim}>
|
||||
Enter send · Esc {choices.length ? 'back' : 'cancel'} · {isMac ? 'Cmd+C copy · Cmd+V paste · Ctrl+C cancel' : 'Ctrl+C cancel'}
|
||||
</Text>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ import * as Ink from '@hermes/ink'
|
|||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
|
||||
import { setInputSelection } from '../app/inputSelectionStore.js'
|
||||
import { readClipboardText } from '../lib/clipboard.js'
|
||||
import { isMac } from '../lib/platform.js'
|
||||
import { writeOsc52Clipboard } from '../lib/osc52.js'
|
||||
|
||||
type InkExt = typeof Ink & {
|
||||
stringWidth: (s: string) => number
|
||||
|
|
@ -279,6 +282,7 @@ export function TextInput({
|
|||
onChange,
|
||||
onPaste,
|
||||
onSubmit,
|
||||
allowClipboardHotkeys = false,
|
||||
mask,
|
||||
placeholder = '',
|
||||
focus = true
|
||||
|
|
@ -484,12 +488,50 @@ export function TextInput({
|
|||
|
||||
const ins = (v: string, c: number, s: string) => v.slice(0, c) + s + v.slice(c)
|
||||
|
||||
const pastePlainText = (text: string) => {
|
||||
const cleaned = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n')
|
||||
|
||||
if (!cleaned) {
|
||||
return
|
||||
}
|
||||
|
||||
const range = selRange()
|
||||
const nextValue = range
|
||||
? vRef.current.slice(0, range.start) + cleaned + vRef.current.slice(range.end)
|
||||
: vRef.current.slice(0, curRef.current) + cleaned + vRef.current.slice(curRef.current)
|
||||
const nextCursor = range ? range.start + cleaned.length : curRef.current + cleaned.length
|
||||
|
||||
commit(nextValue, nextCursor)
|
||||
}
|
||||
|
||||
useInput(
|
||||
(inp: string, k: Key, event: InputEvent) => {
|
||||
const eventRaw = event.keypress.raw
|
||||
|
||||
if (eventRaw === '\x1bv' || eventRaw === '\x1bV' || eventRaw === '\x16') {
|
||||
return void emitPaste({ cursor: curRef.current, hotkey: true, text: '', value: vRef.current })
|
||||
if (eventRaw === '\x1bv' || eventRaw === '\x1bV' || eventRaw === '\x16' || (allowClipboardHotkeys && isMac && k.meta && inp.toLowerCase() === 'v')) {
|
||||
if (cbPaste.current) {
|
||||
return void emitPaste({ cursor: curRef.current, hotkey: true, text: '', value: vRef.current })
|
||||
}
|
||||
|
||||
if (allowClipboardHotkeys) {
|
||||
const text = readClipboardText()
|
||||
|
||||
if (text) {
|
||||
return pastePlainText(text)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (allowClipboardHotkeys && isMac && k.meta && inp.toLowerCase() === 'c') {
|
||||
const range = selRange()
|
||||
|
||||
if (range) {
|
||||
writeOsc52Clipboard(vRef.current.slice(range.start, range.end))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
|
|
@ -687,6 +729,7 @@ export interface PasteEvent {
|
|||
}
|
||||
|
||||
interface TextInputProps {
|
||||
allowClipboardHotkeys?: boolean
|
||||
columns?: number
|
||||
focus?: boolean
|
||||
mask?: string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue