Existe-t-il un moyen intéressant de gérer les entrées multilignes avec GNU readline?

StackOverflow https://stackoverflow.com/questions/161495

  •  03-07-2019
  •  | 
  •  

Question

Mon application possède une interface de ligne de commande et je pense utiliser La bibliothèque GNU Readline fournit l’historique, une ligne de commande modifiable, etc.

Le problème, c’est que mes commandes peuvent être assez longues et complexes (pensez à SQL) et je voudrais permettre aux utilisateurs de répartir les commandes sur plusieurs lignes pour les rendre plus lisibles dans l’historique.

Est-il possible de faire cela dans readline (peut-être en spécifiant une différence entre une nouvelle ligne et une fin de commande)?

Ou mieux me servirais-je de ma propre ligne de commande (mais en utilisant le Bibliothèque GNU History )?

Était-ce utile?

La solution

Vous pouvez le faire.

Vous pouvez définir des options pour les valeurs '\ r' et '\ n' avec

rl_bind_key('\r', return_func);

Votre return_func peut maintenant décider quoi faire avec ces clés.

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

Si vous effectuez cette opération dans un terminal UNIX, vous devrez vous familiariser avec les codes de terminal ANSI si vous souhaitez déplacer votre curseur. Il existe une référence de départ sur wikipedia.

Voici un exemple de code qui utilise readline pour lire plusieurs lignes et qui cesse d’être modifié lorsque vous entrez des points-virgules (je l’ai défini comme EOQ ou end-or-query). Readline est extrêmement puissant, il y a beaucoup de choses à apprendre.

#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);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top