代码之家  ›  专栏  ›  技术社区  ›  John Carter

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

  •  18
  • John Carter  · 技术社区  · 16 年前

    GNU Readline library 提供历史记录、可编辑的命令行等。

    问题在于,我的命令可能非常长且复杂(比如SQL),我希望允许用户将命令分散到多行,以使它们在历史中更具可读性。

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

    或者我最好实现自己的命令行(但可能使用 GNU History library )?

    1 回复  |  直到 7 年前
        1
  •  18
  •   Ian Tegebo Philip Reynolds    11 年前

    你当然可以。

    可以使用定义“\r”和“\n”值的选项

    rl_bind_key('\r', return_func);
    

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

    如果您在UNIX终端中执行此操作,如果您想四处移动光标,则需要了解ANSI终端代码。有一个 starting reference 在维基百科上。

    下面是一些使用readline读取多行的示例代码,当您输入分号(我已将其设置为EOQ或end或查询)时,这些代码将停止编辑。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);
    }