From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1978 invoked from network); 21 Jun 1999 12:06:15 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 21 Jun 1999 12:06:15 -0000 Received: (qmail 15942 invoked by alias); 21 Jun 1999 12:05:41 -0000 Mailing-List: contact zsh-users-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 2402 Received: (qmail 15931 invoked from network); 21 Jun 1999 12:05:39 -0000 To: zsh-users@sunsite.auc.dk Sender: monnier@tequila.cs.yale.edu From: "Stefan Monnier" Newsgroups: lists.zsh.users Subject: Re: completions for make targets? References: Date: 21 Jun 1999 08:05:24 -0400 Message-ID: <5l3dzl3gjf.fsf@tequila.cs.yale.edu> X-Newsreader: Gnus v5.7/Emacs 20.3 Path: tequila.cs.yale.edu NNTP-Posting-Host: tequila.cs.yale.edu X-Trace: 21 Jun 1999 08:05:27 -0500, tequila.cs.yale.edu >>>>> "Raju" == Raju K V writes: > How can I use compctl to complate make targets? Admittedly, my solution doesn't exploit compctl too much (maybe because I had it for tcsh before and just adapted it), but it's probably a bit fancier (in some respects) than many others: comp_make () { local cmd args i where read -Ac cmd; read -cn where i=1 while [[ "$i" -lt "$#cmd" ]]; do if [[ "$cmd[$i]" = "-f" ]]; then reply=("${(@f)$(~/libexec/complete/make.perl "$cmd[$[$i + 1]]" 2>/dev/null)}") comp_fixreply return 0; else ((i += 1)) fi done reply=("${(@f)$(~/libexec/complete/make.perl 2>/dev/null)}") comp_fixreply } compctl -x 'c[-1,-f]' -f -- + -Q -S '' -K comp_make + gmake make now, you'll notice that this depends on a perl file that does the actual target extraction. The perl file is appended. Stefan #!/usr/bin/env perl # read all the var definitions into the "vars" hash-table # and the target lines into the "targetlines" array sub ReadFile { local($file) = @_; local($prevs) = (""); open(MAKEFILE, "<$file") || return; for () { chomp(); $_ = $prevs . $_; $prevs = ""; if (s/\\$//o ) { $prevs = $_; } elsif (/^[- \t]*include[ \t]+([^ \t]+)/) { push(@includes, $1); } elsif (/^[ \t]*([-a-zA-Z0-9_.]+)[ \t]*=(.*)$/o) { $vars{$1} = $2; } elsif (/^((([-a-zA-Z0-9_ ][-a-zA-Z0-9_. ]*)|(\$\((([^()]+)|(\$\([^()]+\)))\)))+)[\t ]*:/o) { push(@targetlines, $1); } } close(MAKEFILE); if ($file = pop(@includes)) { ReadFile($file); } } # debugging: dump out the vars, their values and the targetlines #print "**bindings**\n"; #@vars = keys(%vars); #for (@vars) { # print "<$_> is <$vars{$_}>\n"; #} #print "**targets**\n"; #for (@targetlines) { # print "$_\n"; #} sub ExpandTargets { local(@targets); # look for potential targets (lines with a ":") for $targets (@targetlines) { # for each set of targets, look for variables to substitue while (($var) = $targets =~ /\$\( *([^()\$]*)\)/o ) { # print "var =$var: <$targets> => <"; # first case: a simple macro if ($tmpvar = $vars{$var}) { $var =~ s/([^a-zA-Z0-9 ])/\\$1/og; # quote var $targets =~ s/\$\( *$var\)/$tmpvar/g ; #second case: a macro with simple substitution } elsif (($var0, $s1, $s2) = $var =~ / *(.*):(.*)=(.*)/o) { if ($tmpvar = $vars{$var0}) { $s1 =~ s/([^a-zA-Z0-9 ])/\\$1/og; # quote s1 $tmpvar =~ s/$s1/$s2/g ; $s2 =~ s/([^a-zA-Z0-9 ])/\\$1/og; # quote s2 $var0 =~ s/([^a-zA-Z0-9 ])/\\$1/og; # quote var0 $targets =~ s/\$\( *$var0:$s1=$s2\)/$tmpvar/g ; } else { $var0 =~ s/([^a-zA-Z0-9 ])/\\$1/og; # quote var0 $targets =~ s/\$\( *$var0:$s1=$s2\)//g ; } } else { $var =~ s/([^a-zA-Z0-9 ])/\\$1/og; # quote var $targets =~ s/\$\( *$var\)//g ; } # print "$targets>\n"; } $targets =~ s/:.*$//; # removes anything after a : # split the "targets line" into an array of targets @targets = ($targets =~ /([^ ]+)/og ); #put each target into a hash-table (to remove duplicates) for $target (@targets) { $targets{$target} = true; } } } if ($#ARGV < 0) { if (-r "GNUmakefile") { $file = "GNUmakefile"; } elsif (-r "Makefile") { $file = "Makefile"; } elsif (-r "makefile") { $file = "makefile"; } else { $file = "/dev/null"; } } else { $file = $ARGV[0]; } ReadFile($file); ExpandTargets(); # dump out the table of targets for $target (keys(%targets)) { print "$target \n"; } for $var (keys(%vars)) { print "$var=\n"; }