Something went wrong. Try again.
🎥 Command line media player
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284#!/usr/bin/perl
# Generate ZSH completion
## This file is part of mpv.## mpv is free software; you can redistribute it and/or# modify it under the terms of the GNU Lesser General Public# License as published by the Free Software Foundation; either# version 2.1 of the License, or (at your option) any later version.## mpv is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU Lesser General Public License for more details.## You should have received a copy of the GNU Lesser General Public# License along with mpv. If not, see <http://www.gnu.org/licenses/>.#
use strict;use warnings;use warnings FATAL => 'uninitialized';
my $mpv = $ARGV[0] || 'mpv';
my @opts = parse_main_opts('--list-options', '^ (\-\-[^\s\*]*)\*?\s*(.*)');
die "Couldn't find any options" unless (@opts);
my @ao = parse_opts('--ao=help', '^ ([^\s\:]*)\s*: (.*)');my @vo = parse_opts('--vo=help', '^ ([^\s\:]*)\s*: (.*)');
my @af = parse_opts('--af=help', '^ ([^\s\:]*)\s*: (.*)');my @vf = parse_opts('--vf=help', '^ ([^\s\:]*)\s*: (.*)');
my @protos = parse_opts('--list-protocols', '^ ([^\s]*)');
my ($opts_str, $ao_str, $vo_str, $af_str, $vf_str, $protos_str);
$opts_str .= qq{ '$_' \\\n} foreach (@opts);chomp $opts_str;
$ao_str .= qq{ '$_' \\\n} foreach (@ao);chomp $ao_str;
$vo_str .= qq{ '$_' \\\n} foreach (@vo);chomp $vo_str;
$af_str .= qq{ '$_' \\\n} foreach (@af);chomp $af_str;
$vf_str .= qq{ '$_' \\\n} foreach (@vf);chomp $vf_str;
$protos_str = join(' ', @protos);
my $runtime_completions = <<'EOS'; profile|show-profile) local -a profiles local current for current in "${(@f)$($words[1] --profile=help)}"; do current=${current//\*/\\\*} current=${current//\:/\\\:} current=${current//\[/\\\[} current=${current//\]/\\\]} if [[ $current =~ $'\t'([^$'\t']*)$'\t'(.*) ]]; then if [[ -n $match[2] ]]; then current="$match[1][$match[2]]" else current="$match[1]" fi profiles=($profiles $current) fi done if [[ $state == show-profile ]]; then # For --show-profile, only one allowed if (( ${#profiles} > 0 )); then _values 'profile' $profiles && rc=0 fi else # For --profile, multiple allowed profiles=($profiles 'help[list profiles]') _values -s , 'profile(s)' $profiles && rc=0 fi ;;
audio-device) local -a audio_devices local current for current in "${(@f)$($words[1] --audio-device=help)}"; do current=${current//\*/\\\*} current=${current//\:/\\\:} current=${current//\[/\\\[} current=${current//\]/\\\]} if [[ $current =~ ' '\'([^\']*)\'' \('(.*)'\)' ]]; then audio_devices=($audio_devices "$match[1][$match[2]]") fi done audio_devices=($audio_devices 'help[list audio devices]') _values 'audio device' $audio_devices && rc=0 ;;EOSchomp $runtime_completions;
my $tmpl = <<"EOS";#compdef mpv
# For customization, see:# https://github.com/mpv-player/mpv/wiki/Zsh-completion-customization
local curcontext="\$curcontext" state state_descr linetypeset -A opt_args
local -a match mbegin mendlocal MATCH MBEGIN MEND
# By default, don't complete URLs unless no files matchlocal -a tag_orderzstyle -a ":completion:*:*:\$service:*" tag-order tag_order || \ zstyle ":completion:*:*:\$service:*" tag-order '!urls'
local rc=1
_arguments -C -S \\$opts_str '*:files:->mfiles' && rc=0
case \$state in ao) _values -s , 'audio outputs' \\$ao_str && rc=0 ;;
vo) _values -s , 'video outputs' \\$vo_str && rc=0 ;;
af) _values -s , 'audio filters' \\$af_str && rc=0 ;;
vf) _values -s , 'video filters' \\$vf_str && rc=0 ;;
$runtime_completions
files) compset -P '*,' compset -S ',*' _files -r ',/ \\t\\n\\-' && rc=0 ;;
mfiles) local expl _tags files urls while _tags; do _requested files expl 'media file' _files && rc=0 if _requested urls; then while _next_label urls expl URL; do _urls "\$expl[@]" && rc=0 compadd -S '' "\$expl[@]" $protos_str && rc=0 done fi (( rc )) || return 0 done ;;esac
return rcEOS
print $tmpl;
sub parse_main_opts { my ($cmd, $regex) = @_;
my @list; my @lines = call_mpv($cmd);
foreach my $line (@lines) { my ($name, $desc) = ($line =~ /^$regex/) or next;
next if ($desc eq 'removed' || $desc eq 'alias');
if ($desc =~ /^Flag/) {
push @list, $name;
$name =~ /^--(.*)/; if ($1 !~ /^(\{|\}|v|list-options|really-quiet|no-.*)$/) { push @list, "--no-$1"; }
} elsif ($desc =~ /^Print/) {
push @list, $name;
} else {
# Option takes argument
my $entry = $name;
$desc =~ s/\:/\\:/g; $entry .= "=-:$desc:";
if ($desc =~ /^Choices\\: ([^(]*)/) { my $choices = $1; $choices =~ s/ +$//; # strip trailing space $entry .= "($choices)";
# If "no" is one of the choices, it can also be # negated like a flag (--no-whatever). if ($choices =~ /\bno\b/) { $name =~ s/^--/--no-/; push @list, $name; } } elsif ($line =~ /\[file\]/) { $entry .= '->files'; } elsif ($name =~ /^--(ao|vo|af|vf|profile|show-profile|audio-device)$/) { $entry .= "->$1"; } push @list, $entry; } }
# Sort longest first, because zsh won't complete an option listed # after one that's a prefix of it. @list = sort { $a =~ /([^=]*)/; my $ma = $1; $b =~ /([^=]*)/; my $mb = $1;
length($mb) <=> length($ma) } @list;
return @list;}
sub parse_opts { my ($cmd, $regex) = @_;
my @list; my @lines = call_mpv($cmd);
foreach my $line (@lines) { if ($line !~ /^$regex/) { next; }
my $entry = $1;
if (defined $2) { my $desc = $2; $desc =~ s/\:/\\:/g; $entry .= "[$desc]"; }
push @list, $entry }
return @list;}
sub call_mpv { my ($cmd) = @_; my $output = `"$mpv" --no-config $cmd`; if ($? == -1) { die "Could not run mpv: $!"; } elsif ((my $exit_code = $? >> 8) != 0) { die "mpv returned $exit_code with output:\n$output"; } return split /\n/, $output;}