Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add indication that an option takes a value to the help message #15

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 36 additions & 6 deletions lib/Getopt/Lucid.pm
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ my $VALID_NAME = qr/$VALID_LONG|$VALID_SHORT|$VALID_BARE/;
my $SHORT_BUNDLE = qr/-[$VALID_STARTCHAR]{2,}/;
my $NEGATIVE = qr/(?:--)?no-/;

my @valid_keys = qw( name type default nocase valid needs canon doc );
my @valid_keys = qw( name type default nocase valid needs canon doc placeholder );
my @valid_types = qw( switch counter parameter list keypair);

sub Switch {
Expand Down Expand Up @@ -96,6 +96,8 @@ sub needs { my $self = shift; $self->{needs}=[@_]; return $self };

sub doc { my $self = shift; $self->{doc}=shift; return $self };

sub placeholder { my $self = shift; $self->{placeholder}=shift; return $self };

sub _clone { my $self = shift; bless { %$self }, ref $self }

package Getopt::Lucid;
Expand Down Expand Up @@ -385,22 +387,22 @@ sub usage {
for my $opt ( sort { $a->{strip} cmp $b->{strip} } values %{$self->{spec}} ) {
my $names = [ @{ $opt->{names} } ];
push @doc, [
_build_usage_left_column( $names, \@short_opts ),
_build_usage_left_column( $names, \@short_opts, $opt->{type}, $opt->{placeholder} ),
_build_usage_right_column( $opt->{doc}, $opt->{default}, $opt->{type} ),
];
}

my $max_width = 3 + List::Util::max( map { length } @doc );
my $max_width = 3 + List::Util::max( map { length($_->[0]) } @doc );

my $prog = File::Basename::basename($0);

local $" = '';
my $usage = "Usage: $prog [-@short_opts] [long options] [arguments]\n"
. join( "", map { sprintf( "\t%-${max_width}s %s\n", @$_ ) } @doc );
. join( "", map { sprintf( " %-${max_width}s %s\n", @$_ ) } @doc );
}

sub _build_usage_left_column {
my ($names, $all_short_opts) = @_;
my ($names, $all_short_opts, $type, $placeholder ) = @_;
my @sorted_names =
sort { length $a <=> length $b } map { my $s = $_; $s =~ s/^-*//; $s } @$names;

Expand All @@ -409,13 +411,21 @@ sub _build_usage_left_column {

push @$all_short_opts, @short_opts;

$placeholder = 'value' if ! defined $placeholder;
my $value =
$type eq 'keypair' ? " key=<$placeholder>"
: $type eq 'counter' ? " [<$placeholder>]"
: $type ne 'switch' ? " <$placeholder>"
: ''
;

my $group = sub {
my $list = shift;
'-' . ( @$list == 1 ? $list->[0] : '[' . join( '|', @$list ) . ']' );
};
my $prepare = sub {
my $list = shift;
return ( length $list->[0] > 1 ? '-' : '' ) . $group->($list) if @$list;
return ( length $list->[0] > 1 ? '-' : '' ) . $group->($list) . $value if @$list;
return;
};

Expand Down Expand Up @@ -1107,6 +1117,26 @@ Sets the documentation string for an option.

This string shows up in the "usage" method.

=== placeholder()

Sets the string used for the value placeholder in the usage for an option.
If not specified, defaults to C<value>.

For example,

@spec = (
Param("output")->doc("write output to the specified file")
->placeholder("file"),
);

results in

--output <file> write output to the specified file

rather than the default of

--output <value> write output to the specified file

== Validation

Validation happens in two stages. First, individual parameters may have
Expand Down
12 changes: 6 additions & 6 deletions t/11-usage.t
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ my $prog = basename($0);
my $spec = [
Counter("--verbose|v")->doc("turn on verbose output")->default(2),
Switch("--test")->doc("run in test mode"),
Param("--input")->default("test.txt"),
Param("--input")->default("test.txt")->placeholder('file'),
Switch("-r")->doc("recursive"),
Param("bare"),
List("libs")->default(qw/one two/),
Expand All @@ -28,13 +28,13 @@ my $spec = [

my @expectations = (
qr/^Usage: \Q$prog\E \[-rv] \[long options] \[arguments]$/,
qr/^\s+--bare\s*$/,
qr/^\s+--define\s+\(default: arch=i386, isize=4\)$/,
qr/^\s+--input\s+\(default: test\.txt\)$/,
qr/^\s+--libs\s+\(default: one, two\)$/,
qr/^\s+--bare <value>\s*$/,
qr/^\s+--define key=<value>\s+\(default: arch=i386, isize=4\)$/,
qr/^\s+--input <file>\s+\(default: test\.txt\)$/,
qr/^\s+--libs <value> \s+\(default: one, two\)$/,
qr/^\s+-r\s+recursive$/,
qr/^\s+--test\s+run in test mode$/,
qr/^\s+-v, --verbose\s+turn on verbose output \(default: 2\)$/,
qr/^\s+-v \[<value>\], --verbose \[<value>\]\s+turn on verbose output \(default: 2\)$/,
);

plan tests => 2 + @expectations;
Expand Down