[Bug 1439851] [NEW] complete -o filenames incorrectly adds slashes after directory names
hakon
hakon.hagland at gmail.com
Thu Apr 2 21:06:41 UTC 2015
Public bug reported:
I have a Bash application where I need to complete filenames and
directory names that exist in another directory relative to the current
directory. In the completion list shown in the terminal after I press
TAB, I would like to see directory names with a slash after the name,
and filenames with no slash after. This will help the user to
distinguish between directory names and filenames.
As I understand it, there are two ways to achieve this:
a) either use 'complete -o nospace', or
b) use 'complete -o filenames -o nospace'
For option a), there is a problem as soon as the depth of the path exceeds 1. For example: If I have directories
- a/b/c
- a/b/d
I will, after pressing TAB in the terminal window get
$ cmd a/
b/c b/d
so the completion list will be 'b/c', 'b/d' instead of the less verbose
'c', 'd' (which is also desired, and also how 'complete -o filenames'
works..)
For option b) , the problem is that 'complete -o filenames' will add
slashes after completion words that exist as directory names in the
current directory. This is of course, correct if you try to complete
names in the current directory, but if the completion words are taken
from another directory, this can lead to either multiple slashes (two
slashes) after directory names, or to filenames with trailing slashes (
a filename should of course not have a trailing slash after it).
Here is an example, that I hope will illustrate the problems:
First generate some dummy directories and files:
$ mkdir a
$ touch b
$ mkdir c
$ mkdir dir1
$ touch dir1/a
$ mkdir dir1/b
$ mkdir dir1/c
$ mkdir dir1/b/c
$ mkdir dir1/b/d
Then consider the following completion setup:
$ cat setup
_my_test1() {
local cur comp_dir
cur="${COMP_WORDS[$COMP_CWORD]}"
comp_dir="$PWD"
COMPREPLY=( $( cd "$comp_dir"; compgen -f "$cur" ) )
}
complete -o filenames -o nospace -F _my_test1 test1
_my_test2() {
local cur comp_dir
cur="${COMP_WORDS[$COMP_CWORD]}"
comp_dir="$PWD/dir1"
COMPREPLY=( $( cd "$comp_dir"; compgen -f "$cur" ) )
}
complete -o filenames -o nospace -F _my_test2 test2a
complete -S '/' -o nospace -F _my_test2 test2b
_my_test3() {
local cur comp_dir temp word
cur="${COMP_WORDS[$COMP_CWORD]}"
comp_dir="$PWD/dir1"
temp=( $(cd "$comp_dir"; compgen -f "$cur") )
COMPREPLY=()
for word in "${temp[@]}" ; do
[[ -d "$comp_dir/$word" ]] && word="$word/"
COMPREPLY+=( "$word" )
done
}
complete -o nospace -F _my_test3 test3
_my_test4() {
local cur comp_dir temp word
cur="${COMP_WORDS[$COMP_CWORD]}"
comp_dir="$PWD/dir1"
temp=( $(cd "$comp_dir"; compgen -f "$cur") )
COMPREPLY=()
for word in "${temp[@]}" ; do
[[ -d "$comp_dir/$word" ]] && word="$word/"
COMPREPLY+=( "$word" )
done
}
complete -o filenames -o nospace -F _my_test4 test4
_my_test5() {
local cur comp_dir temp word
cur="${COMP_WORDS[$COMP_CWORD]}"
comp_dir="$PWD/dir1"
temp=( $(cd "$comp_dir"; compgen -f "$cur") )
COMPREPLY=()
for word in "${temp[@]}" ; do
[[ -d "$comp_dir/$word" ]] && word="$word/"
[[ -d "$word" ]] && word="${word%/}"
COMPREPLY+=( "$word" )
done
}
complete -o filenames -o nospace -F _my_test5 test5
Then source the file in the Bash terminal window:
$ . setup
Then:
- 'test1': will complete correctly in the current directory. This example is just to show how the completion should work when the directory to complete in, is different from the current directory.
- 'test2a': will not add slashes after directory names in 'dir1', but will incorrectly add slashes after directory names that also exist in the current directory.
- 'test2b' : Investigates how 'complete -o nospace' works without '-o
filenames' option
- 'test3' : Same as 'test2b', but also manually adds slashes after
directory names in 'dir1'.. (but still leads to the verbose completion
lists described above in a))
- 'test4' : same as 'test2a', but also manually adds slashes after directory names in 'dir1',
but still unwanted slashes are added after names that also exist in the current directory
- 'test5' : Same as 'test4' but also tries to trick Bash completion, by
removing slashes from names that also exists in the current directory.
Notice that still there is no way to avoid the incorrect slash after the
file 'a' in 'dir1'. The reason is that the name 'a' also exists as a
directory name in the current directory..
$ lsb_release -rd
Description: Ubuntu 14.04.2 LTS
Release: 14.04
$ apt-cache policy bash-completion
bash-completion:
Installed: 1:2.1-4
Candidate: 1:2.1-4
Version table:
*** 1:2.1-4 0
500 http://no.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages
100 /var/lib/dpkg/status
** Affects: bash-completion (Ubuntu)
Importance: Undecided
Status: New
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to bash-completion in Ubuntu.
https://bugs.launchpad.net/bugs/1439851
Title:
complete -o filenames incorrectly adds slashes after directory names
Status in bash-completion package in Ubuntu:
New
Bug description:
I have a Bash application where I need to complete filenames and
directory names that exist in another directory relative to the
current directory. In the completion list shown in the terminal after
I press TAB, I would like to see directory names with a slash after
the name, and filenames with no slash after. This will help the user
to distinguish between directory names and filenames.
As I understand it, there are two ways to achieve this:
a) either use 'complete -o nospace', or
b) use 'complete -o filenames -o nospace'
For option a), there is a problem as soon as the depth of the path exceeds 1. For example: If I have directories
- a/b/c
- a/b/d
I will, after pressing TAB in the terminal window get
$ cmd a/
b/c b/d
so the completion list will be 'b/c', 'b/d' instead of the less
verbose 'c', 'd' (which is also desired, and also how 'complete -o
filenames' works..)
For option b) , the problem is that 'complete -o filenames' will add
slashes after completion words that exist as directory names in the
current directory. This is of course, correct if you try to complete
names in the current directory, but if the completion words are taken
from another directory, this can lead to either multiple slashes (two
slashes) after directory names, or to filenames with trailing slashes
( a filename should of course not have a trailing slash after it).
Here is an example, that I hope will illustrate the problems:
First generate some dummy directories and files:
$ mkdir a
$ touch b
$ mkdir c
$ mkdir dir1
$ touch dir1/a
$ mkdir dir1/b
$ mkdir dir1/c
$ mkdir dir1/b/c
$ mkdir dir1/b/d
Then consider the following completion setup:
$ cat setup
_my_test1() {
local cur comp_dir
cur="${COMP_WORDS[$COMP_CWORD]}"
comp_dir="$PWD"
COMPREPLY=( $( cd "$comp_dir"; compgen -f "$cur" ) )
}
complete -o filenames -o nospace -F _my_test1 test1
_my_test2() {
local cur comp_dir
cur="${COMP_WORDS[$COMP_CWORD]}"
comp_dir="$PWD/dir1"
COMPREPLY=( $( cd "$comp_dir"; compgen -f "$cur" ) )
}
complete -o filenames -o nospace -F _my_test2 test2a
complete -S '/' -o nospace -F _my_test2 test2b
_my_test3() {
local cur comp_dir temp word
cur="${COMP_WORDS[$COMP_CWORD]}"
comp_dir="$PWD/dir1"
temp=( $(cd "$comp_dir"; compgen -f "$cur") )
COMPREPLY=()
for word in "${temp[@]}" ; do
[[ -d "$comp_dir/$word" ]] && word="$word/"
COMPREPLY+=( "$word" )
done
}
complete -o nospace -F _my_test3 test3
_my_test4() {
local cur comp_dir temp word
cur="${COMP_WORDS[$COMP_CWORD]}"
comp_dir="$PWD/dir1"
temp=( $(cd "$comp_dir"; compgen -f "$cur") )
COMPREPLY=()
for word in "${temp[@]}" ; do
[[ -d "$comp_dir/$word" ]] && word="$word/"
COMPREPLY+=( "$word" )
done
}
complete -o filenames -o nospace -F _my_test4 test4
_my_test5() {
local cur comp_dir temp word
cur="${COMP_WORDS[$COMP_CWORD]}"
comp_dir="$PWD/dir1"
temp=( $(cd "$comp_dir"; compgen -f "$cur") )
COMPREPLY=()
for word in "${temp[@]}" ; do
[[ -d "$comp_dir/$word" ]] && word="$word/"
[[ -d "$word" ]] && word="${word%/}"
COMPREPLY+=( "$word" )
done
}
complete -o filenames -o nospace -F _my_test5 test5
Then source the file in the Bash terminal window:
$ . setup
Then:
- 'test1': will complete correctly in the current directory. This example is just to show how the completion should work when the directory to complete in, is different from the current directory.
- 'test2a': will not add slashes after directory names in 'dir1', but will incorrectly add slashes after directory names that also exist in the current directory.
- 'test2b' : Investigates how 'complete -o nospace' works without '-o
filenames' option
- 'test3' : Same as 'test2b', but also manually adds slashes after
directory names in 'dir1'.. (but still leads to the verbose completion
lists described above in a))
- 'test4' : same as 'test2a', but also manually adds slashes after directory names in 'dir1',
but still unwanted slashes are added after names that also exist in the current directory
- 'test5' : Same as 'test4' but also tries to trick Bash completion,
by removing slashes from names that also exists in the current
directory. Notice that still there is no way to avoid the incorrect
slash after the file 'a' in 'dir1'. The reason is that the name 'a'
also exists as a directory name in the current directory..
$ lsb_release -rd
Description: Ubuntu 14.04.2 LTS
Release: 14.04
$ apt-cache policy bash-completion
bash-completion:
Installed: 1:2.1-4
Candidate: 1:2.1-4
Version table:
*** 1:2.1-4 0
500 http://no.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages
100 /var/lib/dpkg/status
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1439851/+subscriptions
More information about the foundations-bugs
mailing list