Friday, October 17, 2008

Most useless use of ZSH

I found neat ZSH hack:


1 function most_useless_use_of_zsh {
2 local lines columns colour a b p q i pnew
3 ((columns=COLUMNS-1, lines=LINES-1, colour=0))
4 for ((b=-1.5; b<=1.5; b+=3.0/lines)) do
5 for ((a=-2.0; a<=1; a+=3.0/columns)) do
6 for ((p=0.0, q=0.0, i=0; p*p+q*q < 4 && i < 32; i++)) do
7 ((pnew=p*p-q*q+a, q=2*p*q+b, p=pnew))
8 done
9 ((colour=(i/4)%8))
10 echo -n "\\e[4${colour}m "
11 done
12 echo
13 done
14 }
What do you think this function does?

It draws Mandelbrot fractal :D This is possible because of ZSH floats support.



read more!

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/


read more!

Wednesday, January 30, 2008

Zsh unique features

My favorite shell is The Z Shell. It has many features that can't be found in Bash, for example hash tables:


#!/bin/zsh
typeset -A myArray
myArray[someKey]=firstValue
myArray[otherKey]=secondValue
echo $myArray[someKey] , $myArray[otherKey]

Using hash tables is very easy in Zsh. In Bash you can only emulate hashes.

Another unique Zsh feature is zparseopts. Look at following example:

#!/bin/zsh

zmodload zparseopts
zparseopts -D -E -A Args -- a b -aopt -bopt

if (( ${+Args[-a]} )); then
echo "option -a given";
fi
if (( ${+Args[-b]} )); then
echo "option -b given";
fi
if (( ${+Args[--aopt]} )); then
echo "long option --aopt given";
fi
if (( ${+Args[--bopt]} )); then
echo "long option --bopt given";
fi
if [ "$#@" -gt 0 ]; then
echo Non option arguments are: "$@"
fi

Example outputs of this script:

# ./parseex -a -b
option -a given
option -b given

# ./parseex -a x y --bopt
option -a given
long option --bopt given
Non option arguments are: x y

# ./parseex -a x y --bopt -a
option -a given
long option --bopt given
Non option arguments are: x y

# ./parseex -ab x y --bopt z --aopt z
option -a given
option -b given
long option --aopt given
long option --bopt given
Non option arguments are: x y z z

Notice how extremely easy it is to parse command line options given in not straightforward form! Zparseopts will parse "-ab" as "-a -b" and "-a text -b text2" as "-a -b text text2"! Scripts written using zparseopts behave like normal console applications, because advanced command line options allow comfortable script invocation.


read more!