about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
authorPaul Ackersviller <packersv@users.sourceforge.net>2007-11-05 02:44:52 +0000
committerPaul Ackersviller <packersv@users.sourceforge.net>2007-11-05 02:44:52 +0000
commit17eda071fe660ae704ed9bb48c3558ca73e4eb22 (patch)
tree16d2bc6410997c82cb51eac81295019dfae6a23a /Completion
parent3cf23604b0327a698516eba7fcfaca99d6746f9d (diff)
downloadzsh-17eda071fe660ae704ed9bb48c3558ca73e4eb22.tar.gz
zsh-17eda071fe660ae704ed9bb48c3558ca73e4eb22.tar.xz
zsh-17eda071fe660ae704ed9bb48c3558ca73e4eb22.zip
Merge of 22205, 22988, and 22993.
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Unix/Command/_make56
1 files changed, 46 insertions, 10 deletions
diff --git a/Completion/Unix/Command/_make b/Completion/Unix/Command/_make
index 91dcc1558..93d4b52da 100644
--- a/Completion/Unix/Command/_make
+++ b/Completion/Unix/Command/_make
@@ -51,6 +51,12 @@ expandVars() {
     done
 }
 
+# parseMakefile only runs inside $(...), so it doesn't matter that
+# it pollutes the global namespace, setting zsh variables to
+# make variables.  The difficult case is where a make variable
+# is special in zsh; we use local -h to hide those.  This
+# isn't a complete solution since it means variables defined in
+# included Makefiles are undefined before returning to the parent.
 parseMakefile() {
     local input var val TAB=$'\t' dir=$1
 
@@ -60,6 +66,7 @@ parseMakefile() {
 	    var=${input%%[ $TAB]#=*}
 	    val=${input#*=}
 	    val=${val##[ $TAB]#}
+	    [[ ${(tP)var} = *special ]] && local -h $var
 	    eval $var=\$val
 	    ;;
 	([[:alnum:]][[:alnum:]_]#[ $TAB]#:=*)
@@ -67,6 +74,7 @@ parseMakefile() {
 	    val=${input#*=}
 	    val=${val##[ $TAB]#}
 	    val=$(expandVars 10 $val)
+	    [[ ${(tP)var} = *special ]] && local -h $var
 	    eval $var=\$val
 	    ;;
 	([[:alnum:]][^$TAB:=]#:[^=]*)
@@ -92,6 +100,28 @@ parseMakefile() {
     done
 }
 
+findBasedir () {
+  local file index basedir
+  basedir=$PWD
+  for ((index=0; index<$#@; index++)); do
+    if [[ $@[index] = -C ]]; then
+      file=${~@[index+1]};
+      if [[ -z $file ]]; then
+	# make returns with an error if an empty arg is given
+	# even if the concatenated path is a valid directory
+	return
+      elif [[ $file = /* ]]; then
+	# Absolute path, replace base directory
+	basedir=$file
+      else
+	# Relative, concatenate path
+	basedir=$basedir/$file
+      fi
+    fi
+  done
+  print -- $basedir
+}
+
 _pick_variant -r is_gnu gnu=GNU unix -v -f
 
 if [[ $is_gnu = gnu ]]; then
@@ -100,21 +130,27 @@ else
     incl=.include
 fi
 if [[ "$prev" = -[CI] ]]; then
-  _files -/
+  _files -W ${(q)$(findBasedir ${words[1,CURRENT-1]})} -/
 elif [[ "$prev" = -[foW] ]]; then
-  _files
+  _files -W ${(q)$(findBasedir $words)}
 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
+    file=${~words[file+1]}
+    [[ $file = [^/]* ]] && file=${(q)$(findBasedir $words)}/$file
+    [[ -r $file ]] || file=
   else
-    file=''
+    local basedir
+    basedir=${(q)$(findBasedir $words)}
+    if [[ $is_gnu = gnu && -r $basedir/GNUmakefile ]]; then
+      file=$basedir/GNUmakefile
+    elif [[ -r $basedir/makefile ]]; then
+      file=$basedir/makefile
+    elif [[ -r $basedir/Makefile ]]; then
+      file=$basedir/Makefile
+    else
+      file=''
+    fi
   fi
 
   if [[ -n "$file" ]] && _tags targets; then