How to Autocomplete a Bash Commandline with File Paths

How to autocomplete a bash commandline with file paths?

To auto complete file paths

Substitute

complete -F __my_app_autocomplete my_app

with

complete -o filenames -F __my_app_autocomplete my_app

Here you can find all the compgen options explained:

https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html

Custom Bash Autocomplete with File Path Completion

I think -o default (without -o filenames) should work for you. According to the manual:

  • 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.
  • filenames
    Tell readline that the compspec generates filenames, so it can perform any filename-specific processing (like adding a slash to directory
    names, quoting special characters, or suppressing trailing spaces). Intended to be used with shell functions.

(Also see 'complete -d -o default cd' issue for the difference between -o default and -o bashdefault.)

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

Bash Completion script to complete file path after certain arguments options

You can use compgen -f to complete filenames, like this:

if [[ ${prev} == --*file ]] || [[ ${prev} == --out ]]; then
COMPREPLY=( $(compgen -f -- ${cur}) )
elif ...

However, compgen -f isn't great at completing filenames because it doesn't honour spaces in filenames.

A better way is to use the _filedir function available in bash-completion-lib. It might already be available on your system (type: declare -f _filedir to check).

Using _filedir, your completion function becomes:

if [[ ${prev} == --*file ]] || [[ ${prev} == --out ]]; then
_filedir
elif ...

List directories at a specific path as autocomplete options for a bash script?

I think that you would need to fill the COMPREPLY array. I think this could work:

_repos()
{
local cur;
local base=~/source/repos/
_get_comp_words_by_ref cur;
cur="$base$cur"
_filedir
COMPREPLY=("${COMPREPLY[@]#$base}")
} && complete -o nospace -F _repos repos

If you want to use the -C option, you can use this method below. (Note that I have not evaluated it for file-names containing special characters.)

_repos()
{
( cd ~/source/repos; printf "%s\n" "$2"* )
} && complete -o nospace -C _repos repos

find based filename autocomplete in Bash script

You should take a look at this introduction to bash completion. Briefly, bash has a system for configuring and extending tab completion. Other shells do this, too, and each one has a different way to set it up. Using this system it is not necessary to do everything yourself and adding custom argument completion to a command is relatively easy.



Related Topics



Leave a reply



Submit