| @@ -1,6 +1,7 @@ |
| 1 | 1 | import { FitAddon } from "@xterm/addon-fit"; |
| 2 | 2 | import { Plus, SquareSplitHorizontal, TerminalSquare, Trash2, XIcon } from "lucide-react"; |
| 3 | 3 | import { |
| 4 | + type ResolvedKeybindingsConfig, |
| 4 | 5 | type ScopedThreadRef, |
| 5 | 6 | type TerminalEvent, |
| 6 | 7 | type TerminalSessionSnapshot, |
| @@ -29,7 +30,12 @@ import { · 22 unmodified lines |
| 29 | 30 | wrappedTerminalLinkRangeIntersectsBufferLine, |
| 30 | 31 | } from "../terminal-links"; |
| 31 | 32 | import { |
| 33 | + isDiffToggleShortcut, |
| 32 | 34 | isTerminalClearShortcut, |
| 35 | + isTerminalCloseShortcut, |
| 36 | + isTerminalNewShortcut, |
| 37 | + isTerminalSplitShortcut, |
| 38 | + isTerminalToggleShortcut, |
| 33 | 39 | terminalDeleteShortcutData, |
| 34 | 40 | terminalNavigationShortcutData, |
| 35 | 41 | } from "../keybindings"; |
| @@ -255,6 +261,7 @@ interface TerminalViewportProps { · 219 unmodified lines |
| 255 | 261 | autoFocus: boolean; |
| 256 | 262 | resizeEpoch: number; |
| 257 | 263 | drawerHeight: number; |
| 264 | + keybindings: ResolvedKeybindingsConfig; |
| 258 | 265 | } |
| 259 | 266 | |
| 260 | 267 | export function TerminalViewport({ |
| @@ -271,6 +278,7 @@ export function TerminalViewport({ · 10 unmodified lines |
| 271 | 278 | autoFocus, |
| 272 | 279 | resizeEpoch, |
| 273 | 280 | drawerHeight, |
| 281 | + keybindings, |
| 274 | 282 | }: TerminalViewportProps) { |
| 275 | 283 | const containerRef = useRef<HTMLDivElement>(null); |
| 276 | 284 | const terminalRef = useRef<Terminal | null>(null); |
| @@ -282,6 +290,7 @@ export function TerminalViewport({ · 5 unmodified lines |
| 282 | 290 | const selectionActionRequestIdRef = useRef(0); |
| 283 | 291 | const selectionActionOpenRef = useRef(false); |
| 284 | 292 | const selectionActionTimerRef = useRef<number | null>(null); |
| 293 | + const keybindingsRef = useRef(keybindings); |
| 285 | 294 | const lastAppliedTerminalEventIdRef = useRef(0); |
| 286 | 295 | const terminalHydratedRef = useRef(false); |
| 287 | 296 | const handleSessionExited = useEffectEvent(() => { |
| @@ -292,6 +301,10 @@ export function TerminalViewport({ · 4 unmodified lines |
| 292 | 301 | }); |
| 293 | 302 | const readTerminalLabel = useEffectEvent(() => terminalLabel); |
| 294 | 303 | |
| 304 | + useEffect(() => { |
| 305 | + keybindingsRef.current = keybindings; |
| 306 | + }, [keybindings]); |
| 307 | + |
| 295 | 308 | useEffect(() => { |
| 296 | 309 | const mount = containerRef.current; |
| 297 | 310 | if (!mount) return; |
| @@ -403,6 +416,18 @@ export function TerminalViewport({ · 105 unmodified lines |
| 403 | 416 | }; |
| 404 | 417 | |
| 405 | 418 | terminal.attachCustomKeyEventHandler((event) => { |
| 419 | + const currentKeybindings = keybindingsRef.current; |
| 420 | + const options = { context: { terminalFocus: true, terminalOpen: true } }; |
| 421 | + if ( |
| 422 | + isTerminalToggleShortcut(event, currentKeybindings, options) || |
| 423 | + isTerminalSplitShortcut(event, currentKeybindings, options) || |
| 424 | + isTerminalNewShortcut(event, currentKeybindings, options) || |
| 425 | + isTerminalCloseShortcut(event, currentKeybindings, options) || |
| 426 | + isDiffToggleShortcut(event, currentKeybindings, options) |
| 427 | + ) { |
| 428 | + return false; |
| 429 | + } |
| 430 | + |
| 406 | 431 | const navigationData = terminalNavigationShortcutData(event); |
| 407 | 432 | if (navigationData !== null) { |
| 408 | 433 | event.preventDefault(); |
| @@ -795,6 +820,7 @@ interface ThreadTerminalDrawerProps { · 386 unmodified lines |
| 795 | 820 | onCloseTerminal: (terminalId: string) => void; |
| 796 | 821 | onHeightChange: (height: number) => void; |
| 797 | 822 | onAddTerminalContext: (selection: TerminalContextSelection) => void; |
| 823 | + keybindings: ResolvedKeybindingsConfig; |
| 798 | 824 | } |
| 799 | 825 | |
| 800 | 826 | interface TerminalActionButtonProps { |
| @@ -848,6 +874,7 @@ export default function ThreadTerminalDrawer({ · 47 unmodified lines |
| 848 | 874 | onCloseTerminal, |
| 849 | 875 | onHeightChange, |
| 850 | 876 | onAddTerminalContext, |
| 877 | + keybindings, |
| 851 | 878 | }: ThreadTerminalDrawerProps) { |
| 852 | 879 | const [drawerHeight, setDrawerHeight] = useState(() => clampDrawerHeight(height)); |
| 853 | 880 | const [resizeEpoch, setResizeEpoch] = useState(0); |
| @@ -1166,6 +1193,7 @@ export default function ThreadTerminalDrawer({ · 312 unmodified lines |
| 1166 | 1193 | autoFocus={terminalId === resolvedActiveTerminalId} |
| 1167 | 1194 | resizeEpoch={resizeEpoch} |
| 1168 | 1195 | drawerHeight={drawerHeight} |
| 1196 | + keybindings={keybindings} |
| 1169 | 1197 | /> |
| 1170 | 1198 | </div> |
| 1171 | 1199 | </div> |
| @@ -1188,6 +1216,7 @@ export default function ThreadTerminalDrawer({ · 16 unmodified lines |
| 1188 | 1216 | autoFocus |
| 1189 | 1217 | resizeEpoch={resizeEpoch} |
| 1190 | 1218 | drawerHeight={drawerHeight} |
| 1219 | + keybindings={keybindings} |
| 1191 | 1220 | /> |
| 1192 | 1221 | </div> |
| 1193 | 1222 | )} |