3

I have env variable $SCRIPT. Normaly I can use autocomplete

vim $SC<tab>

and completion works as expected. On some systems it does not work. I have bash completion loaded, but completion in these cases works only with directories (cd $SCRIPT_DIREC<tab> is working).

Mostly I have problem with bash 4.2.

What shopt can enable it?

EDIT: I have compared my shopt settings with Bash 4.3 where it's working and Bash 4.2 (Ubuntu server 12.04) where is NOT working, there were few differences (most of them 4.3 specific), set the rest the same, but nothing worked.

  • I just end up with upgrading bash-completion to 2.0-1 (original version was 1.3-1). – pevik Jul 11 '14 at 7:06
  • shopt -s direxpand is the correct answer to solve the problem (source: askubuntu.com/questions/70750/…). At least on bash 5.0 and bash-completion 2.8 on openSUSE. – pevik Mar 21 at 11:42
0

One way is, you simply can put its alias as

alias Script="<Your $Script Here>"

in your users' .profile in /home/user/.profile and then source it with:

$ . profile

Then check to see if it autocompletes.

  • This answer could be improved with some more explanation or information (e.g., documentation that supports your suggestion). – HalosGhost Jul 10 '14 at 5:11
  • alias Script="<Your $Script here>" -- this should do your thing. – Keyshov Borate Jul 10 '14 at 6:01
  • Edit your post to add extra information that's relevant to the OP; comments should remain mostly for clarification. – HalosGhost Jul 10 '14 at 6:02
  • This is not working :-(. – pevik Jul 10 '14 at 11:17
0

The issue is specifically that shell builtins work to <tab> expand parameter names, but external commands do not. this is why cd works. echo, read, and any other builtin continue to work like OP expects.

nothing to do with shopts.

It's in the bash_completion library (/etc/bash_completion in my 12.04.4 system). Something in release 1.3 exists which causes this failure situation. somewhere at-or-before 1.99 it was fixed.

The bash_completion lib will automatically source ~/.bash_completion if it exists, so i suggest creating such a file with the following contents to overload the function defs in the stock 12.04.4 lib which don't work for you. i did some minor testing, but i'm not affected by this situation in any of the machines i use so caveat emptor.

# following functions are direct copy/pastes from
# bash_completion RELEASE: 1.99
# overloading `_longopt()' and adding `_variables()' and `_init_completion()'
# appears to be all that is needed to correct this.
# 
# http://unix.stackexchange.com/questions/126300/bash-autocomplete-variables-for-other-commands-than-cd

_init_completion()
{
    local exclude= flag outx errx inx OPTIND=1
    while getopts "n:e:o:i:s" flag "$@"; do
        case $flag in
            n) exclude+=$OPTARG ;;
            e) errx=$OPTARG ;;
            o) outx=$OPTARG ;;
            i) inx=$OPTARG ;;
            s) split=false ; exclude+== ;;
        esac
    done
    # For some reason completion functions are not invoked at all by
    # bash (at least as of 4.1.7) after the command line contains an
    # ampersand so we don't get a chance to deal with redirections
    # containing them, but if we did, hopefully the below would also
    # do the right thing with them...
    COMPREPLY=()
    local redir="@(?([0-9])<|?([0-9&])>?(>)|>&)"
    _get_comp_words_by_ref -n "$exclude<>&" cur prev words cword
    # Complete variable names.
    _variables && return 1
    # Complete on files if current is a redirect possibly followed by a
    # filename, e.g. ">foo", or previous is a "bare" redirect, e.g. ">".
    if [[ $cur == $redir* || $prev == $redir ]]; then
        local xspec
        case $cur in
            2'>'*) xspec=$errx ;;
            *'>'*) xspec=$outx ;;
            *'<'*) xspec=$inx ;;
            *)
                case $prev in
                    2'>'*) xspec=$errx ;;
                    *'>'*) xspec=$outx ;;
                    *'<'*) xspec=$inx ;;
                esac
                ;;
        esac
        cur="${cur##$redir}"
        _filedir $xspec
        return 1  
    fi
    # Remove all redirections so completions don't have to deal with them.
    local i skip  
    for (( i=1; i < ${#words[@]}; )); do
        if [[ ${words[i]} == $redir* ]]; then
            # If "bare" redirect, remove also the next word (skip=2).
            [[ ${words[i]} == $redir ]] && skip=2 || skip=1
            words=( "${words[@]:0:i}" "${words[@]:i+skip}" )
            [[ $i -le $cword ]] && cword=$(( cword - skip ))
        else
            i=$(( ++i ))
        fi
    done
    [[ $cword -eq 0 ]] && return 1
    prev=${words[cword-1]}
    [[ ${split-} ]] && _split_longopt && split=true
    return 0
}

_variables()
{
    if [[ $cur =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]; then
        [[ $cur == *{* ]] && local suffix=} || local suffix=
        COMPREPLY+=( $( compgen -P ${BASH_REMATCH[1]} -S "$suffix" -v -- \
            "${BASH_REMATCH[2]}" ) )
        return 0  
    fi
    return 1
}

_longopt()
{   
    local cur prev words cword split
    _init_completion -s || return
    case "${prev,,}" in
        --help|--usage|--version)
            return 0
            ;;
        --*dir*)
            _filedir -d
            return 0
            ;;
        --*file*|--*path*)
            _filedir
            return 0
            ;;
        --+([-a-z0-9_]))
            local argtype=$( $1 --help 2>&1 | sed -ne \
                "s|.*$prev\[\{0,1\}=[<[]\{0,1\}\([-A-Za-z0-9_]\{1,\}\).*|\1|p" )
            case ${argtype,,} in
                *dir*)
                    _filedir -d
                    return 0
                    ;;
                *file*|*path*)
                    _filedir
                    return 0
                    ;;
            esac
            ;;
    esac
    $split && return 0
    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W "$( $1 --help 2>&1 | \
            sed -ne 's/.*\(--[-A-Za-z0-9]\{1,\}=\{0,1\}\).*/\1/p' | sort -u )" \
            -- "$cur" ) )
        [[ $COMPREPLY == *= ]] && compopt -o nospace
    elif [[ "$1" == @(mk|rm)dir ]]; then
        _filedir -d
    else
        _filedir
    fi
}
  • Functions were loaded on commands like mv, but still not working with vim. So I "solved" the problem by upgrading bash-completion to version 2.0-1. Thanks for your tips, I didn't realized that bash-completion allow users related script. – pevik Jul 11 '14 at 7:04
  • yeah, there're hooks for it in the bash.c whatnot that you can't change (how COMPREPLY is handled), builtins you could overload with functions (compgen, complete), and then the arbitrarily customizable userland stuff in the bash_completion shell lib. – jrrs Jul 11 '14 at 19:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.