-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve make target completion #3628
Conversation
- Support completing dynamic make targets. - Support completing make targets when using -C/--directory.
@@ -1,11 +1,19 @@ | |||
# Completions for make | |||
function __fish_complete_make_targets | |||
set directory (echo $argv | string replace -r '^make .*(-C|--directory) ?([^ ]*) .*$' '$2') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary use of echo
- string replace -r '...' '...' -- $argv
.
Also, this does not handle the "--directory=dir" form that at least GNU make also reads.
__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 | ||
make -C $directory -prRn | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($1 !~ "^[#.]") {print $1}}' ^/dev/null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This prints absolutely nothing in my fish clone, because the make -prRn
output is localized - "# „Make“-Datenbank; erstellt am: Wed Dec 7 12:04:14 2016". (Yes, including those annoying quotes).
A possible workaround is to set -lx LC_ALL C
in this function.
GNU make and GNU awk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good find, I found that this might work instead, but not sure if it is safe to filter out all targets with %
. Which one do you prefer the set -lx LC_ALL C
or this one bellow:
make -C source/server -prRn | awk -v RS= -F: '{if ($1 !~ "(^[#.])|%") {print $1}}' | sort
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That latter one (after removing the "-C source/server" part) prints some weird additional stuff in the fish repo. In particular: echo " CPPFLAGS = '-DLOCALEDIR=\"/usr/local/share/locale\" -DPREFIX=L\"/usr/local\" -DDATADIR=L\"/usr/local/share\" -DSYSCONFDIR=L\"/usr/local/etc\" -DBINDIR=L\"/usr/local/bin\" -DDOCDIR=L\"/usr/local/share/doc/fish\" -iquote. -iquote./src/ -DFISH_BUILD_VERSION=\"2.4.0-216-g2db0bbc\"'" ||
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't experience this, but I went with the locale fix instead, since it worked right?
- Remove the unnecessary echo. - Support `-Cdir/path`, `-C dir/path` - Support `--directory=dir/path`, `--directory dir/path`
Since we filter by text that is localized we need to ensure the correct locale is used.
This will need checking against BSD Make as well, as that has caused problems in the past. |
This works for me. Now we need someone to test it with BSD make. |
This is not compatible with BSD make. However, if I do |
@krader1961: So, what does the |
On FreeBSD 12.0:
Interestingly on macOS the system supplied /usr/bin/make appears to be, if not exactly identical to Gnu make, very close to it and has no problem with those options. And Homebrew has a gmake script that does |
Yeah, macOS (edit: Xcode, rather) just ships with an older GPL2 GNU Make rather than BSD make. |
So, what do we do about BSD make? Try to run that command once and check the return status? if make -prRn >/dev/null ^/dev/null
# GNU make
else
# The old stuff
end ? |
So I finally got FreeBSD installed in a virtual machine (was out of space). And can confirm that it is not present, the important part is the I can update the PR with fallback to the old stuff if we can't come up with some better idea. Perhaps try to save the output to a variable directly to prevent running twice? |
Seems like something like this might work in BSD: If anyone have some files they know please try it out:
This was using bash as I didn't know how to switch the stderr and stdout in fish. So we want to pipe the stdout to The flag |
This should work: |
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.
I have made the updates which according to my testing should work for the FreeBSD make. Don't entirely like these long lines, but I run it through the |
Sorry to make your life difficult, @terlar, since I'm excited to see this working. However, on FreeBSD 12.0 (which I don't use other than to test issues with fish on BSD) both On macOS
On Ubuntu 16.04 (Linux) I'm seeing the same problem as on macOS. |
Suppress the output both to stdout and stderr in the check for the option. Also provide the directory (`C`) instead of utilizing an empty Makefile. It seems the empty Makefile (`/dev/null`) returns status code 1 which fails the check and means that it will always be assumed to be FreeBSD.
@krader1961 No worries, this one was my bad. I had two different versions that I played around with, one that I tried inside FreeBSD and one outside (the one I use in my daily use). I didn't notice that I had broken the non-freebsd versions by not suppressing the stdout output as well, which made all those lines end up as completions. Also it seems what I read on some site that you could use However for me it is working on FreeBSD, are you sure those projects you are checking are not using GNU-specific make features? I just did a |
Okay, it's working again on macOS. However while testing on Linux this statement
failed because I had just done I tested on FreeBSD with the iTerm2 project and it correctly enumerates the make targets. Besides changing the BSD versus GNU make test the one other thing that would be nice is to have completions for the |
We don't want to run the default make target when testing for the command.
I wonder how we should do with The tricky thing would be on BSD, let's say you have |
I was under the impression that BSD make's syntax is a subset of the GNU one. Is that not the case? Anyway, what might work is to call whatever make is used on the commandline (via a wrapper function, not E.g. if I enter (Theoretically it would even be possible to rewrite the commandline to gmake in that case, but that sounds weird) |
The solution for |
I am not sure if the code is as good as it can be, please let me know if
there are any potential bugs that you spot straight away.
I have been using Makefile's quite extensively recently and missed the
completion of dynamic targets and also when I run tasks for subfolders
via
make -C
.This pull-request solves these two issues, first by getting the make
targets by querying the make database. This solution is based on
the ideas presented here.
This also wraps the call to
__fish_print_make_targets
and figures outif the commandline contains any
-C
or--directory
, if that is thecase the directory is assigned to a variable and then passed along to
the function.
I have introduced a new argument to the function
__fish_print_make_targets
which is the directory to look for theMakefile, it will default to
.
if none provided.Potential issues (or likely) issues, are that we now explicitly use
the
make
command and don't parse these files and thus if the commandwould be something else it would not work. Personally I have only had
the use-case with
make
though.TLDR;
-C
/--directory
.