tab completion skips files when path begins with ~

Bug #1290572 reported by Steve Beattie
22
This bug affects 5 people
Affects Status Importance Assigned to Milestone
bash-completion (Ubuntu)
Confirmed
Undecided
Unassigned

Bug Description

Tab completion does not list files when the path begins with ~, like so:

  ubuntu@trusty-i386:~$ cd ~ && ls -l testdir
  total 8
  drwxrwxr-x 2 ubuntu ubuntu 4096 Mar 10 13:15 dir1
  drwxrwxr-x 2 ubuntu ubuntu 4096 Mar 10 13:15 Dir2
  -rw-rw-r-- 1 ubuntu ubuntu 0 Mar 10 13:15 file
  ubuntu@trusty-i386:~$ ls -l testdir/<tab><tab>
  dir1/ Dir2/ file
  ubuntu@trusty-i386:~$ ls -l ~/testdir/<tab><tab>
  dir1/ Dir2/

For the record:

  ubuntu@trusty-i386:~$ compopt ls
  compopt +o bashdefault +o default +o dirnames +o filenames +o nospace +o plusdirs ls
  ubuntu@trusty-i386:~$ complete -p ls
  complete -F _longopt ls
  ubuntu@trusty-i386:~$ alias ls
  alias ls='ls --color=auto'

I can't tell if this is the same bug as bug 1288031, as I'm only seeing the auto-completion of only directory names when paths begin with ~, not for all paths.

ProblemType: Bug
DistroRelease: Ubuntu 14.04
Package: bash-completion 1:2.1-2ubuntu2
ProcVersionSignature: Ubuntu 3.13.0-16.36-generic 3.13.5
Uname: Linux 3.13.0-16-generic i686
ApportVersion: 2.13.3-0ubuntu1
Architecture: i386
Date: Mon Mar 10 14:33:50 2014
InstallationDate: Installed on 2014-02-27 (11 days ago)
InstallationMedia: Ubuntu 14.04 LTS "Trusty Tahr" - Alpha i386 (20140224)
PackageArchitecture: all
ProcEnviron:
 TERM=screen
 PATH=(custom, no user)
 XDG_RUNTIME_DIR=<set>
 LANG=en_US.UTF-8
 SHELL=/bin/bash
SourcePackage: bash-completion
UpgradeStatus: No upgrade log present (probably fresh install)

ubuntu@trusty-i386:~$ apt-cache policy bash
bash:
  Installed: 4.3-2ubuntu1
  Candidate: 4.3-2ubuntu1
  Version table:
 *** 4.3-2ubuntu1 0
        500 http://ubuntu-mirror/ubuntu/ trusty/main i386 Packages
        100 /var/lib/dpkg/status

Related branches

Revision history for this message
Steve Beattie (sbeattie) wrote :
description: updated
Revision history for this message
Steve Beattie (sbeattie) wrote :
Download full text (10.2 KiB)

Here's the results of the running tab completion on ~/testdir/ while under set -x:

ubuntu@trusty-i386:~$ set -x
ubuntu@trusty-i386:~$ ls -l ~/testdir/+ local cur prev words cword split
+ _init_completion -s
+ local exclude= flag outx errx inx OPTIND=1
+ getopts n:e:o:i:s flag -s
+ case $flag in
+ split=false
+ exclude+==
+ getopts n:e:o:i:s flag -s
+ COMPREPLY=()
+ local 'redir=@(?([0-9])<|?([0-9&])>?(>)|>&)'
+ _get_comp_words_by_ref -n '=<>&' cur prev words cword
+ local exclude flag i OPTIND=1
+ words=()
+ local cur cword words
+ upargs=()
+ upvars=()
+ local upargs upvars vcur vcword vprev vwords
+ getopts c:i:n:p:w: flag -n '=<>&' cur prev words cword
+ case $flag in
+ exclude='=<>&'
+ getopts c:i:n:p:w: flag -n '=<>&' cur prev words cword
+ [[ 6 -ge 3 ]]
+ case ${!OPTIND} in
+ vcur=cur
+ let 'OPTIND += 1'
+ [[ 6 -ge 4 ]]
+ case ${!OPTIND} in
+ vprev=prev
+ let 'OPTIND += 1'
+ [[ 6 -ge 5 ]]
+ case ${!OPTIND} in
+ vwords=words
+ let 'OPTIND += 1'
+ [[ 6 -ge 6 ]]
+ case ${!OPTIND} in
+ vcword=cword
+ let 'OPTIND += 1'
+ [[ 6 -ge 7 ]]
+ __get_cword_at_cursor_by_ref '=<>&' words cword cur
+ words=()
+ local cword words
+ __reassemble_comp_words_by_ref '=<>&' words cword
+ local exclude i j line ref
+ [[ -n =<>& ]]
+ exclude='=<>&'
+ eval cword=2
++ cword=2
+ [[ -n =<>& ]]
+ line='ls -l ~/testdir/'
+ (( i=0, j=0 ))
+ (( i < 3 ))
+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval 'words[0]=${!ref}${COMP_WORDS[i]}'
++ words[0]=ls
+ line=' -l ~/testdir/'
+ [[ 0 == 2 ]]
+ (( i++, j++ ))
+ (( i < 3 ))
+ [[ 1 -gt 0 ]]
+ [[ -l == +([=<>&]) ]]
+ ref='words[1]'
+ eval 'words[1]=${!ref}${COMP_WORDS[i]}'
++ words[1]=-l
+ line=' ~/testdir/'
+ [[ 1 == 2 ]]
+ (( i++, j++ ))
+ (( i < 3 ))
+ [[ 2 -gt 0 ]]
+ [[ ~/testdir/ == +([=<>&]) ]]
+ ref='words[2]'
+ eval 'words[2]=${!ref}${COMP_WORDS[i]}'
++ words[2]='~/testdir/'
+ line=
+ [[ 2 == 2 ]]
+ eval cword=2
++ cword=2
+ (( i++, j++ ))
+ (( i < 3 ))
+ [[ 3 == 2 ]]
+ local i cur index=16 'lead=ls -l ~/testdir/'
+ [[ 16 -gt 0 ]]
+ [[ -n ls -l ~/testdir/ ]]
+ [[ -n ls-l~/testdir/ ]]
+ cur='ls -l ~/testdir/'
+ (( i = 0 ))
+ (( i <= cword ))
+ [[ 16 -ge 2 ]]
+ [[ ls != \l\s ]]
+ [[ 0 -lt 2 ]]
+ local old_size=16
+ cur=' -l ~/testdir/'
+ local new_size=14
+ index=14
+ (( ++i ))
+ (( i <= cword ))
+ [[ 14 -ge 2 ]]
+ [[ - != \-\l ]]
+ cur='-l ~/testdir/'
+ (( index-- ))
+ [[ 13 -ge 2 ]]
+ [[ -l != \-\l ]]
+ [[ 1 -lt 2 ]]
+ local old_size=13
+ cur=' ~/testdir/'
+ local new_size=11
+ index=11
+ (( ++i ))
+ (( i <= cword ))
+ [[ 11 -ge 10 ]]
+ [[ ~/testdir != \~\/\t\e\s\t\d\i\r\/ ]]
+ cur='~/testdir/'
+ (( index-- ))
+ [[ 10 -ge 10 ]]
+ [[ ~/testdir/ != \~\/\t\e\s\t\d\i\r\/ ]]
+ [[ 2 -lt 2 ]]
+ (( ++i ))
+ (( i <= cword ))
+ [[ -n ~/testdir/ ]]
+ [[ ! -n ~/testdir/ ]]
+ [[ 10 -lt 0 ]]
+ local words cword cur
+ _upvars -a3 words ls -l '~/testdir/' -v cword 2 -v cur '~/testdir/'
+ (( 11 ))
+ (( 11 ))
+ case $1 in
+ [[ -n 3 ]]
+ printf %d 3
+ [[ -n words ]]
+ unset -v words
+ eval 'words=("${@:3:3}")'
++ words=("${@:3:3}")
+ shift 5
+ (( 6 ))
+ case $1 in
+ [[ -n cword ]]
+ unset -v cword
+ eval 'cword="$3"'
++ cword=2
+ shift 3
+ (( 3 ))
+ case $1 in
+ [[ -n cur ]]
+ unset -v cur
+ eval 'cur="$3"'
++ cur='~/testdir/'
+ s...

Revision history for this message
Steve Beattie (sbeattie) wrote :
Download full text (10.2 KiB)

And for comparison, this is running tab completion on testdir/ with set -x set:

ubuntu@trusty-i386:~$ set -x
ubuntu@trusty-i386:~$ ls -l testdir/+ local cur prev words cword split
+ _init_completion -s
+ local exclude= flag outx errx inx OPTIND=1
+ getopts n:e:o:i:s flag -s
+ case $flag in
+ split=false
+ exclude+==
+ getopts n:e:o:i:s flag -s
+ COMPREPLY=()
+ local 'redir=@(?([0-9])<|?([0-9&])>?(>)|>&)'
+ _get_comp_words_by_ref -n '=<>&' cur prev words cword
+ local exclude flag i OPTIND=1
+ words=()
+ local cur cword words
+ upargs=()
+ upvars=()
+ local upargs upvars vcur vcword vprev vwords
+ getopts c:i:n:p:w: flag -n '=<>&' cur prev words cword
+ case $flag in
+ exclude='=<>&'
+ getopts c:i:n:p:w: flag -n '=<>&' cur prev words cword
+ [[ 6 -ge 3 ]]
+ case ${!OPTIND} in
+ vcur=cur
+ let 'OPTIND += 1'
+ [[ 6 -ge 4 ]]
+ case ${!OPTIND} in
+ vprev=prev
+ let 'OPTIND += 1'
+ [[ 6 -ge 5 ]]
+ case ${!OPTIND} in
+ vwords=words
+ let 'OPTIND += 1'
+ [[ 6 -ge 6 ]]
+ case ${!OPTIND} in
+ vcword=cword
+ let 'OPTIND += 1'
+ [[ 6 -ge 7 ]]
+ __get_cword_at_cursor_by_ref '=<>&' words cword cur
+ words=()
+ local cword words
+ __reassemble_comp_words_by_ref '=<>&' words cword
+ local exclude i j line ref
+ [[ -n =<>& ]]
+ exclude='=<>&'
+ eval cword=2
++ cword=2
+ [[ -n =<>& ]]
+ line='ls -l testdir/'
+ (( i=0, j=0 ))
+ (( i < 3 ))
+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval 'words[0]=${!ref}${COMP_WORDS[i]}'
++ words[0]=ls
+ line=' -l testdir/'
+ [[ 0 == 2 ]]
+ (( i++, j++ ))
+ (( i < 3 ))
+ [[ 1 -gt 0 ]]
+ [[ -l == +([=<>&]) ]]
+ ref='words[1]'
+ eval 'words[1]=${!ref}${COMP_WORDS[i]}'
++ words[1]=-l
+ line=' testdir/'
+ [[ 1 == 2 ]]
+ (( i++, j++ ))
+ (( i < 3 ))
+ [[ 2 -gt 0 ]]
+ [[ testdir/ == +([=<>&]) ]]
+ ref='words[2]'
+ eval 'words[2]=${!ref}${COMP_WORDS[i]}'
++ words[2]=testdir/
+ line=
+ [[ 2 == 2 ]]
+ eval cword=2
++ cword=2
+ (( i++, j++ ))
+ (( i < 3 ))
+ [[ 3 == 2 ]]
+ local i cur index=14 'lead=ls -l testdir/'
+ [[ 14 -gt 0 ]]
+ [[ -n ls -l testdir/ ]]
+ [[ -n ls-ltestdir/ ]]
+ cur='ls -l testdir/'
+ (( i = 0 ))
+ (( i <= cword ))
+ [[ 14 -ge 2 ]]
+ [[ ls != \l\s ]]
+ [[ 0 -lt 2 ]]
+ local old_size=14
+ cur=' -l testdir/'
+ local new_size=12
+ index=12
+ (( ++i ))
+ (( i <= cword ))
+ [[ 12 -ge 2 ]]
+ [[ - != \-\l ]]
+ cur='-l testdir/'
+ (( index-- ))
+ [[ 11 -ge 2 ]]
+ [[ -l != \-\l ]]
+ [[ 1 -lt 2 ]]
+ local old_size=11
+ cur=' testdir/'
+ local new_size=9
+ index=9
+ (( ++i ))
+ (( i <= cword ))
+ [[ 9 -ge 8 ]]
+ [[ testdir != \t\e\s\t\d\i\r\/ ]]
+ cur=testdir/
+ (( index-- ))
+ [[ 8 -ge 8 ]]
+ [[ testdir/ != \t\e\s\t\d\i\r\/ ]]
+ [[ 2 -lt 2 ]]
+ (( ++i ))
+ (( i <= cword ))
+ [[ -n testdir/ ]]
+ [[ ! -n testdir/ ]]
+ [[ 8 -lt 0 ]]
+ local words cword cur
+ _upvars -a3 words ls -l testdir/ -v cword 2 -v cur testdir/
+ (( 11 ))
+ (( 11 ))
+ case $1 in
+ [[ -n 3 ]]
+ printf %d 3
+ [[ -n words ]]
+ unset -v words
+ eval 'words=("${@:3:3}")'
++ words=("${@:3:3}")
+ shift 5
+ (( 6 ))
+ case $1 in
+ [[ -n cword ]]
+ unset -v cword
+ eval 'cword="$3"'
++ cword=2
+ shift 3
+ (( 3 ))
+ case $1 in
+ [[ -n cur ]]
+ unset -v cur
+ eval 'cur="$3"'
++ cur=testdir/
+ shift 3
+ (( 0 ))
+ [[ -n cur ]]
+ upvars+=("$vcur")
+ upargs+=(-v $v...

Revision history for this message
Ubuntu QA Website (ubuntuqa) wrote :

This bug has been reported on the Ubuntu ISO testing tracker.

A list of all reports related to this bug can be found here:
http://iso.qa.ubuntu.com/qatracker/reports/bugs/1290572

tags: added: iso-testing
Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in bash-completion (Ubuntu):
status: New → Confirmed
Revision history for this message
JuanJo Ciarlante (jjo) wrote :

This MP[1] seems to fix it for me - at least for:
1) completion when 1st char is '~'
2) fixing potential double escaping when the argument is already escaped, eg: cat /tmp/file\ with\ spac<TAB>

[1] https://code.launchpad.net/~jjo/bash-completion/fix-bash43-quote_readline_by_ref-tilde-and-double_escaping/+merge/210421

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.