当我通过 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 使用 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;
}