zsh.pl 1.9 KB

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