Bash Will Not Auto-Complete (Tab) with Files

Bash will not auto-complete (Tab) with files

The third party "bash_completion" package (not to be confused with bash or its native completion) can sometimes be hard to predict.

  1. Some commands are specifically set up to not never complete files, like cd
  2. Some commands will refuse to complete certain filenames, because bash_completion doesn't realize the program handles them, like mplayer.
  3. Some commands are just buggy, especially when paths contain spaces and other characters, like for scp.

If you're ever in a situation where bash_completion isn't being helpful, you can use M-/ (aka Alt + /) to use bash's native filename completion instead.

If a command is frequently giving you trouble, you can disable bash_completion for this command using complete -r thatcommand at the end of your .bashrc.

Tab completion ignoring some files in Bash/Debian

The bash-completion package uses the function _filedir_xspec to complete vim. That function in general completes filenames, but excludes certain patterns depending on which command it is completing.

For vim, the exclusion pattern starts like this:

_install_xspec '*.@([ao]|so|so.!(conf|*/*) ...

I.e., among other things, files ending in .a should be ignored. The thinking behind that is probably that these are often created as backup copies and you probably don't want to edit them.

If you want to override this behaviour, you can add your own completions into ~/.bash_completion; for example, to get vim to complete on all filenames, use this:

complete -f vim

which will make vim tab completion default to the built-in file completion bevahiour.

Terminals Tab key does not autocomplete, instead attempts to run a script of mine

I found the solution. Quite a rookie derp now that I think about it.

In my ~/.bash_aliases I had an alias that was written like so:

alias test="./run_proxy_tests.sh -p ~/workspace/project/project-proxy.linux.x86_64 -l 1"

I discovered through process of elimination that if I commented it out. The problem disappeared.

But why did this happen? Why did pressing the tab key run an alias. And only when running the git command.

Well I looked at the git repository for git, in the "git-completion.bash" file. And found this:

    while test -n "$rest"; do

No wonder it ran 3 times.

Moral of the story:
Be more explicit when naming aliases

reference:
https://github.com/git/git/blob/master/contrib/completion/git-completion.bash#L132

Do not autocomplete certain extensions from file names in shell for vim

On Ubuntu, if I install the package bash-completion, I can see its contents with:

$ dpkg -L bash-completion

In the output, /etc/bash_completion is listed.

Inside, the following command is written:

. /usr/share/bash-completion/bash_completion

It sources the file /usr/share/bash-completion/bash_completion.

The location of these files vary from an OS to another:

Note: I use a Mac, and on macOS the bash-completion file is stored (by default) in /usr/local/etc/bash_completion, and the bash_completion.d directory is in /usr/local/etc/bash_completion.d

On my system, /usr/share/bash-completion/bash_completion contains this line:

_install_xspec '*.@(o|so|so.!(conf|*/*)|a|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite

I think this line is responsible for the behavior you're observing.

If you want to tweak it to make bash exclude the foo and bar extensions when completing a filename after the $ vim command, you could try the following procedure.

  1. Create the file ~/.bash_completion

Inside the latter, write:

for bcfile in ~/.bash_completion.d/* ; do
[ -f "$bcfile" ] && . $bcfile
done

  1. Create the ~/.bash_completion.d/ directory.

  2. Inside this directory, create a vim file.

Inside the latter, write:

complete -f -X '*.@(o|so|so.!(conf|*/*)|a|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class|foo|bar)' vi vim gvim rvim view rview rgvim rgview gview

complete is a bash builtin command which allows you to specify how arguments to a command name should be completed.

-f is a shorthand for -A file, which specifies to bash that you want to see only filenames in your suggestions.

-X excludes anything which matches the following pattern.

Note that I have merely copied the pattern used in /usr/share/bash-completion/bash_completion, and added the foo and bar extensions:

*.@(o|so|so.!(conf|*/*)|a|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class|foo|bar)
^^^^^^^

It's up to you to modify the pattern to exclude the real extensions you want to avoid.

The names after the pattern tell bash for which commands should it exclude these extensions.

In the previous command, they are:

vi vim gvim rvim view rview rgvim rgview gview

All of them invoke a version of Vi or Vim. You could add other editor names at the end.

For more information see:

$ man bash

Look for the READLINE section and the Programmable Completion subsection, as well as the description of the complete builtin in the SHELL BUILTIN COMMANDS section.

See also An introduction to bash completion part 1 and An introduction to bash completion part 2.

How to autocomplete files under specific directory?

Here's a simple example:

_memo()
{
local MEMO_DIR=$HOME/memo
local cmd=$1 cur=$2 pre=$3
local arr i file

arr=( $( cd "$MEMO_DIR" && compgen -f -- "$cur" ) )
COMPREPLY=()
for ((i = 0; i < ${#arr[@]}; ++i)); do
file=${arr[i]}
if [[ -d $MEMO_DIR/$file ]]; then
file=$file/
fi
COMPREPLY[i]=$file
done
}
complete -F _memo -o nospace memo

auto-complete

How can I get auto-completion in bash for file-names with spaces, too?

You know, I'd swear this used to work and just seemed to stop working recently (last few months). Don't know that any OS X updates updated bash, but whatever.

Anyway, putting "complete -o nospace -d cd" into .bashrc (or whatever rc file you're using) seems to give the desired behavior.

How to configure bash autocomplete for file search and custom search?

You can use complete's -o default option (Usually I'd use both -o default and -o bashdefault):

complete -o default -F _test_complete remote

According to man bash:

  • bashdefault

    Perform the rest of the default bash completions if the compspec generates no matches.

  • default

    Use readline's default filename completion if the compspec generates no matches.

Git auto completion behaving strangely

Check first if the issue persists with Git 2.24, considering 2.23 and 2.24 have worked on the completion script.

Check also if your Git bash completion is correctly installed.

I added in the comments:

There a possibility for your .bashrc/.profile to have somehow an error which would manifest when running that completion bash script.

You need to test it with a minimal (almost empty) content for your .bashrc/.profile ("empty", beside defining at least the $PATH)

The OP alamoot confirms:

Great call!

In my ~/.bash_profile I was calling a script which was setting a custom $BASH_COMPLETION and $BASH_COMPLETION_DIR.

This custom script was part of and old "system setup" I don't need no more.

So taking it out I have got git completion working again.



Related Topics



Leave a reply



Submit