App-Spec

 view release on metacpan or  search on metacpan

lib/App/Spec/Completion/Bash.pm  view on Meta::CPAN

    my $body = <<"EOM";
#!/usr/bin/env bash

# Generated with perl module App::Spec v$appspec_version

_$appname() \{

    COMPREPLY=()
    local program=$appname
    local cur prev words cword
    _init_completion -n : || return
    declare -a FLAGS
    declare -a OPTIONS
    declare -a MYWORDS

    local INDEX=`expr \$cword - 1`
    MYWORDS=("\$\{words[@]:1:\$cword\}")

    FLAGS=($flags_string)
    OPTIONS=($options_string)
    __${appname}_handle_options_flags

$completion_outer
\}

_${appname}_compreply() \{
    local prefix=""
    cur="\$(printf '%q' "\$cur")"
    IFS=\$'\\n' COMPREPLY=(\$(compgen -P "\$prefix" -W "\$*" -- "\$cur"))
    __ltrim_colon_completions "\$prefix\$cur"

    # http://stackoverflow.com/questions/7267185/bash-autocompletion-add-description-for-possible-completions
    if [[ \$\{#COMPREPLY[*]\} -eq 1 ]]; then # Only one completion
        COMPREPLY=( "\$\{COMPREPLY[0]%% -- *\}" ) # Remove ' -- ' and everything after
        COMPREPLY=( "\$\{COMPREPLY[0]%%+( )\}" ) # Remove trailing spaces
    fi
\}

@{[ join '', @$functions ]}
EOM
    my $static_functions = $self->_functions;

    $body .= <<"EOM";
$static_functions
complete -o default -F _$appname $appname
EOM

    return $body;
}

sub flags_options {
    my ($self, $options) = @_;
    my @flags;
    my @opt;
    for my $o (@$options) {
        my $name = $o->name;
        my $aliases = $o->aliases;
        my $summary = $o->summary;
        $summary =~ s/\s+/ /g if defined $summary;
        my @names = ($name, @$aliases);
        ($summary, @names) = $self->escape_singlequote( $summary, @names );
        @names = map {
            length $_ > 1 ? "--$_" : "-$_"
        } @names;

        my @items = map {
            ("'$_'", "'$summary'")
        } @names;

        if ($o->type eq 'flag') {
            push @flags, @items;
        }
        else {
            push @opt, @items;
        }
    }
    return ("@flags", "@opt");
}

sub escape_singlequote {
    my ($self, @strings) = @_;
    my @result;
    for my $string (@strings) {
        no warnings 'uninitialized';
        $string =~ s/[']/'"\\\\'"'/g;
        push @result, $string;
    }
    return wantarray ? @result : $result[0];
}

sub completion_commands {
    my ($self, %args) = @_;
    my $spec = $self->spec;
    my $appname = $spec->name;
    my $functions = $args{functions};
    my $previous = $args{previous} || [];
    my $commands = $args{commands};
    my $options = $args{options};
    my $parameters = $args{parameters};
    my $level = $args{level};
    my $indent = "    " x $level;

    my @commands = map {
        my $name = $_;
        my $summary = $commands->{ $_ }->summary;
        for ($name, $summary) {
            no warnings 'uninitialized';
            s/\s+/ /g;
            s/['`]/'"'"'/g;
            s/\$/\\\$/g;
        }
        "'$name'" . (length $summary ? q{$'\t'} . "'$summary'" : '')
    } sort grep { not m/^_/ } keys %$commands;
    my $cmds = join q{$'\\n'}, @commands;

    my $index = $level - 1;
    my $subc = '';
    if (keys %$commands) {
        $subc = <<"EOM";
$indent# subcmds
${indent}case \$\{MYWORDS\[$index\]\} in
EOM
    }

    for my $name (sort keys %$commands) {
        my $cmd_spec = $commands->{ $name };
        my ($flags_string, $options_string) = $self->flags_options($cmd_spec->options);
        $subc .= <<"EOM";
${indent}  $name)
EOM
        $subc .= $indent . "    FLAGS+=($flags_string)\n" if $flags_string;
        $subc .= $indent . "    OPTIONS+=($options_string)\n" if $options_string;
        $subc .= <<"EOM";
${indent}    __${appname}_handle_options_flags
EOM
        my $subcommands = $cmd_spec->subcommands;
        my $parameters = $cmd_spec->parameters;
        my $cmd_options = $cmd_spec->options;
        if (keys %$subcommands or @$cmd_options or @$parameters) {
            my $comp = $self->completion_commands(

lib/App/Spec/Completion/Bash.pm  view on Meta::CPAN

      do
          local name="${FLAGS[$j]}"
          local desc="${FLAGS[$j+1]}"
          options_spec+="$name"$'\t'"$desc"$'\n'
      done

      for ((j=0; j<${#OPTIONS[@]}; j+=2))
      do
          local name="${OPTIONS[$j]}"
          local desc="${OPTIONS[$j+1]}"
          options_spec+="$name"$'\t'"$desc"$'\n'
      done
      __APPNAME_dynamic_comp 'options' "$options_spec"

      return 1
    else
      return 0
    fi
}

EOM
    my $appname = $self->spec->name;
    $string =~ s/APPNAME/$appname/g;
    return $string;
}

1;

__DATA__

=pod

=head1 NAME

App::Spec::Completion::Bash - Shell Completion generator for bash

See also L<App::Spec::Completion> and L<App::Spec::Completion::Zsh>

=head1 SYNOPSIS

my $completer = App::Spec::Completion::Bash->new( spec => $appspec );

=head1 METHODS

=over 4

=item generate_completion

    my $completion = $completer->generate_completion;

=item completion_commands

=item completion_options

=item completion_parameter

=item completion_parameters

=item dynamic_completion

=item escape_singlequote

    (@names) = $self->escape_singlequote( @names );

=item flags_options

    my ($flags_string, $options_string) = $completer->flags_options($global_options);

=back

=cut



( run in 3.066 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )