new object $has_commands: $root;
var $root inited = 1;
var $has_commands shortcuts = #[];
var $has_commands commands = #[];
public method .init_has_commands() {
var i;
shortcuts = [];
commands = [];
for i in (this().parents()) {
(| shortcuts += i.shortcuts().to_list() |);
(| commands += i.commands().to_list() |);
}
shortcuts = shortcuts.to_dict();
commands = commands.to_dict();
};
public method .shortcuts() {
return shortcuts || #[];
};
public method .commands() {
return commands || #[];
};
public method .match_command() {
arg line;
var word;
// This method will return a list of length three.
// 1. command as matched (may be a shortcut character)
// 2. associated symbol (which is probably a method name)
// 3. the rest of the line, (minus command)
// First try to match the shortcuts (quick)
catch ~keynf {
return [.shortcuts()[line[1]], line[1], substr(line, 2)];
}
// Now try to match an actual command
catch ~keynf {
word = (| substr(line, 1, stridx(line, " ", 1)-1) |) || line;
return [.commands()[word], word, (| substr(line, word.length() + 2) |) || ""];
}
// No match
return 0;
};
public method .parse_line() {
arg line;
var cmd, ret;
if ((cmd = .match_command(line))) {
catch any {
ret = .(cmd[1])(line, cmd[2], cmd[3]);
} with {
switch (error()) {
case ~numargs:
return "Wrong number of arguments.";
default:
rethrow(error());
}
}
return ret;
} else {
return "No such command.";
}
};