为什么我的shell输入框在使用转义序列获取终端大小时会自动显示一部分输出结果?

问题描述 投票:0回答:1

当我通过 ssh 使用 VS Code 作为 shell 控制台时,输入框会出现以下代码:

my@my:~$ echo -e "\033[18t"

my@my:~$ ;23;140t

但是当我使用Termius等其他终端应用程序通过ssh连接同一台机器时,输入框是清晰的:

my@my:~$ echo -e "\033[18t"

my@my:~$ 

如何才能让输入框变得清晰?

其实我正在移植一个shell到我的项目中,我的项目不支持

ioctl()
或其他方法,我发现这个方法可以获取终端大小,但它会使输入框变脏。

我尝试在 echo

\b
之后手动输入
\033[18t
到我的 shell 以清除它,但它仍然存在。

shell visual-studio-code ansi-escape
1个回答
0
投票

我的 shell 使用 linenoise,这个错误应该通过手动调用刷新线来解决。 这个功能是

static void refreshSingleLine(struct linenoiseState *l, int flags) {
    char seq[64];
    size_t plen = strlen(l->prompt);
    int fd = l->ofd;
    char *buf = l->buf;
    size_t len = l->len;
    size_t pos = l->pos;
    struct abuf ab;

    while((plen+pos) >= l->cols) {
        buf++;
        len--;
        pos--;
    }
    while (plen+len > l->cols) {
        len--;
    }

    abInit(&ab);
    /* Cursor to left edge */
    snprintf(seq,sizeof(seq),"\r");
    abAppend(&ab,seq,strlen(seq));

    if (flags & REFRESH_WRITE) {
        /* Write the prompt and the current buffer content */
        abAppend(&ab,l->prompt,strlen(l->prompt));
        if (maskmode == 1) {
            while (len--) abAppend(&ab,"*",1);
        } else {
            abAppend(&ab,buf,len);
        }
        /* Show hits if any. */
        refreshShowHints(&ab,l,plen);
    }

    /* Erase to right */
    snprintf(seq,sizeof(seq),"\x1b[0K");
    abAppend(&ab,seq,strlen(seq));

    if (flags & REFRESH_WRITE) {
        /* Move cursor to original position. */
        snprintf(seq,sizeof(seq),"\r\x1b[%dC", (int)(pos+plen));
        abAppend(&ab,seq,strlen(seq));
    }

    if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */
    abFree(&ab);
}

我在 linenoiseEditStart 函数的末尾调用这个刷新函数,这就是我使用转义的地方

\033[18t

int linenoiseEditStart(struct linenoiseState *l, int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt) {
    /* Populate the linenoise state that we pass to functions implementing
     * specific editing functionalities. */
    l->in_completion = 0;
    l->ifd = stdin_fd != -1 ? stdin_fd : STDIN_FILENO;
    l->ofd = stdout_fd != -1 ? stdout_fd : STDOUT_FILENO;
    l->buf = buf;
    l->buflen = buflen;
    l->prompt = prompt;
    l->plen = strlen(prompt);
    l->oldpos = l->pos = 0;
    l->len = 0;

    /* Enter raw mode. */
    if (enableRawMode(l->ifd) == -1) return -1;

    l->cols = getColumns(stdin_fd, stdout_fd);
    l->oldrows = 0;
    l->history_index = 0;

    /* Buffer starts empty. */
    l->buf[0] = '\0';
    l->buflen--; /* Make sure there is always space for the nulterm */

    /* If stdin is not a tty, stop here with the initialization. We
     * will actually just read a line from standard input in blocking
     * mode later, in linenoiseEditFeed(). */
    if (!isatty(l->ifd)) return 0;

    /* The latest history entry is always our current buffer, that
     * initially is just an empty string. */
    linenoiseHistoryAdd("");

    if (write(l->ofd,prompt,l->plen) == -1) return -1;

    refreshLine(l); // I add this call
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.