Monday, March 10, 2008

Comfortable command line in Java

Readline is well known GNU library that provides comfortable command line in text environment. It can be very easily used with C and C++, but many problems arise when trying to use it with Java. Readline is binary, platform dependant library. Using it with Java needs lots of hacking to preserve some platform independence and is problematic when targeting Windows platform. Readline is also licensed under GPL and any program linking with it must have compliant license. Recently I was developing command line application which had to run under Linux and Windows as well. I was trying to use java-readline, but it didn’t support Windows. I then found other library, which is written in pure Java: JLine.

JLine is small, flexible Java library for handling console input. Feature highlights include:
  • command line editing (you can use arrows to move over entered text, etc.),
  • history of entered commands,
  • completion (also filenames!).

Below you can see example demonstrating JLine flexibility, simplicity and power.
import jline.*;
import java.io.*;
import java.util.*;

public class Cmdline {
public static void main(String[] args) throws IOException {
ConsoleReader reader = new ConsoleReader();
reader.setBellEnabled(false);

List argCompletor1= new LinkedList();
argCompletor1.add(new SimpleCompletor(new String[] { "ls", "mkdir" }));
argCompletor1.add(new FileNameCompletor());
List argCompletor2 = new LinkedList();
argCompletor2.add(new SimpleCompletor(new String[] {"ps"}));
argCompletor2.add(new SimpleCompletor(new String[] {"-ax",
"-axu","--help"}));

List completors = new LinkedList();
completors.add(new ArgumentCompletor(argCompletor1));
completors.add(new ArgumentCompletor(argCompletor2));

reader.addCompletor(new MultiCompletor(completors));

String line;
PrintWriter out = new PrintWriter(System.out);
while ((line = reader.readLine("READY # ")) != null) {
out.println("::" + line );
out.flush();
if (line.equalsIgnoreCase("quit") ||
line.equalsIgnoreCase("q"))
break;
}
}
}
Basically each line in below ends with TAB key pressed, which causes JLine to generate proper completion.
# java -cp jline-0.9.93.jar:. Cmdline
READY #

ls mkdir ps
READY # ls /

_darcs bin boot dev etc fonts
home lib lost+found media mnt opt
proc root sbin sys tmp usr
var
READY # ls /mnt/c

camera cdrom cdromaes
READY # ps -

--help -ax -axu
READY # ps -ax

-ax -axu
READY # mkdir

Cmdline.class Cmdline.java jline-0.9.93.jar
READY # mkdir /

_darcs bin boot dev etc fonts
home lib lost+found media mnt opt
proc root sbin sys tmp usr
var
More information:
  • http://java-readline.sourceforge.net/
  • http://jline.sourceforge.net/

1 comment:

Daniel Spiewak said...

Impressive. One step closer to ncurses for Java...