Tab completion improvements

A plugin can now specify &subroutine in the :Tab attribute; this sub will
be called as a method and can return a list of possible completions.
This commit is contained in:
Juerd Waalboer 2013-02-28 16:04:36 +01:00
parent a9a04db525
commit 7b088cb175
6 changed files with 81 additions and 48 deletions

View file

@ -20,7 +20,7 @@ sub command :Tab(deposit) {
return NEXT;
}
sub amount {
sub amount :Tab(13.37,42) {
my ($self, $cart, $amount) = @_;
$amount = parse_amount($amount)
@ -31,7 +31,7 @@ sub amount {
return ACCEPT;
}
sub create {
sub create :Tab(yes,no) {
my ($self, $cart, $yesno) = @_;
my $user = $self->{new_user};

View file

@ -4,7 +4,25 @@ HELP "market" => "Edit market list";
my $filename = 'revbank.market';
sub command :Tab(market) {
sub _read_market {
open my $fh, '<', $filename or die "$filename: $!";
my %market;
while (readline $fh) {
/^\s*#/ and next;
/\S/ or next;
chomp;
my ($user, $id, $seller, $space, $description) = split " ", $_, 5;
$market{$id} = {
user => $user,
seller => $seller,
space => $space,
description => $description,
};
}
return \%market;
}
sub command :Tab(market,&tab) {
my ($self, $cart, $command) = @_;
if ($command eq 'market') {
@ -12,26 +30,19 @@ sub command :Tab(market) {
return ACCEPT;
}
my @products;
my $product = _read_market->{ $command } or return NEXT;
open my $fh, '<', $filename or die $!;
/\S/ && !/^\s*#/ and push @products, [split " ", $_, 5] while readline $fh;
chomp @$_ for @products;
my $username = parse_user( $product->{ user }) or return NEXT;
my $seller = parse_amount($product->{ seller }) or return NEXT;
my $space = parse_amount($product->{ space }) or return NEXT;
my $description = $product->{description};
for my $fields (@products) {
my ($username, $id, $seller, $space, $description) = @$fields;
next if $command ne $id;
$username = parse_user($username) or next;
$seller = parse_amount($seller) or next;
$space = parse_amount($space) or next;
$cart->add(undef, -($seller + $space), $description, {product_id=>$id});
$cart->add($username, 0+$seller, "\$you bought $description")
if 0+$seller;
return ACCEPT;
}
return NEXT;
$cart->add(undef, -($seller + $space), $description,{product_id=>$command});
$cart->add($username, 0+$seller, "\$you bought $description")
if 0+$seller;
return ACCEPT;
}
sub tab {
return grep /\D/, keys %{ _read_market() };
}

View file

@ -2,7 +2,7 @@
HELP "nyan" => "Nyan!";
sub command :Tab(nyan) {
sub command :Tab(nyan,nyanutf8) {
my ($self, $cart, $command) = @_;
return NEXT if $command !~ /^(?:nyan|nyanutf8)$/;

View file

@ -22,7 +22,7 @@ sub command :Tab(pfand) {
return "Pfand zurueck fuer", \&product;
}
sub product {
sub product :Tab(&tab) {
my ($self, $cart, $product) = @_;
my $pfand = _read_pfand->{ $product };
@ -34,6 +34,10 @@ sub product {
return ACCEPT;
}
sub tab {
return keys %{ _read_pfand() };
}
sub hook_add {
my ($class, $cart, $user, $item) = @_;
return if defined $user;

View file

@ -5,7 +5,24 @@ HELP "edit" => "Edit product list";
my $filename = 'revbank.products';
sub command :Tab(edit) {
sub _read_products {
open my $fh, '<', $filename or die "$filename: $!";
my %products;
while (readline $fh) {
/^\s*#/ and next;
/\S/ or next;
chomp;
my ($ids, $p, $d) = split " ", $_, 3;
my @ids = split /,/, $ids;
$products{ $_ } = { id => $ids[0], price => $p, description => $d}
for @ids;
}
return \%products;
}
sub command :Tab(edit,&tab) {
my ($self, $cart, $command) = @_;
if ($command eq 'edit') {
@ -13,25 +30,19 @@ sub command :Tab(edit) {
return ACCEPT;
}
my @products;
my $product = _read_products->{ $command } or return NEXT;
open my $fh, '<', $filename or die $!;
/\S/ && !/^\s*#/ and push @products, [split " ", $_, 3] while readline $fh;
chomp @$_ for @products;
my $price = parse_amount( $product->{price} ) or return NEXT;
for my $fields (@products) {
my ($ids, $price, $description) = @$fields;
my @ids = split /,/, $ids;
for my $id (@ids) {
next if $id ne $command;
$price = parse_amount($price) or next;
$cart->add(undef, -$price, $description, { product_id => $ids[0] });
return ACCEPT;
}
}
return NEXT;
$cart->add(
undef,
-$price,
$product->{description},
{ product_id => $product->{id} }
);
return ACCEPT;
}
sub tab {
return grep /\D/, keys %{ _read_products() };
}

13
revbank
View file

@ -78,12 +78,19 @@ OUTER: for (;;) {
call_hooks "prompt", $cart, $prompt;
my %completions = qw(abort 1);
for (@plugins) {
for my $plugin (@plugins) {
my $attr = attributes::get(
ref $method ? $method : $_->can($method)
ref $method ? $method : $plugin->can($method)
) or next;
my ($tab) = $attr =~ /Tab \( (.*?) \)/x;
$completions{$_}++ for split /\s*,\s*/, $tab;
for my $keyword (split /\s*,\s*/, $tab) {
if ($keyword =~ /^&(.*)/) {
my $method = $1;
@completions{ $plugin->$method } = ();
} else {
$completions{ $keyword }++;
}
}
}
if (delete $completions{USERS}) {
$completions{$_}++ for RevBank::Users::names;