Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
New completion script for FFmpeg
- X-seq: zsh-workers 28008
- From: Haakon Riiser <haakon.riiser@xxxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: New completion script for FFmpeg
- Date: Tue, 8 Jun 2010 15:39:34 +0200
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
Just wrote a completion script for the audio/video encoder FFmpeg,
and thought I'd share it here in case you want to include it
with zsh.  Since FFmpeg is a moving target (most people use SVN
snapshots), the script uses perl and the ffmpeg executable to
dynamically generate the argument specification.  Hopefully,
this should make the completer more future-proof.  (It assumes
that both ffmpeg and perl is in the PATH, though.)
##############################################################################
#compdef ffmpeg
local context state line
typeset -A opt_args
local BOLD=$'\e[1m'
local NORM=$'\e[m'
_ffmpeg_compadd() {
    compadd -X "${BOLD}$1${NORM}" -q -S "$3" -a $2
}
_ffmpeg_acodecs() {
    local acodecs
    acodecs=($(ffmpeg -codecs 2>/dev/null | sed -n '/^ .[E ]A/ {s/^ .......//; s/ .*//p;}'))
    _ffmpeg_compadd 'force audio codec (''copy'' to copy stream)' acodecs ''
}
_ffmpeg_vcodecs() {
    local vcodecs
    vcodecs=($(ffmpeg -codecs 2>/dev/null | sed -n '/^ .[E ]V/ {s/^ .......//; s/ .*//p;}'))
    _ffmpeg_compadd 'force video codec (''copy'' to copy stream)' vcodecs ''
}
_ffmpeg_argspecs="$(ffmpeg -h 2>/dev/null | perl -e '
my $lastopt;
my $lastopt_description;
my $lastopt_takesargs;
my @lastopt_values;
while (<>) {
    if (/^(-\S+)\s+(\S.+)$/) {
        print_opt();
        $lastopt = $1;
        $lastopt_description = $2;
        if ($lastopt_description =~ /<\w+>/) {
            $lastopt_description =~ s/<.*?>\s+//;
            $lastopt_description =~ s/\S{5} ?//;
            $lastopt_description = $lastopt if not $lastopt_description;
            escape_str($lastopt_description);
        } elsif ($lastopt_description =~ /^(\S+)\s\s+/) {
            my $example = $1;
            $lastopt_description =~ s/^\S+\s\s+//;
            escape_str($example);
            escape_str($lastopt_description);
            if ($example eq q(filename)) {
                $lastopt_takesargs = 0;
                $lastopt .= qq(:$lastopt_description:_files);
            } elsif ($lastopt eq q(-acodec)) {
                $lastopt_takesargs = 0;
                $lastopt .= qq(:$lastopt_description:_ffmpeg_acodecs);
            } elsif ($lastopt eq q(-vcodec)) {
                $lastopt_takesargs = 0;
                $lastopt .= qq(:$lastopt_description:_ffmpeg_vcodecs);
            } else {
                $lastopt_takesargs = 1;
                $lastopt_description .= qq{ ($example)};
            }
        } else {
            $lastopt_takesargs = 0;
        }
        @lastopt_values = ();
    } elsif (/^   (\S+)/) {
        $lastopt_takesargs = 1;
        push @lastopt_values, $1;
    }
}
print_opt();
exit;
sub escape_str {
    $_[0] =~ s/:/\\:/g;
}
sub print_opt {
    return if not $lastopt;
    print qq($lastopt);
    if (!$lastopt_takesargs) {
        print qq(\n);
    } else {
        print qq(:$lastopt_description:);
        if (@lastopt_values) {
            printf qq{(%s)}, join(q( ), @lastopt_values);
        }
        print qq(\n);
    }
}
')"
_ffmpeg_argspecs=(${(f)_ffmpeg_argspecs})
_arguments -S \
    "${_ffmpeg_argspecs[@]}" \
    '*:output file:_files' \
    && return 0
return 1
##############################################################################
-- 
 Haakon
Messages sorted by:
Reverse Date,
Date,
Thread,
Author