Skip to content
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
Closed

complete -f doesn't seem to work #112

ridiculousfish opened this issue Jun 11, 2012 · 15 comments
Assignees
Labels
bug Something that's not working as intended completions
Milestone

Comments

@ridiculousfish
Copy link
Member

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

@maxfl
Copy link
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
Copy link
Member

floam commented Aug 18, 2016

This one is quite annoying.

@alphapapa
Copy link

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
Copy link
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
...

@ridiculousfish
Copy link
Member Author

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
Copy link
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
This essentially breaks the "--no-files" flag to `complete`.

Some commands simply do _not_ take files.

Fixes fish-shell#112.
@alphapapa
Copy link

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
This essentially breaks the "--no-files" flag to `complete`.

Some commands simply do _not_ take files.

Fixes fish-shell#112.
@faho faho closed this as completed in a3a0692 May 21, 2017
@faho
Copy link
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
Copy link

@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
Copy link
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
Copy link
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
Copy link
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
Copy link
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
Copy link
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
Copy link
Contributor

wwwjfy commented Nov 29, 2017

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something that's not working as intended completions
Projects
None yet
Development

No branches or pull requests

8 participants