Existe uma boa maneira de lidar com a entrada multi-linha com GNU readline?
-
03-07-2019 - |
Pergunta
Meu aplicativo tem uma interface de linha de comando, e eu estou pensando em usar o GNU Readline biblioteca para fornecer história, uma linha de comando editável, etc.
O engate é que meus comandos podem ser bastante longa e complexa (acho SQL) e eu gostaria de permitir que os usuários comandos distribuídos por várias linhas para torná-los mais legíveis na história.
É possível fazer isso em readline (talvez especificando uma diferença entre uma nova linha e um fim de comando)?
Ou seria melhor implementar a minha própria linha de comando (mas talvez usando o História GNU biblioteca )?
Solução
Você com certeza pode.
Você pode definir opções para o '\ r' e valores '\ n' com
rl_bind_key('\r', return_func);
Seu return_func pode agora decidir o que fazer com essas chaves.
int return_func(int cnt, int key) { ... }
Se você está fazendo isso dentro de um terminal UNIX, você precisará aprender sobre os códigos de terminal ANSI se você deseja mover o cursor ao redor. Há uma referência a partir de wikipedia.
Aqui está um código de exemplo que usa readline para ler multi-linha e vai parar de editar quando você entra em um ponto e vírgula (Eu defini que como a EOQ ou fim-ou-consulta). Readline é extremamente poderoso, há uma abundância de coisas para aprender.
#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);
}