fish-shell/share/functions/__fish_parse_configure.fish
Mahmoud Al-Qudsi 9d9afd8264 Speed up ./configure completion by not running ./configure --help
Instead, attempt to extract the message that _would_ be displayed on
execution of `./configure --help` by relying on some markers present in
autoconf-generated configure files.

As measured with 'hyperfine' on a laptop running in reduced frequency
power savings mode, `fish -c "__fish_parse_configure ./configure"`
runtime dropped from ~1.25s to ~0.8ms, which is inline with the
previously observed ~350ms execution time for `./configure --help`.
fish's own startup time is approximately 75ms before parsing begins.

Still very slow, but much better.
2018-04-18 15:40:52 -05:00

66 lines
2.3 KiB
Fish

function __fish_parse_configure
if test (count $argv) -ne 1
echo "Usage: parse_configure path/to/configure" 1>&2
return 1
end
# `complete` parses `./configure` as `configure` so we have to handle all paths, not just ./
if not test -x $argv[1]
printf "Cannot find or execute '%s'\n" $argv[1] 1>&2
return 1
end
# Must support output along the lines of
# -h, --help display this help and exit
# --help=short display options specific to this package
# --help=recursive display the short help of all the included packages
# -V, --version display version information and exit
# -q, --quiet, --silent do not print `checking ...' messages
set -l next_line
set -l line
set -l buffer
# eval $argv[1] --help 2>/dev/null |
# Just fish's `./configure --help` takes ~350ms to run, before parsing
# The following chain attempts to extract the help message:
cat $argv[1] | tr \n \u0e | sed -n 's/.*Report the --help message\(.*\?\)ac_status.*/\1/; s/ac_status.*//p' | tr \u0e \n |
while test "$next_line" != "" || read -lL next_line
# In autoconfigure scripts, the first column wraps at 26 chars
# echo next_line: $next_line
# echo old_line: $line
if test "$line" = ""
set line $next_line
set next_line "" # mark it as consumed
continue
else if string match -qr '^( |\t){2,}[^-]\S*' -- $next_line
# echo "continuation line found. Old value of line: " \"$line\"
set line "$line "(string trim $next_line)
set next_line "" # mark it as consumed
continue
end
# echo line: $line
# Search for one or more strings starting with `-` separated by commas
if string replace -fr '^\s+(-.*?)\s+([^\s\-].*)' '$1\n$2' -- $line | read -lL opts description
for opt in (string split -n , -- $opts | string trim)
if string match -qr -- '--.*=\[.*\]' $opt
# --option=[OPTIONAL_VALUE]
string replace -r -- '(--.*)=.*' '$1' $opt | read opt
else if string match -qr -- '--.*=[A-Z]+' $opt
# --option=CLASS_OF_VALUE (eg FILE or DIR)
string replace -r -- '(--.*)=.*' '$1' $opt | read opt
else if string match -qr -- '--.*=\S+' $opt
# --option=literal_value, leave as-is
else if string match -qr -- '-[^-]\b' $opt
# short option, leave as-is
end
echo "$opt"\t"$description" # parsed by `complete` as value and description
end
end
set line ""
end
end