Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
111 lines
2.8 KiB
TypeScript
111 lines
2.8 KiB
TypeScript
import type { KeyboardEvent as ReactKeyboardEvent, RefObject } from "react";
|
|
import type { Editor } from "@tiptap/core";
|
|
import { isAgentRichTextImeComposing } from "./agentRichTextIme";
|
|
import { moveSelectionOverCaretAnchor } from "./agentRichTextEditorSupport";
|
|
|
|
export function handleAgentRichTextKeyDownCapture(
|
|
event: ReactKeyboardEvent<HTMLDivElement>,
|
|
input: {
|
|
disabled: boolean;
|
|
editorRef: RefObject<Editor | null>;
|
|
onKeyDownForPaletteRef: RefObject<
|
|
((event: KeyboardEvent) => boolean) | undefined
|
|
>;
|
|
onHistoryNavigationRef: RefObject<
|
|
((direction: "older" | "newer") => boolean) | undefined
|
|
>;
|
|
onSubmitGuidanceRef: RefObject<(() => void) | undefined>;
|
|
onSubmitRef: RefObject<() => void>;
|
|
submitOnEnter: boolean;
|
|
}
|
|
): void {
|
|
if (isAgentRichTextImeComposing(event.nativeEvent)) {
|
|
return;
|
|
}
|
|
if (input.disabled) {
|
|
return;
|
|
}
|
|
if (input.onKeyDownForPaletteRef.current?.(event.nativeEvent)) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
return;
|
|
}
|
|
if (
|
|
(event.key === "ArrowUp" || event.key === "ArrowDown") &&
|
|
!event.shiftKey &&
|
|
!event.metaKey &&
|
|
!event.ctrlKey &&
|
|
!event.altKey
|
|
) {
|
|
const currentEditor = input.editorRef.current;
|
|
const selection = currentEditor?.state.selection;
|
|
const documentSize = currentEditor?.state.doc.content.size ?? 0;
|
|
const isAtDocumentBoundary =
|
|
Boolean(selection?.empty) &&
|
|
(selection?.from === 1 || selection?.to === documentSize - 1);
|
|
if (
|
|
currentEditor &&
|
|
!currentEditor.isDestroyed &&
|
|
isAtDocumentBoundary &&
|
|
input.onHistoryNavigationRef.current?.(
|
|
event.key === "ArrowUp" ? "older" : "newer"
|
|
)
|
|
) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
return;
|
|
}
|
|
}
|
|
if (
|
|
(event.key === "ArrowLeft" || event.key === "ArrowRight") &&
|
|
!event.shiftKey &&
|
|
!event.metaKey &&
|
|
!event.ctrlKey &&
|
|
!event.altKey
|
|
) {
|
|
const currentEditor = input.editorRef.current;
|
|
if (
|
|
currentEditor &&
|
|
!currentEditor.isDestroyed &&
|
|
moveSelectionOverCaretAnchor(
|
|
currentEditor.state,
|
|
(transaction) => currentEditor.view.dispatch(transaction),
|
|
event.key
|
|
)
|
|
) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
return;
|
|
}
|
|
}
|
|
if (
|
|
event.key === "Enter" &&
|
|
(event.metaKey || event.ctrlKey) &&
|
|
!event.shiftKey &&
|
|
!event.altKey
|
|
) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
if (!input.submitOnEnter) {
|
|
return;
|
|
}
|
|
input.onSubmitGuidanceRef.current?.();
|
|
return;
|
|
}
|
|
if (
|
|
event.key !== "Enter" ||
|
|
event.shiftKey ||
|
|
event.metaKey ||
|
|
event.ctrlKey ||
|
|
event.altKey
|
|
) {
|
|
return;
|
|
}
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
if (!input.submitOnEnter) {
|
|
return;
|
|
}
|
|
input.onSubmitRef.current();
|
|
}
|