diff --git a/lib/Getopt/Lucid.pm b/lib/Getopt/Lucid.pm index 1904f7d..592e786 100644 --- a/lib/Getopt/Lucid.pm +++ b/lib/Getopt/Lucid.pm @@ -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 { @@ -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; @@ -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; @@ -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; }; @@ -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. + +For example, + + @spec = ( + Param("output")->doc("write output to the specified file") + ->placeholder("file"), + ); + +results in + + --output write output to the specified file + +rather than the default of + + --output write output to the specified file + == Validation Validation happens in two stages. First, individual parameters may have diff --git a/t/11-usage.t b/t/11-usage.t index 2725229..a6ee59c 100644 --- a/t/11-usage.t +++ b/t/11-usage.t @@ -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/), @@ -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 \s*$/, + qr/^\s+--define key=\s+\(default: arch=i386, isize=4\)$/, + qr/^\s+--input \s+\(default: test\.txt\)$/, + qr/^\s+--libs \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 \[\], --verbose \[\]\s+turn on verbose output \(default: 2\)$/, ); plan tests => 2 + @expectations;