Есть ли способ очистить текст, переносимый по строкам, в приглашении GNU Readline?Linux

Ответить
Anonymous
 Есть ли способ очистить текст, переносимый по строкам, в приглашении GNU Readline?

Сообщение Anonymous »

Я пишу простое приложение REPL на C. Одной из необходимых функций была подсветка синтаксиса, поэтому я написал свою собственную функцию rl_redisplay, которая позволяет мне выделять тест с помощью escape-символов ANSI.

Код: Выделить всё

void redisplay(void) {
fputs("\033[2K\r", stdout);

char *hl = highlight_line(rl_line_buffer);
const char *line = hl ? hl : rl_line_buffer;

fputs(rl_display_prompt, stdout);
fputs(line, stdout);

fflush(stdout);
if (hl) free(hl);
}
Этот код перемещает курсор в начало строки и очищает его до конца экрана. Но когда я использую клавиши со стрелками для просмотра истории, иногда встречаются команды, которые переносят строки из-за размера терминала, в этих случаях эта функция очищает только последнюю строку, поэтому терминал теперь имеет дополнительные строки вверху. Я попытался подсчитать, сколько строк мне нужно пройти вверх и очистить, узнав размер экрана:

Код: Выделить всё

void redisplay(void) {
int rows, cols;
rl_get_screen_size(&rows, &cols);

// Calculate how many lines the current display uses
int prompt_len = strlen(rl_display_prompt);
int total_len = prompt_len + rl_end;
int lines_used = (total_len / cols) + 1;

// Move to the start of the first line and clear everything
for (int i = 1; i < lines_used; i++) {
printf("\033[A");  // Move up
}
printf("\r\033[J");  // Move to start and clear down

// Draw prompt and highlighted content
char *hl = highlight_line(rl_line_buffer);
const char *line = hl ? hl : rl_line_buffer;

fputs(rl_display_prompt, stdout);
fputs(line, stdout);

// Calculate where cursor should be
int cursor_pos = prompt_len + rl_point;
int cursor_row = cursor_pos / cols;
int cursor_col = cursor_pos % cols;

// Calculate where we are now (end of everything we just printed)
int current_pos = prompt_len + rl_end);
int current_row = current_pos / cols;
int current_col = current_pos % cols;

// Move cursor to correct position
int row_diff = current_row - cursor_row;
if (row_diff > 0) {
printf("\033[%dA", row_diff);  // Move up
}

// Move to correct column
printf("\r");  // Start of line
if (cursor_col > 0) {
printf("\033[%dC", cursor_col);  // Move right
}

fflush(stdout);
if (hl) free(hl);
}
Этот метод случайным образом (9 раз из 10) удаляет строку над ней, поэтому текст в терминале удаляется.
Есть ли способ переместить курсор в начало приглашения независимо от того, сколько строк обернуто текстом, чтобы я мог просто вывести \033[2k\r, чтобы удалить текст и перерисовать его?>

Подробнее здесь: https://stackoverflow.com/questions/797 ... ine-prompt
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»