From 2740cc80d20d44d2f1ab09f3647c82903d42f3ca Mon Sep 17 00:00:00 2001 From: Terje Larsen Date: Wed, 7 Dec 2016 11:05:14 +0100 Subject: [PATCH] improve make target completion - Support completing dynamic make targets. - Support completing make targets when using -C/--directory. - Support `-Cdir/path`, `-C dir/path` - Support `--directory=dir/path`, `--directory dir/path` This detects if the make command have the `-p` switch otherwise it assumes it is BSD make and will run a different command to try to figure out the available targets. --- share/completions/make.fish | 12 +++++-- .../functions/__fish_print_make_targets.fish | 31 +++++++++++++------ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/share/completions/make.fish b/share/completions/make.fish index dbebb409e..d62ee8cd7 100644 --- a/share/completions/make.fish +++ b/share/completions/make.fish @@ -1,13 +1,21 @@ # Completions for make +function __fish_complete_make_targets + set directory (string replace -r '^make .*(-C ?|--directory[= ]?)([^ ]*) .*$' '$2' -- $argv) + if test $status -eq 0 -a -d $directory + __fish_print_make_targets $directory + else + __fish_print_make_targets + end +end # This completion reenables file completion on # assignments, so e.g. 'make foo FILES=' will receive standard # filename completion. complete -c make -n 'commandline -ct | string match "*=*"' -complete -x -c make -a "(__fish_print_make_targets)" --description "Target" +complete -x -c make -a "(__fish_complete_make_targets (commandline -c))" --description "Target" complete -r -c make -s f --description "Use file as makefile" -r -complete -x -c make -s C -x -a "(__fish_complete_directories (commandline -ct))" --description "Change directory" +complete -x -c make -s C -l directory -x -a "(__fish_complete_directories (commandline -ct))" --description "Change directory" complete -c make -s d --description "Debug mode" complete -c make -s e --description "Environment before makefile" complete -c make -s i --description "Ignore errors" diff --git a/share/functions/__fish_print_make_targets.fish b/share/functions/__fish_print_make_targets.fish index bf3ecb9f2..c5640324f 100644 --- a/share/functions/__fish_print_make_targets.fish +++ b/share/functions/__fish_print_make_targets.fish @@ -1,13 +1,26 @@ -function __fish_print_make_targets - # Some seds (e.g. on Mac OS X), don't support \n in the RHS - # Use a literal newline instead - # http://sed.sourceforge.net/sedfaq4.html#s4.1 - # The 'rev | cut | rev' trick removes everything after the last colon - for file in GNUmakefile Makefile makefile +function __fish_print_make_targets --argument directory + # Since we filter based on localized text, we need to ensure the + # text will be using the correct locale. + set -lx LC_ALL C + + if test -z "$directory" + set directory '.' + end + + set -l bsd_make + if make -C $directory -pn >/dev/null ^/dev/null + set bsd_make 0 + else + set bsd_make 1 + end + + for file in $directory/{GNUmakefile,Makefile,makefile} if test -f $file - __fish_sgrep -h -o -E '^[^#%=$[:space:]][^#%=$]*:([^=]|$)' $file ^/dev/null | rev | cut -d ":" -f 2- | rev | sed -e 's/^ *//;s/ *$//;s/ */\\ -/g' ^/dev/null - # On case insensitive filesystems, Makefile and makefile are the same; stop now so we don't double-print + if test "$bsd_make" = 0 + make -C $directory -prRn | awk -v RS= -F: '/^# Files/,/^# Finished Make data base/ {if ($1 !~ "^[#.]") {print $1}}' ^/dev/null + else + make -C $directory -d g1 -rn >/dev/null ^| awk -F, '/^#\*\*\* Input graph:/,/^$/ {if ($1 !~ "^#... ") {gsub(/# /,"",$1); print $1}}' ^/dev/null + end break end end