Есть ли хороший способ обработки многострочного ввода с помощью GNU readline? - PullRequest
18 голосов
/ 02 октября 2008

Мое приложение имеет интерфейс командной строки, и я думаю об использовании библиотеки GNU Readline для предоставления истории, редактируемой командной строки и т. Д.

Проблема в том, что мои команды могут быть довольно длинными и сложными (например, SQL), и я хотел бы позволить пользователям распределять команды по нескольким строкам, чтобы сделать их более читабельными в истории.

Возможно ли сделать это в readline (возможно, указав разницу между новой строкой и концом команды)?

Или мне лучше реализовать собственную командную строку (но, возможно, использовать GNU History library )?

1 Ответ

18 голосов
/ 02 октября 2008

Вы уверены, что можете.

Вы можете определить параметры для значений '\ r' и '\ n' с помощью

rl_bind_key('\r', return_func);

Ваш return_func теперь может решать, что делать с этими ключами.

int return_func(int cnt, int key) { ... }

Если вы делаете это внутри терминала UNIX, вам нужно будет узнать о кодах терминала ANSI, если вы хотите переместить курсор. В википедии есть начальная ссылка .

Вот пример кода, который использует readline для чтения многострочного текста и прекратит редактирование, когда вы введете точку с запятой (я установил это как EOQ или end-or-query). Readline чрезвычайно эффективен, есть много вещей, которые нужно изучить.

#include <stdio.h>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>

int my_startup(void);
int my_bind_cr(int, int);
int my_bind_eoq(int, int);
char *my_readline(void);

int my_eoq; 

int
main(int argc, char *argv[])
{

  if (isatty(STDIN_FILENO)) {
    rl_readline_name = "my";
    rl_startup_hook = my_startup;
    my_readline();
  }
}

int
my_startup(void) 
{
  my_eoq = 0;
  rl_bind_key('\n', my_bind_cr);
  rl_bind_key('\r', my_bind_cr);
  rl_bind_key(';', my_bind_eoq);
}

int
my_bind_cr(int count, int key) {
  if (my_eoq == 1) {
    rl_done = 1;
  }
  printf("\n");
}

int
my_bind_eoq(int count, int key) {
  my_eoq = 1;

  printf(";");
}

char * 
my_readline(void)
{
  char *line;

  if ((line = readline("")) == NULL) {
    return NULL;
  }

  printf("LINE : %s\n", line);
}
...