bash-completion icon indicating copy to clipboard operation
bash-completion copied to clipboard

Allow make completions of intermediate targets if they are phony

Open slagelwa opened this issue 7 years ago • 4 comments

Commit https://github.com/scop/bash-completion/commit/e0c08321795c8174fa2275d2683c4ffc1b36db5b appears to also fix an issue were intermediate targets were previously being included in completion when they probably shouldn't have. However there are use cases in which you do want to include these -- in my situation I use .SECONDARY to ensure all of my intermediates are not deleted and in then in places use phony targets to build these intermediates. I use these phony targets in situations such as debugging and the like when I want to only build specific targets and use the phony targets to give them easily recognizable names. Perhaps can change the rules slightly so that if they are intermediate targets and they are phony to keep them in the autocomplete?

slagelwa avatar May 30 '18 19:05 slagelwa

Just hit the issue too

If we add .SECONDARY: test.file, only this file is exclude from completion

If we add .SECONDARY: because we want to keep all intermediates files without the need to explicitly specify them, all target are excluded from the completion.

Even if they are are intermediates, is it possible to include them in completion to avoid this behavior @scop ? or at least show all targets if there is no target specified for .SECONDARY ?

Regards,

rockandska avatar Apr 16 '20 19:04 rockandska

Honestly, the uses cases the make completion caters for are way beyond my trivial make uses, and we'd really use a competent maintainer for it here in the project. I mean of course many things are possible, I'm just not qualified to make the call what's good for general use when talking about as intricate cases as this.

scop avatar May 01 '20 12:05 scop

Sorry, I can't contribute a fix but the empty .SECONDARY: special target breaks all completion. Eg:

foo:
  echo bar

# Comment me out to get completion.
.SECONDARY:

If you comment out .SECONDARY:, you get a nice completion for foo. If you uncomment it, no completions are shown.

niedzielski avatar Aug 14 '22 01:08 niedzielski

The issue seems to be these lines:

    /^# * File is an intermediate prerequisite/ {
      s/^.*$//;x;                               # unhold target
      d;                                        # delete line
    }

I don't know why this is special-cased but makefiles with .SECONDARY include this additional line of output. Here's a quick visual diff of with and without a .SECONDARY special target in the same makefile. The command executed to generate this output was grabbed from set -x: make -npq __BASH_MAKE_COMPLETION__=1 -f makefile -C . .DEFAULT.

image

There are no other meaningful differences in the file.

Using set -x, if I take the old command I get no output:

make -npq __BASH_MAKE_COMPLETION__=1 -f makefile -C . .DEFAULT|
sed -ne '    1,/^# * Make data base/           d;        # skip any makefile output
    /^# * Finished Make data base/,/^# * Make data base/{
                                      d;        # skip any makefile output
    }
    /^# * Variables/,/^# * Files/     d;        # skip until files section
    /^# * Not a target/,/^$/          d;        # skip not target blocks
    /^/,/^$/!            d;        # skip anything user dont want

    # The stuff above here describes lines that are not
    #  explicit targets or not targets other than special ones
    # The stuff below here decides whether an explicit target
    #  should be output.

    /^# * File is an intermediate prerequisite/ {
      s/^.*$//;x;                               # unhold target
      d;                                        # delete line
    }

    /^$/ {                                      # end of target block
      x;                                        # unhold target
      /^$/d;                                    # dont print blanks
      s|^\(.\{0\}\)\(.\{0\}[^:/]*/\{0,1\}\)[^:]*:.*$|\2|p;
      d;                                        # hide any bugs
    }

    # This pattern includes a literal tab character as \t is not a portable
    # representation and fails with BSD sed
    /^[^#	:%]\{1,\}:/ {         # found target block
      /^\.PHONY:/                 d;            # special target
      /^\.SUFFIXES:/              d;            # special target
      /^\.DEFAULT:/               d;            # special target
      /^\.PRECIOUS:/              d;            # special target
      /^\.INTERMEDIATE:/          d;            # special target
      /^\.SECONDARY:/             d;            # special target
      /^\.SECONDEXPANSION:/       d;            # special target
      /^\.DELETE_ON_ERROR:/       d;            # special target
      /^\.IGNORE:/                d;            # special target
      /^\.LOW_RESOLUTION_TIME:/   d;            # special target
      /^\.SILENT:/                d;            # special target
      /^\.EXPORT_ALL_VARIABLES:/  d;            # special target
      /^\.NOTPARALLEL:/           d;            # special target
      /^\.ONESHELL:/              d;            # special target
      /^\.POSIX:/                 d;            # special target
      /^\.NOEXPORT:/              d;            # special target
      /^\.MAKE:/                  d;            # special target
      /^[^a-zA-Z0-9]/d;            # convention for hidden tgt
      h;                                        # hold target
      d;                                        # delete line
    }'

When I delete the aforementioned lines from bash-completions/make, it prints the expected target foo:

make -npq __BASH_MAKE_COMPLETION__=1 -f makefile -C . .DEFAULT|
sed -ne '    1,/^# * Make data base/           d;        # skip any makefile output
    /^# * Finished Make data base/,/^# * Make data base/{
                                      d;        # skip any makefile output
    }
    /^# * Variables/,/^# * Files/     d;        # skip until files section
    /^# * Not a target/,/^$/          d;        # skip not target blocks
    /^/,/^$/!            d;        # skip anything user dont want

    # The stuff above here describes lines that are not
    #  explicit targets or not targets other than special ones
    # The stuff below here decides whether an explicit target
    #  should be output.

    /^$/ {                                      # end of target block
      x;                                        # unhold target
      /^$/d;                                    # dont print blanks
      s|^\(.\{0\}\)\(.\{0\}[^:/]*/\{0,1\}\)[^:]*:.*$|\2|p;
      d;                                        # hide any bugs
    }

    # This pattern includes a literal tab character as \t is not a portable
    # representation and fails with BSD sed
    /^[^#	:%]\{1,\}:/ {         # found target block
      /^\.PHONY:/                 d;            # special target
      /^\.SUFFIXES:/              d;            # special target
      /^\.DEFAULT:/               d;            # special target
      /^\.PRECIOUS:/              d;            # special target
      /^\.INTERMEDIATE:/          d;            # special target
      /^\.SECONDARY:/             d;            # special target
      /^\.SECONDEXPANSION:/       d;            # special target
      /^\.DELETE_ON_ERROR:/       d;            # special target
      /^\.IGNORE:/                d;            # special target
      /^\.LOW_RESOLUTION_TIME:/   d;            # special target
      /^\.SILENT:/                d;            # special target
      /^\.EXPORT_ALL_VARIABLES:/  d;            # special target
      /^\.NOTPARALLEL:/           d;            # special target
      /^\.ONESHELL:/              d;            # special target
      /^\.POSIX:/                 d;            # special target
      /^\.NOEXPORT:/              d;            # special target
      /^\.MAKE:/                  d;            # special target
      /^[^a-zA-Z0-9]/d;            # convention for hidden tgt
      h;                                        # hold target
      d;                                        # delete line
    }'

I really don't know why that particular line, # File is an intermediate prerequisite., is special-cased but other lines like # Modification time never checked. are not. I would guess it is safe to be deleted by that comparison but that is a mighty guess.

niedzielski avatar Oct 27 '22 04:10 niedzielski