Imported Upstream version 7.59.0
[platform/upstream/curl.git] / scripts / zsh.pl
1 #!/usr/bin/env perl
2
3 # Generate ZSH completion
4
5 use strict;
6 use warnings;
7
8 my $curl = $ARGV[0] || 'curl';
9
10 my $regex = '\s+(?:(-[^\s]+),\s)?(--[^\s]+)\s([^\s.]+)?\s+(.*)';
11 my @opts = parse_main_opts('--help', $regex);
12
13 my $opts_str;
14
15 $opts_str .= qq{  $_ \\\n} foreach (@opts);
16 chomp $opts_str;
17
18 my $tmpl = <<"EOS";
19 #compdef curl
20
21 # curl zsh completion
22
23 local curcontext="\$curcontext" state state_descr line
24 typeset -A opt_args
25
26 local rc=1
27
28 _arguments -C -S \\
29 $opts_str
30   '*:URL:_urls' && rc=0
31
32 return rc
33 EOS
34
35 print $tmpl;
36
37 sub parse_main_opts {
38     my ($cmd, $regex) = @_;
39
40     my @list;
41     my @lines = call_curl($cmd);
42
43     foreach my $line (@lines) {
44         my ($short, $long, $arg, $desc) = ($line =~ /^$regex/) or next;
45
46         my $option = '';
47
48         $desc =~ s/'/'\\''/g if defined $desc;
49         $desc =~ s/\[/\\\[/g if defined $desc;
50         $desc =~ s/\]/\\\]/g if defined $desc;
51
52         $option .= '{' . trim($short) . ',' if defined $short;
53         $option .= trim($long)  if defined $long;
54         $option .= '}' if defined $short;
55         $option .= '\'[' . trim($desc) . ']\'' if defined $desc;
56
57         $option .= ":'$arg'" if defined $arg;
58
59         $option .= ':_files'
60             if defined $arg and ($arg eq '<file>' || $arg eq '<filename>'
61                 || $arg eq '<dir>');
62
63         push @list, $option;
64     }
65
66     # Sort longest first, because zsh won't complete an option listed
67     # after one that's a prefix of it.
68     @list = sort {
69         $a =~ /([^=]*)/; my $ma = $1;
70         $b =~ /([^=]*)/; my $mb = $1;
71
72         length($mb) <=> length($ma)
73     } @list;
74
75     return @list;
76 }
77
78 sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
79
80 sub call_curl {
81     my ($cmd) = @_;
82     my $output = `"$curl" $cmd`;
83     if ($? == -1) {
84         die "Could not run curl: $!";
85     } elsif ((my $exit_code = $? >> 8) != 0) {
86         die "curl returned $exit_code with output:\n$output";
87     }
88     return split /\n/, $output;
89 }