Skip to content

Commit 24ff60a

Browse files
authored
Revert "fix: unsynced line buffer on backspace or on keyboard type (#645)" (#666)
This reverts commit 934b853.
1 parent 934b853 commit 24ff60a

File tree

3 files changed

+13
-49
lines changed

3 files changed

+13
-49
lines changed

api/internal/features/terminal/init.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ func (t *Terminal) readOutput(r io.Reader) {
161161
return
162162
}
163163

164+
func() {
165+
t.wsLock.Lock()
166+
defer t.wsLock.Unlock()
167+
t.outputBuf = append(t.outputBuf, buf[:n]...)
168+
}()
169+
164170
msg := TerminalMessage{
165171
TerminalId: t.TerminalId,
166172
Type: "stdout",

view/app/terminal/terminal.tsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,15 @@ const TerminalSession: React.FC<{
6363
useEffect(() => {
6464
if (isTerminalOpen && isActive && isContainerReady) {
6565
initializeTerminal();
66-
} else {
67-
// Cleanup: destroy terminal when it's closed or becomes inactive
68-
destroyTerminal();
6966
}
70-
}, [isTerminalOpen, isActive, isContainerReady, initializeTerminal, destroyTerminal]);
67+
}, [isTerminalOpen, isActive, isContainerReady, initializeTerminal]);
7168

7269
useEffect(() => {
7370
if (fitAddonRef) {
7471
setFitAddonRef(fitAddonRef);
7572
}
7673
}, [fitAddonRef, setFitAddonRef]);
7774

78-
// Cleanup on unmount
79-
useEffect(() => {
80-
return () => {
81-
destroyTerminal();
82-
};
83-
}, [destroyTerminal]);
84-
8575
return (
8676
<div
8777
ref={terminalRef}

view/app/terminal/utils/useTerminal.ts

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,16 @@ export const useTerminal = (
3131
const { sendJsonMessage, message, isReady } = useWebSocket();
3232
const [terminalInstance, setTerminalInstance] = useState<any | null>(null);
3333
const resizeTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
34-
const terminalInstanceRef = useRef<any | null>(null);
3534

3635
const destroyTerminal = useCallback(() => {
37-
const instance = terminalInstanceRef.current;
38-
if (instance) {
39-
instance.dispose();
40-
terminalInstanceRef.current = null;
36+
if (terminalInstance) {
37+
terminalInstance.dispose();
4138
setTerminalInstance(null);
4239
}
43-
// Clear the terminal container to remove any stale input
44-
if (terminalRef.current) {
45-
terminalRef.current.innerHTML = '';
46-
}
4740
if (resizeTimeoutRef.current) {
4841
clearTimeout(resizeTimeoutRef.current);
4942
}
50-
}, []);
43+
}, [terminalInstance, terminalId]);
5144

5245
useEffect(() => {
5346
if (isStopped && terminalInstance) {
@@ -77,8 +70,6 @@ export const useTerminal = (
7770
if (parsedMessage.type === OutputType.EXIT) {
7871
destroyTerminal();
7972
} else if (parsedMessage.data) {
80-
// Write output from backend - this includes echoed input
81-
// Using write ensures proper synchronization with terminal state
8273
terminalInstance.write(parsedMessage.data);
8374
}
8475
}
@@ -87,19 +78,6 @@ export const useTerminal = (
8778
}
8879
}, [message, terminalInstance, destroyTerminal, terminalId]);
8980

90-
// Cleanup effect: destroy terminal when isTerminalOpen becomes false or component unmounts
91-
useEffect(() => {
92-
if (!isTerminalOpen && terminalInstanceRef.current) {
93-
destroyTerminal();
94-
}
95-
return () => {
96-
// Cleanup on unmount
97-
if (terminalInstanceRef.current) {
98-
destroyTerminal();
99-
}
100-
};
101-
}, [isTerminalOpen, destroyTerminal]);
102-
10381
const initializeTerminal = useCallback(async () => {
10482
if (!terminalRef.current || terminalInstance || !isReady) return;
10583

@@ -180,35 +158,26 @@ export const useTerminal = (
180158
if (allowInput) {
181159
term.attachCustomKeyEventHandler((event: KeyboardEvent) => {
182160
const key = event.key.toLowerCase();
183-
184-
// Handle Ctrl+J or Cmd+J (toggle terminal shortcut)
185161
if (key === 'j' && (event.ctrlKey || event.metaKey)) {
186162
return false;
187-
}
188-
189-
// Handle Ctrl+C or Cmd+C for copy (when there's a selection)
190-
if (key === 'c' && (event.ctrlKey || event.metaKey) && !event.shiftKey) {
163+
} else if (key === 'c' && (event.ctrlKey || event.metaKey) && !event.shiftKey) {
191164
if (event.type === 'keydown') {
192165
try {
193166
const selection = term.getSelection();
194167
if (selection) {
195168
navigator.clipboard.writeText(selection).then(() => {
196-
term.clearSelection();
169+
term.clearSelection(); // Clear selection after successful copy
197170
});
198171
return false;
199172
}
200173
} catch (error) {
201174
console.error('Error in Ctrl+C handler:', error);
202175
}
203176
}
177+
return false;
204178
}
205-
206-
// Allow xterm to process all other keys normally
207179
return true;
208180
});
209-
210-
// onData is called when xterm processes input
211-
// Send all input to backend - backend echo will handle display
212181
term.onData((data) => {
213182
sendJsonMessage({
214183
action: 'terminal',
@@ -229,7 +198,6 @@ export const useTerminal = (
229198
});
230199
}
231200

232-
terminalInstanceRef.current = term;
233201
setTerminalInstance(term);
234202
} catch (error) {
235203
console.error('Error initializing terminal:', error);

0 commit comments

Comments
 (0)