Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Make Completion




One problem I have noticed when completing the options list is that it no longer seems to complete the makefile targets if the Makefile is selected using e.g. -f Makefile.FOO (so there is no default named Makefile in the directory). The "file=($opt_args[(K)(-f|--file|--makefile)])" does not seem to be returning a valid string/file

Regards

Nick


On 11/07/13 10:54, Peter Stephenson wrote:
On Wed, 10 Jul 2013 14:28:13 +0100
Nick Cross <zsh@xxxxxxxxx> wrote:
Am I right in thinking that the make completion under ZSH (5.0.2 on
Fedora18) does not complete the command line -* options (as opposed to
Bash which does) ? I have tried "make -<tab>" and nothing happens - in
bash it prints out a menu of the - options (e.g. --debug).

Yes, it's fairly basic in terms of options, though quite smart about
looking inside makefiles.

Currently it's quite hard to update since it doesn't use _arguments.  As
a first step, this fixes that problem, so it should be much easier to
add further GNU option handling as a next step (or further variants if
desired).

Lightly tested --- I don't think I've completely broken it but 100%
satisfaction not guaranteed.

diff --git a/Completion/Unix/Command/_make b/Completion/Unix/Command/_make
index 53e2e1b..72d16bb 100644
--- a/Completion/Unix/Command/_make
+++ b/Completion/Unix/Command/_make
@@ -148,7 +148,9 @@ _make-findBasedir () {
  _make() {

    local prev="$words[CURRENT-1]" file expl tmp is_gnu dir incl match
-  local -A TARGETS VARIABLES
+  local context state line
+  local -a option_specs
+  local -A TARGETS VARIABLES opt_args
    local ret=1

    _pick_variant -r is_gnu gnu=GNU unix -v -f
@@ -156,21 +158,43 @@ _make() {
    if [[ $is_gnu == gnu ]]
    then
      incl="(-|)include"
+    # TBD: update option_specs
+    option_specs=(
+      '-C[change directory first]:directory:->dir'
+      '-I[include directory for makefiles]:directory:->dir'
+      '-f[specify makefile]:makefile:->file'
+      '-o[specify file not to remake]:file not to remake:->file'
+      '-W[pretend file was modified]:file to treat as modified:->file'
+    )
    else
+    # Basic make options only.
      incl=.include
+    option_specs=(
+      '-C[change directory first]:directory:->dir'
+      '-I[include directory for makefiles]:directory:->dir'
+      '-f[specify makefile]:makefile:->file'
+      '-o[specify file not to remake]:file not to remake:->file'
+      '-W[pretend file was modified]:file to treat as modified:->file'
+    )
    fi

-  if [[ "$prev" == -[CI] ]]
-  then
+  _arguments -s $option_specs \
+    '*:make target:->target' && ret=0
+
+  case $state in
+    (dir)
      _files -W ${(q)$(_make-findBasedir ${words[1,CURRENT-1]})} -/ && ret=0
-  elif [[ "$prev" == -[foW] ]]
-  then
+    ;;
+
+    (file)
      _files -W ${(q)$(_make-findBasedir $words)} && ret=0
-  else
-    file="$words[(I)-f]"
-    if (( file ))
+    ;;
+
+    (target)
+    file=($opt_args[(K)(-f|--file|--makefile)])
+    file=$file[1]
+    if [[ -n $file ]]
      then
-      file=${~words[file+1]}
        [[ $file == [^/]* ]] && file=${(q)$(_make-findBasedir $words)}/$file
        [[ -r $file ]] || file=
      else
@@ -222,7 +246,7 @@ _make() {
            compadd -S '=' -- ${(k)VARIABLES} && ret=0
        done
      fi
-  fi
+  esac

    return ret
  }


pws




Messages sorted by: Reverse Date, Date, Thread, Author