summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/components/terminal.tsx
diff options
context:
space:
mode:
authorDaniel Polito <[email protected]>2026-01-16 13:51:02 -0300
committerGitHub <[email protected]>2026-01-16 10:51:02 -0600
commit88fd6a294b3ad88d50cb8e1853589ee4e68dc74e (patch)
tree1b187dab4b86528430498edc3ec3d3d4a243ea5f /packages/app/src/components/terminal.tsx
parentea8ef37d50408203d2ef7ebbdb82bbd15bbf8461 (diff)
downloadopencode-88fd6a294b3ad88d50cb8e1853589ee4e68dc74e.tar.gz
opencode-88fd6a294b3ad88d50cb8e1853589ee4e68dc74e.zip
feat(desktop): Terminal Splits (#8767)
Diffstat (limited to 'packages/app/src/components/terminal.tsx')
-rw-r--r--packages/app/src/components/terminal.tsx21
1 files changed, 18 insertions, 3 deletions
diff --git a/packages/app/src/components/terminal.tsx b/packages/app/src/components/terminal.tsx
index 8001e2caa..a37a540f1 100644
--- a/packages/app/src/components/terminal.tsx
+++ b/packages/app/src/components/terminal.tsx
@@ -7,9 +7,11 @@ import { resolveThemeVariant, useTheme, withAlpha, type HexColor } from "@openco
export interface TerminalProps extends ComponentProps<"div"> {
pty: LocalPTY
+ focused?: boolean
onSubmit?: () => void
onCleanup?: (pty: LocalPTY) => void
onConnectError?: (error: unknown) => void
+ onExit?: () => void
}
type TerminalColors = {
@@ -38,7 +40,7 @@ export const Terminal = (props: TerminalProps) => {
const sdk = useSDK()
const theme = useTheme()
let container!: HTMLDivElement
- const [local, others] = splitProps(props, ["pty", "class", "classList", "onConnectError"])
+ const [local, others] = splitProps(props, ["pty", "focused", "class", "classList", "onConnectError"])
let ws: WebSocket | undefined
let term: Term | undefined
let ghostty: Ghostty
@@ -49,6 +51,7 @@ export const Terminal = (props: TerminalProps) => {
let handleTextareaBlur: () => void
let reconnect: number | undefined
let disposed = false
+ let cleaning = false
const getTerminalColors = (): TerminalColors => {
const mode = theme.mode()
@@ -88,6 +91,11 @@ export const Terminal = (props: TerminalProps) => {
t.focus()
setTimeout(() => t.textarea?.focus(), 0)
}
+
+ createEffect(() => {
+ if (local.focused) focusTerminal()
+ })
+
const handlePointerDown = () => {
const activeElement = document.activeElement
if (activeElement instanceof HTMLElement && activeElement !== container) {
@@ -166,6 +174,11 @@ export const Terminal = (props: TerminalProps) => {
return true
}
+ // allow cmd+d and cmd+shift+d for terminal splitting
+ if (event.metaKey && key === "d") {
+ return true
+ }
+
return false
})
@@ -231,7 +244,6 @@ export const Terminal = (props: TerminalProps) => {
// console.log("Scroll position:", ydisp)
// })
socket.addEventListener("open", () => {
- console.log("WebSocket connected")
sdk.client.pty
.update({
ptyID: local.pty.id,
@@ -250,7 +262,9 @@ export const Terminal = (props: TerminalProps) => {
props.onConnectError?.(error)
})
socket.addEventListener("close", () => {
- console.log("WebSocket disconnected")
+ if (!cleaning) {
+ props.onExit?.()
+ }
})
})
@@ -274,6 +288,7 @@ export const Terminal = (props: TerminalProps) => {
})
}
+ cleaning = true
ws?.close()
t?.dispose()
})