我如何保存和还原” XTERM.JS实例的上下文?

发布于 2025-01-26 19:37:47 字数 1813 浏览 1 评论 0 原文

在我的电子应用程序中,我有一个 xterm.js 在我的一个终端模拟器中 react tabs 。我如何保留该终端的状态,以便在使用文本并返回文本时,仍然存在光标位置等?反应中通常的方法是使用状态变量,将其设置在父组件中并将其传递给渲染器上的孩子,但是由于Xterm.js并不是React组件本身,到现在为止,我还不知道该怎么做。

目前,我创建了这样的终端:

import { useEffect, useRef, useState } from "react";
import { Terminal as TerminalType } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
//import { SearchAddon } from 'xterm-addon-search'
import 'xterm/css/xterm.css';

export const Terminal = () => {

  const [terminal] = useState(new TerminalType({
                              cursorBlink: true,
                              cursorStyle: window.api.isWindows ? "bar" : "underline"
                      }));
  useEffect(() => {
    const fitAddon = new FitAddon();
    terminal.loadAddon(fitAddon);
    
    window.api.receive('terminal.incomingData', (data) => {
      terminal.write(data);
    });
    
    terminal.open(document.getElementById('xterm-container') as HTMLElement);
    terminal.onData((key) => {
      window.api.send('terminal.keystroke', key);
    });
    fitAddon.fit();
    // simulate enter press to show the initial prompt command
    window.api.send('terminal.keystroke', '\r');
  }, [terminal]);

  return (
    <div id="xterm-container"></div>
  )
}

更新1: forcerender = {true} 确实有效地制作选项卡:

<TabPanel key="3" forceRender={true}>
  <Terminal />
</TabPanel>

但是,它不仅在需要时一直保持渲染效果,即行动。欢迎更好地解决此问题的方法。 另外,我发现一个问题 fitaddon.fit()在设置 forcerender = {true} 时不起作用。

In my electron application, I have an xterm.js terminal emulator, in one of my react tabs. How do I preserve the state of this terminal so that when the use go out and back the text, cursor position etc still is there? the usual approach in react is just use state variables, set it in the parent component and pass it down to the child on renderer but since xterm.js isn't a react component itself, by now I have no idea how to do that.

currently I create the terminal like this:

import { useEffect, useRef, useState } from "react";
import { Terminal as TerminalType } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
//import { SearchAddon } from 'xterm-addon-search'
import 'xterm/css/xterm.css';

export const Terminal = () => {

  const [terminal] = useState(new TerminalType({
                              cursorBlink: true,
                              cursorStyle: window.api.isWindows ? "bar" : "underline"
                      }));
  useEffect(() => {
    const fitAddon = new FitAddon();
    terminal.loadAddon(fitAddon);
    
    window.api.receive('terminal.incomingData', (data) => {
      terminal.write(data);
    });
    
    terminal.open(document.getElementById('xterm-container') as HTMLElement);
    terminal.onData((key) => {
      window.api.send('terminal.keystroke', key);
    });
    fitAddon.fit();
    // simulate enter press to show the initial prompt command
    window.api.send('terminal.keystroke', '\r');
  }, [terminal]);

  return (
    <div id="xterm-container"></div>
  )
}

UPDATE 1:
Making the tab with forceRender={true} does work:

<TabPanel key="3" forceRender={true}>
  <Terminal />
</TabPanel>

But it keeps the rendering mounted all the time, not only when it's needed, i.e., the tab is actived. Better ways to solve this is welcome.
Also, I found an issue fitAddon.fit() doesn't work when forceRender={true} is set.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

他不在意 2025-02-02 19:37:48

您可以使用xterm addon 保存您的终端缓冲区或其中一部分。它将被序列化为您可以传递的字符串,以恢复状态。

You can use the xterm addon @xterm/addon-serialize to save your terminal buffer, or part of it. It will be serialized to a string you can pass to write() to restore the state.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文