Readline interface

From Rosetta Code
Readline interface is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Build a simple application with a readline interface.

The interface should provide

  • a history
  • commandline editing
  • application specific commands

The application could be based on Simple database or something else.

If the language already provides a readline interface, then it should be demonstrated how build an application specific readline interface (one that only understands the applications commands) and also show how to customize the builtin readline to provide the above features and especially add application specific commands.

C

A program that does absolutely nothing. Type 'help' for help. <lang c>#include <readline/readline.h>

  1. include <readline/history.h>
  2. include <string.h>

int main() { char *s; using_history(); while (1) { s = readline("This be a prompt> ");

if (!s || !strcmp(s, "quit")) { puts("bye."); return 0; }

if (!strcmp(s, "help")) puts("commands: ls, cat, quit"); else if (!strcmp(s, "ls") || !strcmp(s, "cat")) { printf("command `%s' not implemented yet.\n", s); add_history(s); } else puts("Yes...?"); } }</lang>

Pike

watch.pike is the solution from Simple database#Pike. this solution demonstrates how to retrofit an application with a readline interface by inheriting the original and overriding specific functions.

<lang pike>#!/usr/bin/pike

inherit "watch.pike";

Stdio.Readline readln = Stdio.Readline();

void print_help() {

   write("The following commands are available: \n");
   write(sort(indices(functions))*", ");
   write("\n");

}

void watch_add() {

   ::watch_add(db);

}

void watch_list() {

   ::watch_list(db);

}

void do_exit() {

   exit(0);

}

mapping functions = ([ "add":watch_add,

                      "list":watch_list,
                      "load":watch_load,
                      "save":watch_save,
                      "help":print_help,
                      "quit":do_exit ]);

string prompt_read(string prompt) {

   return readln->read(prompt+": ");

}

void main() {

 Stdio.Readline.History readline_history = Stdio.Readline.History(512);
 readln->enable_history(readline_history);
 string prompt="> ";


 print_help();
 while(1)
 {
   string input=readln->read(prompt);
   if(!input)
     exit(0);
   if(input != "")
   {
      if (functions[input])
          functions[input]();
      else
      {
          write("unknown command\n");
          print_help();
      }
   }
 }

}</lang>

Sample session:

pike watch_rl.pike
The following commands are available:
add, help, list, load, quit, save
> load
> list
  Rosetta Code                            2 Simple Database                (27.10.2011.)
> add
Series: Rdm asks!
Title: Balanced ternary
Episode: 1
Date watched: 1.11.2011
Add new series? [y/n]: : y
> list
  Rdm asks!                               1 Balanced ternary               (1.11.2011.)
  Rosetta Code                            2 Simple Database                (27.10.2011.)
> hello
unknown command
The following commands are available: 
add, help, list, load, quit, save
> save
> quit