Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.

Commit d9299ae

Browse files
committed
fix: in minisplits, blocks that contain pty output may have excess whitespace
This PR adds a way for streaming controllers to request that the view remove all prior output. Previously, the pty/client controller was calling xtermContainer.remove() directly, i.e. it was manipulating the DOM directly. Nope!! Fixes #6759
1 parent 9ec3996 commit d9299ae

File tree

5 files changed

+23
-6
lines changed

5 files changed

+23
-6
lines changed

plugins/plugin-bash-like/src/pty/client.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,10 @@ async function initOnMessage(
612612
// note: this is still an open issue for things like `git log` or `less` where
613613
// the xterm stays alive in race with scrolling
614614
window.requestAnimationFrame(() => {
615-
xtermContainer.remove()
615+
// this tells the view to clear any prior output
616+
// !! DO NOT CALL xtermContainer.remove() directly !!
617+
execOptions.stdout(null)
618+
616619
// respond to the REPL
617620
respondToRepl({
618621
apiVersion: 'kui-shell/v1',
@@ -883,7 +886,9 @@ export const doExec = (
883886
(execOptions.type === ExecType.Nested && execOptions.quiet !== false) ||
884887
resizer.wasEverInAltBufferMode()
885888
) {
886-
xtermContainer.remove()
889+
// this tells the view to clear any prior output
890+
// !! DO NOT CALL xtermContainer.remove() directly !!
891+
execOptions.stdout(null)
887892
} else {
888893
xtermContainer.classList.add('xterm-terminated')
889894
}

plugins/plugin-client-common/src/components/Content/Scalar/HTMLDom.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,17 @@ export default class HTMLDom extends React.PureComponent<Props> {
4949
}
5050

5151
public render() {
52-
return (
52+
return !this.props.content ? (
53+
<React.Fragment />
54+
) : (
5355
<div
5456
className={
5557
'padding-content scrollable scrollable-auto page-content' +
5658
(this.props.className ? ` ${this.props.className}` : '')
5759
}
5860
style={{ display: 'flex', flex: 1 }}
5961
>
60-
<div style={{ display: 'flex', flex: 1 }} ref={dom => this.setState({ dom })} />
62+
<div className="kui--ignore-if-empty" ref={dom => this.setState({ dom })} />
6163
</div>
6264
)
6365
}

plugins/plugin-client-common/src/components/Content/Scalar/XtermDom.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ export default class XtermDom extends React.PureComponent<Props> {
4747
}
4848

4949
public render() {
50-
return (
50+
return this.props.response.rows.length === 0 ? (
51+
<React.Fragment />
52+
) : (
5153
<div className="padding-content scrollable scrollable-auto page-content" style={{ display: 'flex', flex: 1 }}>
5254
<div style={{ display: 'flex', flex: 1 }}>
5355
<div className="xterm-container xterm-terminated">

plugins/plugin-client-common/src/components/Views/Terminal/Block/Output.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,9 @@ export default class Output extends React.PureComponent<Props, State> {
115115
// eslint-disable-next-line @typescript-eslint/no-unused-vars
116116
private async streamingConsumer(part: Streamable) {
117117
if (hasUUID(this.props.model)) {
118+
// part === null: the controller wants to clear any prior output
118119
this.setState(curState => ({
119-
streamingOutput: curState.streamingOutput.concat([part])
120+
streamingOutput: part === null ? [] : curState.streamingOutput.concat([part])
120121
}))
121122
this.props.onRender()
122123
eventChannelUnsafe.emit(`/command/stdout/done/${this.props.uuid}/${this.props.model.execUUID}`)

plugins/plugin-client-common/web/css/static/ui.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ body.still-loading .repl {
127127
}
128128

129129
/* generic */
130+
.kui--ignore-if-empty {
131+
display: flex;
132+
flex: 1;
133+
&:empty {
134+
display: none;
135+
}
136+
}
130137
.kui--hero-text {
131138
flex: 1;
132139
display: flex;

0 commit comments

Comments
 (0)