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

complete -f doesn't seem to work #112

Closed
ridiculousfish opened this Issue Jun 11, 2012 · 15 comments

Comments

Projects
None yet
8 participants
@ridiculousfish
Member

ridiculousfish commented Jun 11, 2012

The -f flag doesn't seem to work. It's supposed to suppress completing files, but it never seems to do it.

@maxfl

This comment has been minimized.

Show comment
Hide comment
@maxfl

maxfl Jun 13, 2012

Contributor

there are two notes here:

  1. -f works if there are other completions specified
    complete -c ttt -f #doesn't prevent files from completing if it is the only command
    complete -c ttt -a 'a1 a2' # after this line '-f' works
  2. -f key works globally for the command. Not for each option (unfortunately).
Contributor

maxfl commented Jun 13, 2012

there are two notes here:

  1. -f works if there are other completions specified
    complete -c ttt -f #doesn't prevent files from completing if it is the only command
    complete -c ttt -a 'a1 a2' # after this line '-f' works
  2. -f key works globally for the command. Not for each option (unfortunately).
@floam

This comment has been minimized.

Show comment
Hide comment
@floam

floam Aug 18, 2016

Member

This one is quite annoying.

Member

floam commented Aug 18, 2016

This one is quite annoying.

@alphapapa

This comment has been minimized.

Show comment
Hide comment
@alphapapa

alphapapa Sep 21, 2016

Yeah, it's a bit annoying all right. :) I have a command that takes arguments from a list in a file, which complete makes very easy. But if I type one that doesn't match anything in the list, and there's a file in the current directory that what I typed completes to, it completes it as if that file were a choice in my list file. D:

I'm not much with C++, but what about this line:

https://github.com/fish-shell/fish-shell/blob/master/src/complete.cpp#L966

Is that inverting the option, causing it to complete files when it shouldn't?

alphapapa commented Sep 21, 2016

Yeah, it's a bit annoying all right. :) I have a command that takes arguments from a list in a file, which complete makes very easy. But if I type one that doesn't match anything in the list, and there's a file in the current directory that what I typed completes to, it completes it as if that file were a choice in my list file. D:

I'm not much with C++, but what about this line:

https://github.com/fish-shell/fish-shell/blob/master/src/complete.cpp#L966

Is that inverting the option, causing it to complete files when it shouldn't?

@radomirbosak

This comment has been minimized.

Show comment
Hide comment
@radomirbosak

radomirbosak Dec 28, 2016

Contributor

@alphapapa I don't think that line is inverting the option. More likely the problem lies in that use_files gets initialized to 1 in src/complete.cpp:862:

bool use_common = 1, use_files = 1;

but since there are no matching completions, the lines with

if (o->result_mode & NO_FILES) use_files = false;

never get executed.

Question regarding the -f switch: To what is it tied? To specific (short/long) options? To command itself? To options when some conditions are fulfilled?

In code the flag controlling this seems to be tied to options - it resides in result_mode variable of the complete_entry_opt_t structure:

/// Struct describing a completion option entry.
///
/// If option is empty, the comp field must not be empty and contains a list of arguments to the
/// command.
///
/// The type field determines how the option is to be interpreted: either empty (args_only) or
/// short, single-long ("old") or double-long ("GNU"). An invariant is that the option is empty if
/// and only if the type is args_only.
///
/// If option is non-empty, it specifies a switch for the command. If \c comp is also not empty, it
/// contains a list of non-switch arguments that may only follow directly after the specified
/// switch.
typedef struct complete_entry_opt_t {
    // Text of the option (like 'foo').
    wcstring option;
    // Type of the option: args-oly, short, single_long, or double_long.
    complete_option_type_t type;
    // Arguments to the option.
    wcstring comp;
    // Description of the completion.
    wcstring desc;
    // Condition under which to use the option.
    wcstring condition;
    // Must be one of the values SHARED, NO_FILES, NO_COMMON, EXCLUSIVE, and determines how
    // completions should be performed on the argument after the switch.
    int result_mode;
    // Completion flags.
    complete_flags_t flags;

    const wcstring localized_desc() const { return C_(desc); }

    size_t expected_dash_count() const {
        switch (this->type) {
            case option_type_args_only:
                return 0;
            case option_type_short:
            case option_type_single_long:
                return 1;
            case option_type_double_long:
                return 2;
        }
        DIE("unreachable");
    }

} complete_entry_opt_t;
...

where NO_FILES is a constant defined in complete.h:

...
/// Use all completions.
#define SHARED 0
/// Do not use file completion.
#define NO_FILES 1
/// Require a parameter after completion.
#define NO_COMMON 2
/// Only use the argument list specifies with completion after option. This is the same as (NO_FILES
/// | NO_COMMON).
#define EXCLUSIVE 3
...
Contributor

radomirbosak commented Dec 28, 2016

@alphapapa I don't think that line is inverting the option. More likely the problem lies in that use_files gets initialized to 1 in src/complete.cpp:862:

bool use_common = 1, use_files = 1;

but since there are no matching completions, the lines with

if (o->result_mode & NO_FILES) use_files = false;

never get executed.

Question regarding the -f switch: To what is it tied? To specific (short/long) options? To command itself? To options when some conditions are fulfilled?

In code the flag controlling this seems to be tied to options - it resides in result_mode variable of the complete_entry_opt_t structure:

/// Struct describing a completion option entry.
///
/// If option is empty, the comp field must not be empty and contains a list of arguments to the
/// command.
///
/// The type field determines how the option is to be interpreted: either empty (args_only) or
/// short, single-long ("old") or double-long ("GNU"). An invariant is that the option is empty if
/// and only if the type is args_only.
///
/// If option is non-empty, it specifies a switch for the command. If \c comp is also not empty, it
/// contains a list of non-switch arguments that may only follow directly after the specified
/// switch.
typedef struct complete_entry_opt_t {
    // Text of the option (like 'foo').
    wcstring option;
    // Type of the option: args-oly, short, single_long, or double_long.
    complete_option_type_t type;
    // Arguments to the option.
    wcstring comp;
    // Description of the completion.
    wcstring desc;
    // Condition under which to use the option.
    wcstring condition;
    // Must be one of the values SHARED, NO_FILES, NO_COMMON, EXCLUSIVE, and determines how
    // completions should be performed on the argument after the switch.
    int result_mode;
    // Completion flags.
    complete_flags_t flags;

    const wcstring localized_desc() const { return C_(desc); }

    size_t expected_dash_count() const {
        switch (this->type) {
            case option_type_args_only:
                return 0;
            case option_type_short:
            case option_type_single_long:
                return 1;
            case option_type_double_long:
                return 2;
        }
        DIE("unreachable");
    }

} complete_entry_opt_t;
...

where NO_FILES is a constant defined in complete.h:

...
/// Use all completions.
#define SHARED 0
/// Do not use file completion.
#define NO_FILES 1
/// Require a parameter after completion.
#define NO_COMMON 2
/// Only use the argument list specifies with completion after option. This is the same as (NO_FILES
/// | NO_COMMON).
#define EXCLUSIVE 3
...
@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Dec 29, 2016

Member

Question regarding the -f switch: To what is it tied? To specific (short/long) options? To command itself?

A complete command specifies an option (--backup) and/or a set of arguments (none existing simple). When completing, we try to complete the argument if the previous parameter matches the option. We also try to complete the option itself.

If we find a matching completion of the option OR its argument, and that completion has the NO_FILES flag, then we don't do file completion for that parameter.

Member

ridiculousfish commented Dec 29, 2016

Question regarding the -f switch: To what is it tied? To specific (short/long) options? To command itself?

A complete command specifies an option (--backup) and/or a set of arguments (none existing simple). When completing, we try to complete the argument if the previous parameter matches the option. We also try to complete the option itself.

If we find a matching completion of the option OR its argument, and that completion has the NO_FILES flag, then we don't do file completion for that parameter.

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho May 5, 2017

Member

Ummm.... this part might have something to do with it:

// If we have found no command specific completions at all, fall back to using
// file completions.
if (completer.empty()) do_file = true;
Member

faho commented May 5, 2017

Ummm.... this part might have something to do with it:

// If we have found no command specific completions at all, fall back to using
// file completions.
if (completer.empty()) do_file = true;

faho added a commit to faho/fish-shell that referenced this issue May 5, 2017

Don't complete files if no completion can be found
This essentially breaks the "--no-files" flag to `complete`.

Some commands simply do _not_ take files.

Fixes fish-shell#112.
@alphapapa

This comment has been minimized.

Show comment
Hide comment
@alphapapa

alphapapa May 5, 2017

Wow, that was easy. Thanks @faho! Been bugging me for a long time. :)

However, I'm not sure how a command completion would request filename completion now, since there doesn't seem to be an option to complete that means "try to complete with filenames".

alphapapa commented May 5, 2017

Wow, that was easy. Thanks @faho! Been bugging me for a long time. :)

However, I'm not sure how a command completion would request filename completion now, since there doesn't seem to be an option to complete that means "try to complete with filenames".

faho added a commit to faho/fish-shell that referenced this issue May 11, 2017

Don't complete files if no completion can be found
This essentially breaks the "--no-files" flag to `complete`.

Some commands simply do _not_ take files.

Fixes fish-shell#112.

@faho faho closed this in a3a0692 May 21, 2017

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho May 21, 2017

Member

I've now merged this fix (I love it when deleting code is all you need).

This is not in 2.6.0 since it needs a bunch of testing.

Member

faho commented May 21, 2017

I've now merged this fix (I love it when deleting code is all you need).

This is not in 2.6.0 since it needs a bunch of testing.

@faho faho modified the milestones: next-minor, fish-future May 21, 2017

@krackers

This comment has been minimized.

Show comment
Hide comment
@krackers

krackers Oct 16, 2017

@faho When I tried manually cherrypicking this patch into 2.6.0 I found that one issue was that cd no longer autocompleted with the directories.

krackers commented Oct 16, 2017

@faho When I tried manually cherrypicking this patch into 2.6.0 I found that one issue was that cd no longer autocompleted with the directories.

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho Oct 16, 2017

Member

@krackers: You also need to cherrypick 4afd418, since the cd.fish completion script erroneously used "-f" (via "-x"). See #4061.

Also, IIRC, there were a bunch more scripts that did that - at least pacman (908063d).

Member

faho commented Oct 16, 2017

@krackers: You also need to cherrypick 4afd418, since the cd.fish completion script erroneously used "-f" (via "-x"). See #4061.

Also, IIRC, there were a bunch more scripts that did that - at least pacman (908063d).

@wwwjfy

This comment has been minimized.

Show comment
Hide comment
@wwwjfy

wwwjfy Nov 28, 2017

Contributor

@faho +1 for @alphapapa 's comment

However, I'm not sure how a command completion would request filename completion now, since there doesn't seem to be an option to complete that means "try to complete with filenames".

I think filename is a quite common argument for cli utils, without defaulting to filename completion, some of utils don't auto-complete any more. I don't want (and I don't think it should be necessary) to write completion for each util.

I'd certainly hope there is a workaround. Thanks!

Contributor

wwwjfy commented Nov 28, 2017

@faho +1 for @alphapapa 's comment

However, I'm not sure how a command completion would request filename completion now, since there doesn't seem to be an option to complete that means "try to complete with filenames".

I think filename is a quite common argument for cli utils, without defaulting to filename completion, some of utils don't auto-complete any more. I don't want (and I don't think it should be necessary) to write completion for each util.

I'd certainly hope there is a workaround. Thanks!

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho Nov 28, 2017

Member

I'd certainly hope there is a workaround. Thanks!

@wwwjfy: Just don't use "-f". Any command that doesn't explicitly have a completion that uses "-f" (or "-x") will get files. If the completion has a "-n" condition it also has to be true to suppress files. Obviously it's possible that there might be bugs, but e.g. for the git completions it works.

Member

faho commented Nov 28, 2017

I'd certainly hope there is a workaround. Thanks!

@wwwjfy: Just don't use "-f". Any command that doesn't explicitly have a completion that uses "-f" (or "-x") will get files. If the completion has a "-n" condition it also has to be true to suppress files. Obviously it's possible that there might be bugs, but e.g. for the git completions it works.

@wwwjfy

This comment has been minimized.

Show comment
Hide comment
@wwwjfy

wwwjfy Nov 28, 2017

Contributor

@faho Thanks for prompt responses.

Then a few completions have issues. I met two commands with the completion issues:

  1. patch -i <filename>
  2. pip -r <filename>

They work before. I'll take a look at the completion files to see where the problem is.

Contributor

wwwjfy commented Nov 28, 2017

@faho Thanks for prompt responses.

Then a few completions have issues. I met two commands with the completion issues:

  1. patch -i <filename>
  2. pip -r <filename>

They work before. I'll take a look at the completion files to see where the problem is.

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho Nov 28, 2017

Member

patch -i

Yep:

complete -c patch -s i -l input -r -f -d "Read the patch from patchfile"

has a "-f". I'd love a PR for this that also checks the other options.

pip -r

This uses the upstream completions (which just map it to bash's completions):

$ pip completion --fish
function __fish_complete_pip
    set -lx COMP_WORDS (commandline -o) ""
    set -lx COMP_CWORD (math (contains -i -- (commandline -t) $COMP_WORDS)-1)
    set -lx PIP_AUTO_COMPLETE 1
    string split \  -- (eval $COMP_WORDS[1])
end
complete -fa "(__fish_complete_pip)" -c pip
# pip fish completion end

Also has a "-f". This one would have to be reported to the pip people (piple?).

Member

faho commented Nov 28, 2017

patch -i

Yep:

complete -c patch -s i -l input -r -f -d "Read the patch from patchfile"

has a "-f". I'd love a PR for this that also checks the other options.

pip -r

This uses the upstream completions (which just map it to bash's completions):

$ pip completion --fish
function __fish_complete_pip
    set -lx COMP_WORDS (commandline -o) ""
    set -lx COMP_CWORD (math (contains -i -- (commandline -t) $COMP_WORDS)-1)
    set -lx PIP_AUTO_COMPLETE 1
    string split \  -- (eval $COMP_WORDS[1])
end
complete -fa "(__fish_complete_pip)" -c pip
# pip fish completion end

Also has a "-f". This one would have to be reported to the pip people (piple?).

@wwwjfy

This comment has been minimized.

Show comment
Hide comment
@wwwjfy

wwwjfy Nov 29, 2017

Contributor

@faho Thanks for your help. I've created a PR #4560.

Contributor

wwwjfy commented Nov 29, 2017

@faho Thanks for your help. I've created a PR #4560.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment