153 lines
6.5 KiB
Fish
153 lines
6.5 KiB
Fish
function mm --description "MakeMeFish - List all Make targets in the Makefile of the current directory"
|
|
|
|
set current_pos 1
|
|
while test (count $argv) -ge $current_pos
|
|
# Check if a help flag was passed to mm
|
|
set help_flags -- -h --help
|
|
if contains -- $argv[$current_pos] $help_flags
|
|
echo ""
|
|
echo " Usage:"
|
|
echo " " (set_color green)"mm"(set_color normal) "will look for a Makefile in the order specified by GNU Make and list all targets in it."
|
|
echo " " "To filter for a specific target, just start typing and targets will be filtered as you type."
|
|
echo " " (set_color green)"mm <keyword>"(set_color normal) "will start MakeMeFish with an initial, editable query" (set_color green)"<keyword>"(set_color normal)
|
|
echo " " (set_color green)"mm -i"(set_color normal) "will start MakeMeFish in interactive mode. When a target is run, you will return to the selection menu."
|
|
echo " " (set_color green)"mm -f <filename>"(set_color normal) "to specify what Makefile to load."
|
|
echo " " "All flags can be combined in any order."
|
|
echo ""
|
|
return 0
|
|
else if test $argv[$current_pos] = "-f"
|
|
set current_pos (math "$current_pos+1") # skip the next
|
|
set filename $argv[$current_pos]
|
|
else if test $argv[$current_pos] = "-i"
|
|
set interactive 1
|
|
else
|
|
if set -q initial_query
|
|
set initial_query $initial_query $argv[$current_pos]
|
|
else
|
|
set initial_query $argv[$current_pos]
|
|
end
|
|
end
|
|
set current_pos (math "$current_pos+1")
|
|
end
|
|
|
|
function __mm_get_makefile_name -a 'filename'
|
|
if test -n "$filename"
|
|
set makefile_filenames $filename
|
|
else
|
|
set makefile_filenames 'GNUmakefile' 'makefile' 'Makefile'
|
|
end
|
|
for filename in $makefile_filenames
|
|
if test -f $filename
|
|
echo $filename
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
# Based on:
|
|
# https://github.com/fish-shell/fish-shell/blob/8e418f5205106b11f83fa1956076a9b20c56f0f9/share/completions/make.fish
|
|
# and
|
|
# https://stackoverflow.com/a/26339924
|
|
function __mm_parse_makefile -a 'filename'
|
|
# Ensure correct locale set
|
|
set -lx LC_ALL C
|
|
|
|
set makeflags -f $filename
|
|
|
|
# first awk merges any line that ends with a backslash with the next line
|
|
if make --version 2>/dev/null | string match -q 'GNU*'
|
|
make $makeflags -pRrq : 2>/dev/null |
|
|
awk '{if (sub(/\\\$/,"")) printf "%s", $0; else print $0}' |
|
|
awk -F: '/^# Files/,/^# Finished Make data base/ {
|
|
if ($1 == "# Not a target") skip = 1;
|
|
if ($1 !~ "^[#.\t]") {
|
|
if (!skip) print $1; skip=0
|
|
}
|
|
}' 2>/dev/null
|
|
else
|
|
# BSD make
|
|
make $makeflags -d g1 -rn >/dev/null 2>| awk -F, '/^#\*\*\* Input graph:/,/^$/ {if ($1 !~ "^#... ") {gsub(/# /,"",$1); print $1}}' 2>/dev/null
|
|
end
|
|
end
|
|
|
|
function __mm_get_targets -a 'filename'
|
|
set static_targets
|
|
set file_targets
|
|
set generated_targets
|
|
|
|
set parsed_makefile (__mm_parse_makefile $filename | sort -f)
|
|
for row in $parsed_makefile # Loop over all rows in the Makefile
|
|
set row (string trim $row)
|
|
if test -n "$row" # No blanks plz
|
|
if test (string match -r '.\.|\/' $row) # this is a file or path
|
|
set file_targets $file_targets $row
|
|
else # grep the target and see if it's generated by a function or a true target
|
|
set found_in_file (grep "$row:" $filename)
|
|
if test -n "$found_in_file"
|
|
set static_targets $static_targets $row # true target
|
|
else
|
|
set generated_targets $generated_targets $row # generated by function
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
string split " " $static_targets $file_targets $generated_targets
|
|
end
|
|
|
|
function __mm_fzf_command -a 'filename' -a 'interactive' -a 'make_command' -a 'query'
|
|
if [ $interactive -eq 1 ]
|
|
set fzf_interactive "--bind \"enter:execute:$make_command {}; echo; echo 'Done'; sleep 1\""
|
|
end
|
|
|
|
if test -n "$query"
|
|
set fzf_query "--query=$query"
|
|
end
|
|
set fzf_opts "--read0
|
|
$fzf_query
|
|
$fzf_interactive
|
|
--height 60%
|
|
--layout=reverse
|
|
--border
|
|
--preview-window='right:60%'
|
|
--preview='grep
|
|
--color=always -A 10 -B 1 \^{}: $filename; or echo -GENERATED TARGET-'"
|
|
|
|
set -q FZF_TMUX; or set FZF_TMUX 0
|
|
set -q FZF_TMUX_HEIGHT; or set FZF_TMUX_HEIGHT 60%
|
|
if [ $FZF_TMUX -eq 1 ]
|
|
echo "fzf-tmux -d$FZF_TMUX_HEIGHT $fzf_opts"
|
|
else
|
|
echo "fzf $fzf_opts"
|
|
end
|
|
end
|
|
|
|
if __mm_dependencies
|
|
set custom_filename $filename
|
|
set filename (__mm_get_makefile_name $filename)
|
|
if test -z "$filename"
|
|
echo 'No makefile found in the current working directory'
|
|
else
|
|
set targets (__mm_get_targets $filename)
|
|
if test -n "$targets"
|
|
if test -n "$custom_filename"
|
|
set make_command "make -f $filename"
|
|
else
|
|
set make_command "make"
|
|
end
|
|
# Interactive?
|
|
if test -n "$interactive"; and test $interactive -eq 1
|
|
string join0 -- $targets | eval (__mm_fzf_command $filename 1 $make_command $initial_query)
|
|
else
|
|
string join0 -- $targets | eval (__mm_fzf_command $filename 0 $make_command $initial_query) | read -lz result # print targets as a list, pipe them to fzf, put the chosen command in $result
|
|
set result (string trim -- $result) # Trim newlines and whitespace from the command
|
|
and commandline -- "$make_command $result" # Prepend the make command
|
|
commandline -f repaint # Repaint command line
|
|
end
|
|
else
|
|
echo "No targets found in $filename"
|
|
end
|
|
end
|
|
end
|
|
|
|
end |