Shell usability

Hi all,

I´d like to extend the usability of JNode's shell and also write some new commands. For this I have some suggestions for new APIs and API changes.
Please comment on it. Say what you think about it, if you have other/new ideas or whatever...

Currently the Command Interface has one method that looks like this:

public void execute(CommandLine commandLine, InputStream in, PrintStream out, PrintStream err) throws Exception;

----------

The CommandLine is something like a Parser that provides tokens. I´d like to replace this by a class CommandArgs that looks like this:

public CommandArgs(String commandName, String[] args);

public boolean isOptionSet(char flag, String longVersion);

This method returns, whether a commandline option is set. You can test whether a option is set. True is returned, if flag or its longVersion is set. For example, "command -afd --import file -hj" would give you true for 'a','f','d','h','j' and "import". That means the position for flags doesn't matter, you can also "group" flags and every option can have a short and long version (e.g. '-i' == '--import').

public CommandToken[] getParameters(String prefix);

This gives you parameters that are added to the command like this: "command -Dparam1 -Dparam2". The Prefixes are developer-configurable.

public CommandToken[] getOptions(String prefix);

This gives you (key, value) pairs for a prefix. "command -Dkey1=value1 -Dkey2=value2 -Kkey1=value2" would give you (key1,value2) for "-K" and so on.

public boolean hasNext()
public CommandToken next()

these methods refer to the remaining arguments not being flags, options or parameters (but files or something like that).

public String[] getArgs();
public String getCommandName();

return the normal command and arguments as they were typed by the user.

And there will be a method to set the Syntax used. In my examples "-" for flags, "--" for long optionflags, "-D" and "-K" for parameters and (key,value) pairs.

----------

I would like to wrap "InputStream in, PrintStream out, PrintStream err" in a new class CommandEnvironment. The CommandEnvironment then has getters for the Streams and some new method, I'm not yet quite sure about, but something like this:

String getProperty(String key);

to get system properties. I want to have such a method instead of using system classes, so we are able to overwrite single properties or to add properties to a specific Command by the shell.

String getMessage(String key);

This would be a method for i18n, and commands get their messages from this method. The key then must also reflect the command, e.g. "org.jnode.shell.command.Cat.helpMessage". I don't know, if it is really a good idea, but this way we could have a "systemwide" i18n mechanism.
I think of this: It is checked, whether the key is present in the user locale. If it´s not present it is looked for some default locale, if still not found, the prefix "org.jnode.shell.command.Cat" would give you a hint, where to find the resource files, and you still do not have one huge resource file for all messages regarding any app running on jnode. And another point: If still nothing was found you could give back "-'key' not found-" instead of throwing an exception, so that even an user could add the i18n-message (now knowing the key).

----------

Then I would like to have a new abstract class

abstract class CommandAdapter implements Command, KeyboardListener, PointerListener, FocusListener {

    keyPressed(KeyEvent e) {}

    // ... other empty methods

}

If the shell encounters a CommandAdapter instead of only a Command, it auto-registers the Listeners to the Console. This would solve a common and complicated task for Commands. Until now, every Command has to get the Console with much more effort, where you have to register your listeners.

Further I would like to have a PropertyChangeListener machanism to console, and CommandAdapter in order to get events like "consolesize changed", which will be the case if we go to graphical consoles or have some commands that can change the nativ screensize.

----------

The shell itself lacks some features that are very useful and known from bash, that I would like to implement:

"Ctrl+R" + regexp reverse searches the history for regexp.
start + "pgup" reverse search the history for a command starting with start.
a better TAB-compleation and a TAB-TAB-multiproposial mode like in bash.
and some more...

----------

So, please comment on this or make additions or tell me what you like and what you don't like. If you agree to my proposals, I would also adopt all the commands to the new Command interface or CommandAdapter as needed.

Peter

Commons-CLI

Hi Peter,
have you tried to use the Commons-CLI package from Jakarta-Commons ?

Maybe this can help to standardize the elaboration of commands and related parameters. Or some features could be already present there.

Bye,
Sandro

Hi Sandro, thanks for that

Hi Sandro,

thanks for that hint. I didn't know Commons-CLI, only had a look at Java GetOpts (http://www.urbanophile.com/arenn/hacking/download.html) which is not comfortable to use in my eyes.
The Commons-CLI API looks really pretty, I would immediatly use it Smiling

But since I didn't get much positiv feedback to my original post, I'm currently not working on the shell Sad

Peter

There are good points....

I think thre is still place for improvemnts on the shell.
But not sure if we really need the CommandAdapter with all those listeners implemented. Few commands will want to listen directly to the mouse and keyboard events I guess.

I think what you want to achieve with the CommandEnvironment can be adressed best with isolates where each command would start a new isolate (except the built-in shell commands) with its own system properties and in, out, and error streams etc.

I agree with some command history and command completion improvements
and fixes to the current sytax classes which are buggy, (see the older version of the route command in the cvs history and its -gw option) but I don't think we have to reproduce every single intricacy of the unix style command line parsing where sometimes I find commands with tens and tens of options somewhat exagerated.

Levente