1

When using xterm.js in a user-resizable layout, when the xterm.js terminal shrinks, any commands that you are still typing overflow. But commands where you have pressed enter wrap properly. The text that overflows doesn't come back either and is completely removed from the DOM. I am using the xterm.js fit addon with ResizeObserver to update the terminal on resize. I am also using sveltekit, svelte split panes, and the I am using the web container api from stackblitz to run the terminal. Here is my code for the component that has the xterm.js terminal (this only includes parts related to the question):

<script lang="ts">
    import { WebContainer } from '@webcontainer/api';
    import { getContext, onDestroy, onMount } from 'svelte';
    import type { Writable } from 'svelte/store';
    import { Terminal } from 'xterm';
    import 'xterm/css/xterm.css';
    import { FitAddon } from 'xterm-addon-fit';

    onMount(async () => {
        const terminalEl = document.querySelector('.terminal') as HTMLDivElement;
        const webcontainerInstance = await WebContainer.boot();

        const fitAddon = new FitAddon();

        const terminal = new Terminal({
            convertEol: true
        });

        terminal.loadAddon(fitAddon);
        terminal.open(terminalEl);

        fitAddon.fit();

        const shellProcess = await webcontainerInstance.spawn('jsh', {
            terminal: {
                cols: terminal.cols,
                rows: terminal.rows
            }
        });
        shellProcess.output.pipeTo(
            new WritableStream({
                write(data) {
                    terminal.write(data);
                }
            })
        );

        const input = shellProcess.input.getWriter();
        terminal.onData((data) => {
            input.write(data);
        });

        const ro = new ResizeObserver(() => {
            fitAddon.fit();
        });

        ro.observe(terminalEl);

        onDestroy(() => {
            webcontainerInstance.teardown();
        });
    });
</script>

<div id="container" class="bg-slate-1000">
    <div class="terminal bg-slate-1000" />
</div>

I also have the code for the main component with the layout using svelte split panes (this only includes parts related to the question):

<script lang="ts">
    import { setContext } from 'svelte';
    import { writable } from 'svelte/store';
    import TerminalOutput from '../TerminalOutput.svelte';
    import { Pane, Splitpanes } from 'svelte-splitpanes';
</script>

<Splitpanes
    class="overflow-hidden w-screen"
    style="height: calc(100vh - 4rem);"
    theme="no-splitter"
>
    <Pane size={20}>
        
    </Pane>
    <Pane size={80} minSize={30}>
        <Splitpanes horizontal theme="nosplitter">
                <Splitpanes theme="no-splitter" horizontal>
                    <Pane size={65} minSize={30}>
                    </Pane>
                    <Pane size={35}>
                        <TerminalOutput />
                    </Pane>
                </Splitpanes>
        </Splitpanes>
    </Pane>
</Splitpanes>

Thanks for reading!

Alien 10
  • 71
  • 2
  • 8
  • Idk how your webcontainer instance maps to standard PTY logic, but normally you'd have to tell the TTY/PTY (where the shell process runs) about the resize, too. – jerch Apr 24 '23 at 13:25

0 Answers0