Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 61 additions & 1 deletion apps/web/src/components/ComposerPromptEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,19 @@ const SURROUND_SYMBOLS: [string, string][] = [
];
const SURROUND_SYMBOLS_MAP = new Map<string, string>(SURROUND_SYMBOLS);
const BACKTICK_SURROUND_CLOSE_SYMBOL = SURROUND_SYMBOLS_MAP.get("`") ?? null;
const DEAD_KEY_GRAVE_LOOKALIKE_CHARACTERS = new Set(["\u02cb", "\u2035", "\uff40"]);
const RECENT_DEAD_KEY_MAX_AGE_MS = 1_000;

function hasCommandModifier(event: KeyboardEvent): boolean {
return event.metaKey || event.ctrlKey;
}

function hasRecentDeadKeyDown(recentDeadKeyDown: { timestamp: number } | null): boolean {
return (
recentDeadKeyDown !== null &&
performance.now() - recentDeadKeyDown.timestamp <= RECENT_DEAD_KEY_MAX_AGE_MS
);
}

type SerializedComposerMentionNode = Spread<
{
Expand Down Expand Up @@ -1134,6 +1147,7 @@ function ComposerSurroundSelectionPlugin(props: {
expandedStart: number;
expandedEnd: number;
} | null>(null);
const recentDeadKeyDownRef = useRef<{ timestamp: number } | null>(null);

useEffect(() => {
terminalContextsRef.current = props.terminalContexts;
Expand Down Expand Up @@ -1205,14 +1219,30 @@ function ComposerSurroundSelectionPlugin(props: {

useEffect(() => {
const onKeyDown = (event: KeyboardEvent) => {
const isPlainDeadKeyDown =
event.key === "Dead" &&
!event.defaultPrevented &&
!event.isComposing &&
!hasCommandModifier(event);
const isPlainSpaceKeyDown =
(event.key === " " || event.code === "Space") &&
!event.defaultPrevented &&
!event.isComposing &&
!hasCommandModifier(event);
if (isPlainDeadKeyDown) {
recentDeadKeyDownRef.current = { timestamp: performance.now() };
} else if (!isPlainSpaceKeyDown) {
recentDeadKeyDownRef.current = null;
}

if (pendingDeadKeySelectionRef.current) {
if (event.key === "Dead" || event.key === " " || event.code === "Space") {
return;
}
pendingDeadKeySelectionRef.current = null;
}

if (event.defaultPrevented || event.isComposing || event.metaKey || event.ctrlKey) {
if (event.defaultPrevented || event.isComposing || hasCommandModifier(event)) {
pendingSurroundSelectionRef.current = null;
pendingDeadKeySelectionRef.current = null;
return;
Expand Down Expand Up @@ -1259,6 +1289,7 @@ function ComposerSurroundSelectionPlugin(props: {
BACKTICK_SURROUND_CLOSE_SYMBOL !== null &&
pendingSurroundSelectionRef.current
) {
recentDeadKeyDownRef.current = null;
pendingDeadKeySelectionRef.current = pendingSurroundSelectionRef.current;
return;
}
Expand All @@ -1267,23 +1298,52 @@ function ComposerSurroundSelectionPlugin(props: {
return;
}

if (
event.inputType === "insertCompositionText" &&
typeof event.data === "string" &&
DEAD_KEY_GRAVE_LOOKALIKE_CHARACTERS.has(event.data) &&
hasRecentDeadKeyDown(recentDeadKeyDownRef.current)
) {
recentDeadKeyDownRef.current = null;
if (!applySurroundInsertion("`")) {
editor.update(() => {
const selection = $getSelection();
if ($isRangeSelection(selection)) {
selection.insertText("`");
}
pendingSurroundSelectionRef.current = null;
});
}
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
return;
}

if (event.inputType === "insertCompositionText") {
if (typeof event.data === "string" && event.data.length > 0) {
recentDeadKeyDownRef.current = null;
}
return;
}

if (typeof event.data !== "string") {
recentDeadKeyDownRef.current = null;
pendingSurroundSelectionRef.current = null;
return;
}
const inputData = event.inputType === "insertText" ? event.data : null;
if (!inputData || inputData.length !== 1) {
recentDeadKeyDownRef.current = null;
pendingSurroundSelectionRef.current = null;
return;
}
if (!applySurroundInsertion(inputData)) {
recentDeadKeyDownRef.current = null;
return;
}

recentDeadKeyDownRef.current = null;
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
Expand Down
Loading