使用GNU readline处理多行输入有一种很好的方法吗?

时间:2022-07-25 00:15:14

My application has a command line interface, and I'm thinking about using the GNU Readline library to provide history, an editable command line, etc.

我的应用程序有一个命令行界面,我正在考虑使用GNU Readline库来提供历史记录,可编辑的命令行等。

The hitch is that my commands can be quite long and complex (think SQL) and I'd like to allow users to spread commands over multiple lines to make them more readable in the history.

问题是,我的命令可能很长而且很复杂(想想SQL),我想让用户在多行上传播命令,使它们在历史记录中更具可读性。

Is it possible to do this in readline (maybe by specifying a difference between a newline and an end of command)?

是否可以在readline中执行此操作(可能通过指定换行符和命令结尾之间的差异)?

Or would I be better off implementing my own command line (but maybe using the GNU History library)?

或者我会更好地实现自己的命令行(但可能使用GNU历史库)?

1 个解决方案

#1


16  

You sure can.

你确定可以。

You can define options for the '\r' and '\n' values with

您可以使用定义'\ r'和'\ n'值的选项

rl_bind_key('\r', return_func);

Your return_func can now decide what to do with those keys.

您的return_func现在可以决定如何处理这些键。

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

If you're doing this inside a UNIX terminal, you will need to learn about ANSI terminal codes if you want to move your cursor around. There's a starting reference on wikipedia.

如果您在UNIX终端中执行此操作,则需要了解ANSI终端代码(如果要移动光标)。*上有一个开始参考。

Here's some sample code that uses readline to read multi-line and will stop editing when you enter in a semi-colon (I've set that as the EOQ or end-or-query). Readline is extremely powerful, there's plenty of stuff to learn.

下面是一些使用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);
}

#1


16  

You sure can.

你确定可以。

You can define options for the '\r' and '\n' values with

您可以使用定义'\ r'和'\ n'值的选项

rl_bind_key('\r', return_func);

Your return_func can now decide what to do with those keys.

您的return_func现在可以决定如何处理这些键。

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

If you're doing this inside a UNIX terminal, you will need to learn about ANSI terminal codes if you want to move your cursor around. There's a starting reference on wikipedia.

如果您在UNIX终端中执行此操作,则需要了解ANSI终端代码(如果要移动光标)。*上有一个开始参考。

Here's some sample code that uses readline to read multi-line and will stop editing when you enter in a semi-colon (I've set that as the EOQ or end-or-query). Readline is extremely powerful, there's plenty of stuff to learn.

下面是一些使用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);
}