zsh-workers
 help / color / mirror / code / Atom feed
* Re: Bug#262247: zsh: Improved make completion
       [not found] <20040730101751.GA11905@larve.net>
@ 2004-07-30 15:30 ` Clint Adams
  2004-07-30 16:51   ` Hugo Haas
  0 siblings, 1 reply; 7+ messages in thread
From: Clint Adams @ 2004-07-30 15:30 UTC (permalink / raw)
  To: zsh-workers; +Cc: Hugo Haas, 262247-forwarded

[-- Attachment #1: Type: text/plain, Size: 655 bytes --]

> Attached is a Perl script that can be used as a replacement of the
> Perl script appearing in the make completion code (_make) to follow
> include statements in Makefiles.

You mean it should replace the expression

'@matches = /^(?:([a-zA-Z0-9]+[^\/\t=\s]+)\s*)+:/  and
        print join(" ", @matches);
if (/^\.include\s+\<bsd\.port\.(subdir\.|pre\.)?mk>/ ||
    /^\.include\s+\".*mk\/bsd\.pkg\.(subdir\.)?mk\"/) {
    print "fetch fetch-list extract patch configure build install reinstall dein
stall package describe checkpatch checksum makesum\n";
    }
'

in _make?

Maybe the perl and awk bits should be replaced by some native Z-Shell parsing.

[-- Attachment #2: ma.pl --]
[-- Type: text/x-perl, Size: 673 bytes --]

sub match() {
    my ($fn) = @_;
    @matches = /^(?:([a-zA-Z0-9]+[^\/\t=\s]+)\s*)+:/  and 
    print join(" ", @matches);
    if (/^include\s+(\S+)/) {
	my $i = $1;;
	if ($fn =~ m|/|) {
	    $fn =~ s|/[^/]+$|/$i|;
	} else {
	    $fn = $i;
	}
	&parse($fn);
    }
    elsif (/^\.include\s+\<bsd\.port\.(subdir\.|pre\.)?mk>/ ||
	     /^\.include\s+\".*mk\/bsd\.pkg\.(subdir\.)?mk\"/) {
	print "fetch fetch-list extract patch configure build install reinstall deinstall package describe checkpatch checksum makesum\n";
    }
}

sub parse() {
    my ($fn) = @_;
    my $f;
    open($f, $fn) || return;
    while (<$f>) {
	&match($fn);
    }
    close($f);
}

&parse($ARGV[0]);

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Bug#262247: zsh: Improved make completion
  2004-07-30 15:30 ` Bug#262247: zsh: Improved make completion Clint Adams
@ 2004-07-30 16:51   ` Hugo Haas
  2004-08-18 15:07     ` Hugo Haas
  0 siblings, 1 reply; 7+ messages in thread
From: Hugo Haas @ 2004-07-30 16:51 UTC (permalink / raw)
  To: Clint Adams; +Cc: zsh-workers, 262247-forwarded

[-- Attachment #1: Type: text/plain, Size: 1078 bytes --]

* Clint Adams <schizo@debian.org> [2004-07-30 11:30-0400]
> > Attached is a Perl script that can be used as a replacement of the
> > Perl script appearing in the make completion code (_make) to follow
> > include statements in Makefiles.
> 
> You mean it should replace the expression
> 
> '@matches = /^(?:([a-zA-Z0-9]+[^\/\t=\s]+)\s*)+:/  and
>         print join(" ", @matches);
> if (/^\.include\s+\<bsd\.port\.(subdir\.|pre\.)?mk>/ ||
>     /^\.include\s+\".*mk\/bsd\.pkg\.(subdir\.)?mk\"/) {
>     print "fetch fetch-list extract patch configure build install reinstall dein
> stall package describe checkpatch checksum makesum\n";
>     }
> '
> 
> in _make?

Yes, it basically does the same, but follows include statements. It
doesn't work for something like "include $(MYFILE)", but works for
"include myfile" — resolving variable seemed complex.

> Maybe the perl and awk bits should be replaced by some native Z-Shell parsing.

I agree, but that sounds complex to do. :-)

Cheers,

Hugo

-- 
Hugo Haas - http://larve.net/people/hugo/

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 307 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Bug#262247: zsh: Improved make completion
  2004-07-30 16:51   ` Hugo Haas
@ 2004-08-18 15:07     ` Hugo Haas
  2004-08-18 17:04       ` Wayne Davison
  2004-08-21 18:09       ` Wayne Davison
  0 siblings, 2 replies; 7+ messages in thread
From: Hugo Haas @ 2004-08-18 15:07 UTC (permalink / raw)
  To: Clint Adams; +Cc: zsh-workers, 262247


[-- Attachment #1.1: Type: text/plain, Size: 1317 bytes --]

* Hugo Haas <hugo@larve.net> [2004-07-30 18:51+0200]
> * Clint Adams <schizo@debian.org> [2004-07-30 11:30-0400]
> > > Attached is a Perl script that can be used as a replacement of the
> > > Perl script appearing in the make completion code (_make) to follow
> > > include statements in Makefiles.
> > 
> > You mean it should replace the expression
> > 
> > '@matches = /^(?:([a-zA-Z0-9]+[^\/\t=\s]+)\s*)+:/  and
> >         print join(" ", @matches);
> > if (/^\.include\s+\<bsd\.port\.(subdir\.|pre\.)?mk>/ ||
> >     /^\.include\s+\".*mk\/bsd\.pkg\.(subdir\.)?mk\"/) {
> >     print "fetch fetch-list extract patch configure build install reinstall dein
> > stall package describe checkpatch checksum makesum\n";
> >     }
> > '
> > 
> > in _make?
> 
> Yes, it basically does the same, but follows include statements. It
> doesn't work for something like "include $(MYFILE)", but works for
> "include myfile" — resolving variable seemed complex.
> 
> > Maybe the perl and awk bits should be replaced by some native Z-Shell parsing.
> 
> I agree, but that sounds complex to do. :-)

Attached is an attempt at doing this. It seems to work, though I only
enabled it for the gnu case.

Let me know what you think.

Regards,

Hugo

-- 
Hugo Haas - http://larve.net/people/hugo/

[-- Attachment #1.2: patch-make --]
[-- Type: text/plain, Size: 1510 bytes --]

--- _make	2004-08-18 10:10:24.000000000 -0400
+++ /usr/share/zsh/4.2.0/functions/Completion/Unix/_make	2004-08-18 11:03:52.000000000 -0400
@@ -1,5 +1,26 @@
 #compdef make gmake pmake dmake
 
+parseMakefile() {
+    local input
+    while read input; do
+	case $input in
+	    [[:alnum:]]##:)
+		echo $input| cut -d: -f1
+		;;
+	    include\ *)
+                local f
+		f=$(echo $input| cut -d\  -f2)
+		if [ $f != '/*' ]; then
+		    f=$dir/$f
+		fi
+		if [ -r $f ]; then
+		    parseMakefile < $f
+		fi
+		;;
+	esac
+    done
+}
+
 local prev="$words[CURRENT-1]" file expl tmp is_gnu cmdargs useperl
 
 zstyle -t ":completion:${curcontext}:" use-perl && useperl=1
@@ -24,14 +45,10 @@
   fi
 
   if [[ -n "$file" ]] && _tags targets; then
-    if [[ $is_gnu = gnu ]] &&
-       zstyle -t ":completion:${curcontext}:targets" call-command; then
-       if [[ -n $useperl ]]; then
-        cmdargs=(perl -F: -ane '/^[a-zA-Z0-9][^\/\t=]+:/ && print "$F[0]\n"')
-       else
-        cmdargs=(awk '/^[a-zA-Z0-9][^\/\t=]+:/ {print $1}' FS=:)
-       fi
-       tmp=( $(_call_program targets "$words[1]" -nsp --no-print-directory -f "$file" .PHONY 2> /dev/null | $cmdargs) )
+    if [[ $is_gnu = gnu ]]; then
+      dir=$(dirname $file)
+      tmp=( $(parseMakefile < $file) )
+      _wanted targets expl 'make target' compadd -a tmp && return 0
     elif [[ -n $useperl ]]; then
       tmp=(
       $(perl -ne '@matches = /^(?:([a-zA-Z0-9]+[^\/\t=\s]+)\s*)+:/  and

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 307 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Bug#262247: zsh: Improved make completion
  2004-08-18 15:07     ` Hugo Haas
@ 2004-08-18 17:04       ` Wayne Davison
  2004-08-21 18:09       ` Wayne Davison
  1 sibling, 0 replies; 7+ messages in thread
From: Wayne Davison @ 2004-08-18 17:04 UTC (permalink / raw)
  To: zsh-workers

While I was looking at your patch, I tried turning on useperl without
your patch applied and discovered that the completion of make targets
stopped working.  Here's a patch to fix it:

--- orig/_make	2002-10-03 23:03:41.000000000 -0700
+++ _make	2004-08-18 10:01:53.000000000 -0700
@@ -35,7 +35,7 @@
     elif [[ -n $useperl ]]; then
       tmp=(
       $(perl -ne '@matches = /^(?:([a-zA-Z0-9]+[^\/\t=\s]+)\s*)+:/  and
-	print join(" ", @matches);
+	print join(" ", @matches), "\n";
 if (/^\.include\s+\<bsd\.port\.(subdir\.|pre\.)?mk>/ ||
     /^\.include\s+\".*mk\/bsd\.pkg\.(subdir\.)?mk\"/) {
     print "fetch fetch-list extract patch configure build install reinstall deinstall package describe checkpatch checksum makesum\n";

..wayne..


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Bug#262247: zsh: Improved make completion
  2004-08-18 15:07     ` Hugo Haas
  2004-08-18 17:04       ` Wayne Davison
@ 2004-08-21 18:09       ` Wayne Davison
  2004-08-22  1:47         ` Bart Schaefer
  2004-08-26 16:10         ` Hugo Haas
  1 sibling, 2 replies; 7+ messages in thread
From: Wayne Davison @ 2004-08-21 18:09 UTC (permalink / raw)
  To: Hugo Haas; +Cc: zsh-workers, 262247

[-- Attachment #1: Type: text/plain, Size: 858 bytes --]

On Wed, Aug 18, 2004 at 11:07:36AM -0400, Hugo Haas wrote:
> Attached is an attempt at doing this. It seems to work, though I only
> enabled it for the gnu case.

I tried your patch, and it ignored targets that had dependencies (since
it only matched a colon at the end of the line).  Here's my attempt at a
zsh-only verson of _make.  It not only follows include files, but it
expands variables too.  I tried to make it handle both gnu and non-gnu
include files, but I assume that the ".include <...>" form needs more
code to handle where the include really resides.

Since the patch was larger than the new _make script, I'm just attaching
the new _make script here.  Give it a try and see how you like it.

Also, feel free to suggest how to improve it (for instance, I'd like to
know if the eval statements can be replaced with something else).

..wayne..

[-- Attachment #2: _make --]
[-- Type: text/plain, Size: 2471 bytes --]

#compdef make gmake pmake dmake

local prev="$words[CURRENT-1]" file expl tmp is_gnu cmdargs dir incl

expandVars() {
    local open close var val tmp=$1 ret=$1
    while :; do
	var=${tmp#*\$}
	if [[ $var != $tmp ]]; then
	    tmp=$var
	    case $var in
	    (\(*)
		open='('
		close=')'
		;;
	    ({*)
		open='{'
		close='}'
		;;
	    ([[:alnum:]]*)
		open=''
		close=''
		var=${(s::)var[1]}
		;;
	    (*)
		continue
		;;
	    esac
	    if [[ $open != '' ]]; then
		var=${var#$open}
		var=${var%%$close*}
	    fi
	    case $var in
	    ([[:alnum:]_]#)
		eval val=\${$var}
		val=$(expandVars $val)
		ret=${ret//\$$open$var$close/$val}
		;;
	    esac
	else
	    print $ret
	    return
	fi
    done
}

parseMakefile() {
    local input var val TAB=$'\t' dir=$1

    while read input; do
	case "$input " in
	([[:alnum:]][^$TAB:= ]#[ $TAB]#=*)
	    var=${input%%[ $TAB]#=*}
	    val=${input#*=}
	    val=${val##[ $TAB]#}
	    eval $var=\$val
	    ;;
	([[:alnum:]][^$TAB:= ]#[ $TAB]#:=*)
	    var=${input%%[ $TAB]#:=*}
	    val=${input#*=}
	    val=${val##[ $TAB]#}
	    val=$(expandVars $val)
	    eval $var=\$val
	    ;;
	([[:alnum:]][^$TAB:=]#:[^=]*)
	    input=${input%%:*}
	    print $(expandVars $input)
	    ;;
	($incl *)
	    local f=${input##$incl ##}
	    if [[ $incl = '.include' ]]; then
		f=${f#[\"<]}
		f=${f%[\">]}
	    fi
	    f=$(expandVars $f)
	    case $f in
	    (/*) ;;
	    (*)  f=$dir/$f ;;
	    esac
	    if [ -r $f ]; then
		parseMakefile ${f%%/[^/]##} < $f
	    fi
	    ;;
	esac
    done
}

_pick_variant -r is_gnu gnu=GNU unix -v -f

if [[ $is_gnu = gnu ]]; then
    incl=include
else
    incl=.include
fi
if [[ "$prev" = -[CI] ]]; then
  _files -/
elif [[ "$prev" = -[foW] ]]; then
  _files
else
  file="$words[(I)-f]"
  if (( file )); then
    file="$words[file+1]"
  elif [[ -e Makefile ]]; then
    file=Makefile
  elif [[ -e makefile ]]; then
    file=makefile
  elif [[ $is_gnu = gnu && -e GNUmakefile ]]; then
    file=GNUmakefile
  else
    file=''
  fi

  if [[ -n "$file" ]] && _tags targets; then
    if [[ $is_gnu = gnu ]] &&
       zstyle -t ":completion:${curcontext}:targets" call-command; then
       tmp=( $(_call_program targets "$words[1]" -nsp --no-print-directory -f "$file" .PHONY 2> /dev/null | parseMakefile $PWD) )
    else
       tmp=( $(parseMakefile $PWD < $file) )
    fi
    _wanted targets expl 'make target' compadd -a tmp && return 0
  fi
  compstate[parameter]="${PREFIX%%\=*}"
  compset -P 1 '*='
  _value "$@"
fi

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Bug#262247: zsh: Improved make completion
  2004-08-21 18:09       ` Wayne Davison
@ 2004-08-22  1:47         ` Bart Schaefer
  2004-08-26 16:10         ` Hugo Haas
  1 sibling, 0 replies; 7+ messages in thread
From: Bart Schaefer @ 2004-08-22  1:47 UTC (permalink / raw)
  To: zsh-workers

[Dropped bugs.debian.org]

On Sat, 21 Aug 2004, Wayne Davison wrote:

> Also, feel free to suggest how to improve it (for instance, I'd like to 
> know if the eval statements can be replaced with something else).

Let's see ...

                eval val=\${$var}

... I believe that's ...

		val=${(P)var}

... and ...

            eval $var=\$val

... can be ...

	    : ${(P)var::=$val}

... but I'm not sure that last is any better than the eval.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Bug#262247: zsh: Improved make completion
  2004-08-21 18:09       ` Wayne Davison
  2004-08-22  1:47         ` Bart Schaefer
@ 2004-08-26 16:10         ` Hugo Haas
  1 sibling, 0 replies; 7+ messages in thread
From: Hugo Haas @ 2004-08-26 16:10 UTC (permalink / raw)
  To: Wayne Davison; +Cc: zsh-workers, 262247

[-- Attachment #1: Type: text/plain, Size: 2204 bytes --]

Hi Wayne.

* Wayne Davison <wayned@users.sourceforge.net> [2004-08-21 11:09-0700]
> On Wed, Aug 18, 2004 at 11:07:36AM -0400, Hugo Haas wrote:
> > Attached is an attempt at doing this. It seems to work, though I only
> > enabled it for the gnu case.
> 
> I tried your patch, and it ignored targets that had dependencies (since
> it only matched a colon at the end of the line).

Oh, that's right…

> Here's my attempt at a zsh-only verson of _make.  It not only
> follows include files, but it expands variables too.

It's pretty cool. I found an issue with the code though, which I don't
know how to work around: variable names are different in make and zsh.

In make:

  A variable name may be any sequence of characters not containing
  `:', `#', `=', or leading or trailing whitespace.

In zsh:

  A name may be any sequence of alphanumeric characters and
  underscores, or  the single  characters ‘*’, ‘@’, ‘#’, ‘?’, ‘-’,
  ‘$’, or ‘!’.

I guess that it's not a big deal: there will be cases where variables
won't be expanded, and certain rules will be missing, but it's better
than the previous code which didn't look at variables at all.

Also, the make documentation says:

  However, variable names containing characters other than letters,
  numbers, and underscores should be avoided, as they may be given
  special meanings in the future, and with some shells they cannot be
  passed through the environment to a sub-`make' (*note Communicating
  Variables to a Sub-`make': Variables/Recursion.).

Therefore, it's recommended to use cases which are actually going to
work with your code. So I think it's fine.

> I tried to make it handle both gnu and non-gnu include files, but I
> assume that the ".include <...>" form needs more code to handle
> where the include really resides.
> 
> Since the patch was larger than the new _make script, I'm just attaching
> the new _make script here.  Give it a try and see how you like it.

I think it's a great improvement on the current _make script, and
would be happy to see it included in zsh.

Regards,

Hugo

-- 
Hugo Haas - http://larve.net/people/hugo/

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 307 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-08-26 19:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20040730101751.GA11905@larve.net>
2004-07-30 15:30 ` Bug#262247: zsh: Improved make completion Clint Adams
2004-07-30 16:51   ` Hugo Haas
2004-08-18 15:07     ` Hugo Haas
2004-08-18 17:04       ` Wayne Davison
2004-08-21 18:09       ` Wayne Davison
2004-08-22  1:47         ` Bart Schaefer
2004-08-26 16:10         ` Hugo Haas

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).