Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate fish completion file #3545

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -53,6 +53,7 @@ mkinstalldirs
tags
test-driver
scripts/_curl
scripts/curl.fish
curl_fuzzer
curl_fuzzer_seed_corpus.zip
libstandaloneengine.a
@@ -3408,6 +3408,31 @@ case "$OPT_ZSH_FPATH" in
;;
esac

dnl **********************************************************************
dnl Check for fish completion path
dnl **********************************************************************

OPT_FISH_FPATH=default
AC_ARG_WITH(fish-functions-dir,
AC_HELP_STRING([--with-fish-functions-dir=PATH],[Install fish completions to PATH])
AC_HELP_STRING([--without-fish-functions-dir],[Do not install fish completions]),
[OPT_FISH_FPATH=$withval])
case "$OPT_FISH_FPATH" in
no)
dnl --without-fish-functions-dir option used
;;
default|yes)
dnl --with-fish-functions-dir option used without path
FISH_FUNCTIONS_DIR="$datarootdir/fish/completions"
AC_SUBST(FISH_FUNCTIONS_DIR)
;;
*)
dnl --with-fish-functions-dir option used with path
FISH_FUNCTIONS_DIR="$withval"
AC_SUBST(FISH_FUNCTIONS_DIR)
;;
esac

This comment has been minimized.

Copy link
@danielgustafsson

danielgustafsson Feb 10, 2019

Member

This will get unwieldy when the third and fourth and .. and ... shell gets added. Is there a way to support the tab completion with a single configure flag invocation? --with-shell-functions={fish|zsh}?

This comment has been minimized.

Copy link
@simon04

simon04 Feb 10, 2019

Author Contributor

Maybe someone else with a better understanding of the build system (than me) can investigate (later on)?

This comment has been minimized.

Copy link
@danielgustafsson

danielgustafsson Feb 13, 2019

Member

Yes, this can be deferred, potentially till when we want to add a third tab completion target even.


dnl **********************************************************************
dnl Back to "normal" configuring
dnl **********************************************************************
@@ -20,13 +20,15 @@
#
###########################################################################
ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@
FISH_FUNCTIONS_DIR = @FISH_FUNCTIONS_DIR@
PERL = @PERL@

ZSH_COMPLETION_FUNCTION_FILENAME = _curl
FISH_COMPLETION_FUNCTION_FILENAME = curl.fish

CLEANFILES = $(ZSH_COMPLETION_FUNCTION_FILENAME)
CLEANFILES = $(ZSH_COMPLETION_FUNCTION_FILENAME) $(FISH_COMPLETION_FUNCTION_FILENAME)

all-local: $(ZSH_COMPLETION_FUNCTION_FILENAME)
all-local: $(ZSH_COMPLETION_FUNCTION_FILENAME) $(FISH_COMPLETION_FUNCTION_FILENAME)

$(ZSH_COMPLETION_FUNCTION_FILENAME): zsh.pl
if CROSSCOMPILING
@@ -36,10 +38,20 @@ else # if not cross-compiling:
$(PERL) $(srcdir)/zsh.pl $(top_builddir)/src/curl$(EXEEXT) > $@
endif

$(FISH_COMPLETION_FUNCTION_FILENAME): zsh.pl
if CROSSCOMPILING
@echo "NOTICE: we can't generate fish completion when cross-compiling!"
else # if not cross-compiling:
@if ! test -x "$(PERL)"; then echo "No perl: can't install zsh.pl"; exit 0; fi
$(PERL) $(srcdir)/zsh.pl $(top_builddir)/src/curl$(EXEEXT) fish > $@
endif

install-data-local:
if CROSSCOMPILING
@echo "NOTICE: we can't install zsh completion when cross-compiling!"
else # if not cross-compiling:
$(MKDIR_P) $(DESTDIR)$(ZSH_FUNCTIONS_DIR)
$(MKDIR_P) $(DESTDIR)$(FISH_FUNCTIONS_DIR)
$(INSTALL_DATA) $(ZSH_COMPLETION_FUNCTION_FILENAME) $(DESTDIR)$(ZSH_FUNCTIONS_DIR)/$(ZSH_COMPLETION_FUNCTION_FILENAME)
$(INSTALL_DATA) $(FISH_COMPLETION_FUNCTION_FILENAME) $(DESTDIR)$(FISH_FUNCTIONS_DIR)/$(FISH_COMPLETION_FUNCTION_FILENAME)
endif
@@ -1,19 +1,25 @@
#!/usr/bin/env perl

# Generate ZSH completion
# Generate ZSH or FISH completion
This conversation was marked as resolved by bagder

This comment has been minimized.

Copy link
@danielgustafsson

danielgustafsson Feb 10, 2019

Member

I'm not sure it's worth complicating this script with multiple shell support, instead of just make a new fish.pl file. At the very least we should rename it..

This comment has been minimized.

Copy link
@simon04

simon04 Feb 10, 2019

Author Contributor

Thanks for your remarks! I also considered a separate fish.pl, but refrained from doing so to avoid duplicating the code for parsing and escaping the curl --help output. Ad renaming: agreed!

# Usage: zsh.pl [path to curl] [fish|zsh]

use strict;
use warnings;

my $curl = $ARGV[0] || 'curl';
my $shell = $ARGV[1] || 'zsh'; # zsh or fish
This conversation was marked as resolved by bagder

This comment has been minimized.

Copy link
@danielgustafsson

danielgustafsson Feb 10, 2019

Member

This makes the path to curl possible to omit if running for zsh, but not for fish which makes for poor user experience. If we go down the route of multi-shell support we should go for proper getopts parsing.

This comment has been minimized.

Copy link
@simon04

simon04 Feb 10, 2019

Author Contributor

Agreed, I'll integrate Getopt::Long

This comment has been minimized.

Copy link
@simon04

simon04 Feb 10, 2019

Author Contributor

Done.


my $regex = '\s+(?:(-[^\s]+),\s)?(--[^\s]+)\s*(\<.+?\>)?\s+(.*)';
my @opts = parse_main_opts('--help', $regex);

my $opts_str;
if ($shell eq 'fish') {
print "# curl fish completion\n\n";
print qq{$_ \n} foreach (@opts);
} elsif ($shell eq 'zsh') {
my $opts_str;

$opts_str .= qq{ $_ \\\n} foreach (@opts);
chomp $opts_str;
$opts_str .= qq{ $_ \\\n} foreach (@opts);
chomp $opts_str;

my $tmpl = <<"EOS";
#compdef curl
@@ -32,7 +38,8 @@
return rc
EOS

print $tmpl;
print $tmpl;
}

sub parse_main_opts {
my ($cmd, $regex) = @_;
@@ -52,16 +59,26 @@ sub parse_main_opts {
$desc =~ s/\]/\\\]/g if defined $desc;
$desc =~ s/\:/\\\:/g if defined $desc;

$option .= '{' . trim($short) . ',' if defined $short;
$option .= trim($long) if defined $long;
$option .= '}' if defined $short;
$option .= '\'[' . trim($desc) . ']\'' if defined $desc;

$option .= ":'$arg'" if defined $arg;

$option .= ':_files'
if defined $arg and ($arg eq '<file>' || $arg eq '<filename>'
|| $arg eq '<dir>');
if ($shell eq 'fish') {
$option .= "complete --command curl";
$option .= " --short-option '" . strip_dash(trim($short)) . "'"
if defined $short;
$option .= " --long-option '" . strip_dash(trim($long)) . "'"
if defined $long;
$option .= " --description '" . strip_dash(trim($desc)) . "'"
if defined $desc;
} elsif ($shell eq 'zsh') {
$option .= '{' . trim($short) . ',' if defined $short;
$option .= trim($long) if defined $long;
$option .= '}' if defined $short;
$option .= '\'[' . trim($desc) . ']\'' if defined $desc;

$option .= ":'$arg'" if defined $arg;

$option .= ':_files'
if defined $arg and ($arg eq '<file>' || $arg eq '<filename>'
|| $arg eq '<dir>');
}

push @list, $option;
}
@@ -73,12 +90,13 @@ sub parse_main_opts {
$b =~ /([^=]*)/; my $mb = $1;

length($mb) <=> length($ma)
} @list;
} @list if $shell eq 'zsh';

return @list;
}

sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
sub strip_dash { my $s = shift; $s =~ s/^-+//g; return $s };

sub call_curl {
my ($cmd) = @_;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.