Custom bash tab completion showing possible completions, but not actually completing input
Clash Royale CLAN TAG#URR8PPP
up vote
3
down vote
favorite
I have tried very hard to figure this one out before actually posting here, but I can't seem to find any other examples of people solving this particular issue.
I am running Ubuntu 17.10
I have written a custom function to handle tab completion for one of my scripts. The intention is that when I type in the name of my script and hit [TAB] that it list all of the files in /opt/use that end in ".use" (without displaying the ".use" or the leading path). I seem to have made that work so far.
The files in /opt/use are as follows:
blender-2.79.use
chrome.use
clarisse-3.6.use
unity-2017.3.0p2.use
The code for the function and the completion is:
_use ()
files=( `compgen -f -X "!*.use" /opt/use/` )
output=()
for file in "$files[@]"; do
fileBaseName=`basename $file .use`
output+=("$fileBaseName")
done
COMPREPLY=( $output[@] )
complete -F _use use
Please don't judge me too harshly, I'm a graphic artist, not a programmer. :)
Also, my "use" script is actually an alias for the following command:
source /opt/scripts/use.sh
Now when I type:
use[SPACE][TAB][TAB]
I successfully get a list of the files in /opt/use that end in ".use".
So far so good. For example, I type "use[SPACE][TAB][TAB]", this is what it looks like:
bvz@bvz-xps15-linux:~$ use
blender-2.79 chrome clarisse-3.6 unity-2017.3.0p2
My first question is why I have to hit [TAB] twice? The first time just beeps. The second time it shows me my options. That isn't an issue for me, I just wonder if it is a clue as to my problem, which is this:
If I type enough letters to be completely unique, the tab completion does not actually "complete" the line. It just leaves the entry exactly as I typed it and re-shows me the list of files in /opt/use. So, for example, if I type:
use clar[TAB][TAB]
instead of filling out the line to read:
use clarisse-3.6
which is what I would expect (and what I am after) it leaves the line as:
use clar
and shows me underneath the full list of possible completions. Here is a sample:
bvz@bvz-xps15-linux:~$ use clar[TAB][TAB]
blender-2.79 chrome clarisse-3.6 unity-2017.3.0p2
bvz@bvz-xps15-linux:~$ use clar
Notice how it didn't actually complete the line to read "clarisse-3.6" even though that is the only possible completion.
Can anyone enlighten me as to what I have done wrong? Also, if this is a duplicate I apologize. I have looked around for several days but can't find any examples where someone has even run into this issue, much less solved it.
Thanks
bash autocomplete
 |Â
show 2 more comments
up vote
3
down vote
favorite
I have tried very hard to figure this one out before actually posting here, but I can't seem to find any other examples of people solving this particular issue.
I am running Ubuntu 17.10
I have written a custom function to handle tab completion for one of my scripts. The intention is that when I type in the name of my script and hit [TAB] that it list all of the files in /opt/use that end in ".use" (without displaying the ".use" or the leading path). I seem to have made that work so far.
The files in /opt/use are as follows:
blender-2.79.use
chrome.use
clarisse-3.6.use
unity-2017.3.0p2.use
The code for the function and the completion is:
_use ()
files=( `compgen -f -X "!*.use" /opt/use/` )
output=()
for file in "$files[@]"; do
fileBaseName=`basename $file .use`
output+=("$fileBaseName")
done
COMPREPLY=( $output[@] )
complete -F _use use
Please don't judge me too harshly, I'm a graphic artist, not a programmer. :)
Also, my "use" script is actually an alias for the following command:
source /opt/scripts/use.sh
Now when I type:
use[SPACE][TAB][TAB]
I successfully get a list of the files in /opt/use that end in ".use".
So far so good. For example, I type "use[SPACE][TAB][TAB]", this is what it looks like:
bvz@bvz-xps15-linux:~$ use
blender-2.79 chrome clarisse-3.6 unity-2017.3.0p2
My first question is why I have to hit [TAB] twice? The first time just beeps. The second time it shows me my options. That isn't an issue for me, I just wonder if it is a clue as to my problem, which is this:
If I type enough letters to be completely unique, the tab completion does not actually "complete" the line. It just leaves the entry exactly as I typed it and re-shows me the list of files in /opt/use. So, for example, if I type:
use clar[TAB][TAB]
instead of filling out the line to read:
use clarisse-3.6
which is what I would expect (and what I am after) it leaves the line as:
use clar
and shows me underneath the full list of possible completions. Here is a sample:
bvz@bvz-xps15-linux:~$ use clar[TAB][TAB]
blender-2.79 chrome clarisse-3.6 unity-2017.3.0p2
bvz@bvz-xps15-linux:~$ use clar
Notice how it didn't actually complete the line to read "clarisse-3.6" even though that is the only possible completion.
Can anyone enlighten me as to what I have done wrong? Also, if this is a duplicate I apologize. I have looked around for several days but can't find any examples where someone has even run into this issue, much less solved it.
Thanks
bash autocomplete
1
Your function is not making any use of the partial word being completed, which should be in$COMP_WORDS[$COMP_CWORD]
.
â muru
Feb 1 at 3:49
So, I should filter my results to only show those that match what was typed? I.e. I would use something like: word="$COMP_WORDS[$COMP_CWORD]" and then only add to my output array those elements that start with $word?
â bvz
Feb 1 at 4:47
That, in fact was what I needed to do! Thanks for your help. If you wan to put your comment in the form of an answer, I will accept that as the solution. Thanks again!
â bvz
Feb 1 at 4:53
1
It would be better if you posted how you fixed the function using that as an answer!
â muru
Feb 1 at 5:03
I did edit my post above. Should I post it as a separate answer? Thanks again for your help. This had me spinning for a few days!
â bvz
Feb 1 at 5:04
 |Â
show 2 more comments
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I have tried very hard to figure this one out before actually posting here, but I can't seem to find any other examples of people solving this particular issue.
I am running Ubuntu 17.10
I have written a custom function to handle tab completion for one of my scripts. The intention is that when I type in the name of my script and hit [TAB] that it list all of the files in /opt/use that end in ".use" (without displaying the ".use" or the leading path). I seem to have made that work so far.
The files in /opt/use are as follows:
blender-2.79.use
chrome.use
clarisse-3.6.use
unity-2017.3.0p2.use
The code for the function and the completion is:
_use ()
files=( `compgen -f -X "!*.use" /opt/use/` )
output=()
for file in "$files[@]"; do
fileBaseName=`basename $file .use`
output+=("$fileBaseName")
done
COMPREPLY=( $output[@] )
complete -F _use use
Please don't judge me too harshly, I'm a graphic artist, not a programmer. :)
Also, my "use" script is actually an alias for the following command:
source /opt/scripts/use.sh
Now when I type:
use[SPACE][TAB][TAB]
I successfully get a list of the files in /opt/use that end in ".use".
So far so good. For example, I type "use[SPACE][TAB][TAB]", this is what it looks like:
bvz@bvz-xps15-linux:~$ use
blender-2.79 chrome clarisse-3.6 unity-2017.3.0p2
My first question is why I have to hit [TAB] twice? The first time just beeps. The second time it shows me my options. That isn't an issue for me, I just wonder if it is a clue as to my problem, which is this:
If I type enough letters to be completely unique, the tab completion does not actually "complete" the line. It just leaves the entry exactly as I typed it and re-shows me the list of files in /opt/use. So, for example, if I type:
use clar[TAB][TAB]
instead of filling out the line to read:
use clarisse-3.6
which is what I would expect (and what I am after) it leaves the line as:
use clar
and shows me underneath the full list of possible completions. Here is a sample:
bvz@bvz-xps15-linux:~$ use clar[TAB][TAB]
blender-2.79 chrome clarisse-3.6 unity-2017.3.0p2
bvz@bvz-xps15-linux:~$ use clar
Notice how it didn't actually complete the line to read "clarisse-3.6" even though that is the only possible completion.
Can anyone enlighten me as to what I have done wrong? Also, if this is a duplicate I apologize. I have looked around for several days but can't find any examples where someone has even run into this issue, much less solved it.
Thanks
bash autocomplete
I have tried very hard to figure this one out before actually posting here, but I can't seem to find any other examples of people solving this particular issue.
I am running Ubuntu 17.10
I have written a custom function to handle tab completion for one of my scripts. The intention is that when I type in the name of my script and hit [TAB] that it list all of the files in /opt/use that end in ".use" (without displaying the ".use" or the leading path). I seem to have made that work so far.
The files in /opt/use are as follows:
blender-2.79.use
chrome.use
clarisse-3.6.use
unity-2017.3.0p2.use
The code for the function and the completion is:
_use ()
files=( `compgen -f -X "!*.use" /opt/use/` )
output=()
for file in "$files[@]"; do
fileBaseName=`basename $file .use`
output+=("$fileBaseName")
done
COMPREPLY=( $output[@] )
complete -F _use use
Please don't judge me too harshly, I'm a graphic artist, not a programmer. :)
Also, my "use" script is actually an alias for the following command:
source /opt/scripts/use.sh
Now when I type:
use[SPACE][TAB][TAB]
I successfully get a list of the files in /opt/use that end in ".use".
So far so good. For example, I type "use[SPACE][TAB][TAB]", this is what it looks like:
bvz@bvz-xps15-linux:~$ use
blender-2.79 chrome clarisse-3.6 unity-2017.3.0p2
My first question is why I have to hit [TAB] twice? The first time just beeps. The second time it shows me my options. That isn't an issue for me, I just wonder if it is a clue as to my problem, which is this:
If I type enough letters to be completely unique, the tab completion does not actually "complete" the line. It just leaves the entry exactly as I typed it and re-shows me the list of files in /opt/use. So, for example, if I type:
use clar[TAB][TAB]
instead of filling out the line to read:
use clarisse-3.6
which is what I would expect (and what I am after) it leaves the line as:
use clar
and shows me underneath the full list of possible completions. Here is a sample:
bvz@bvz-xps15-linux:~$ use clar[TAB][TAB]
blender-2.79 chrome clarisse-3.6 unity-2017.3.0p2
bvz@bvz-xps15-linux:~$ use clar
Notice how it didn't actually complete the line to read "clarisse-3.6" even though that is the only possible completion.
Can anyone enlighten me as to what I have done wrong? Also, if this is a duplicate I apologize. I have looked around for several days but can't find any examples where someone has even run into this issue, much less solved it.
Thanks
bash autocomplete
edited Feb 12 at 9:20
GAD3R
22.4k154894
22.4k154894
asked Feb 1 at 3:46
bvz
1464
1464
1
Your function is not making any use of the partial word being completed, which should be in$COMP_WORDS[$COMP_CWORD]
.
â muru
Feb 1 at 3:49
So, I should filter my results to only show those that match what was typed? I.e. I would use something like: word="$COMP_WORDS[$COMP_CWORD]" and then only add to my output array those elements that start with $word?
â bvz
Feb 1 at 4:47
That, in fact was what I needed to do! Thanks for your help. If you wan to put your comment in the form of an answer, I will accept that as the solution. Thanks again!
â bvz
Feb 1 at 4:53
1
It would be better if you posted how you fixed the function using that as an answer!
â muru
Feb 1 at 5:03
I did edit my post above. Should I post it as a separate answer? Thanks again for your help. This had me spinning for a few days!
â bvz
Feb 1 at 5:04
 |Â
show 2 more comments
1
Your function is not making any use of the partial word being completed, which should be in$COMP_WORDS[$COMP_CWORD]
.
â muru
Feb 1 at 3:49
So, I should filter my results to only show those that match what was typed? I.e. I would use something like: word="$COMP_WORDS[$COMP_CWORD]" and then only add to my output array those elements that start with $word?
â bvz
Feb 1 at 4:47
That, in fact was what I needed to do! Thanks for your help. If you wan to put your comment in the form of an answer, I will accept that as the solution. Thanks again!
â bvz
Feb 1 at 4:53
1
It would be better if you posted how you fixed the function using that as an answer!
â muru
Feb 1 at 5:03
I did edit my post above. Should I post it as a separate answer? Thanks again for your help. This had me spinning for a few days!
â bvz
Feb 1 at 5:04
1
1
Your function is not making any use of the partial word being completed, which should be in
$COMP_WORDS[$COMP_CWORD]
.â muru
Feb 1 at 3:49
Your function is not making any use of the partial word being completed, which should be in
$COMP_WORDS[$COMP_CWORD]
.â muru
Feb 1 at 3:49
So, I should filter my results to only show those that match what was typed? I.e. I would use something like: word="$COMP_WORDS[$COMP_CWORD]" and then only add to my output array those elements that start with $word?
â bvz
Feb 1 at 4:47
So, I should filter my results to only show those that match what was typed? I.e. I would use something like: word="$COMP_WORDS[$COMP_CWORD]" and then only add to my output array those elements that start with $word?
â bvz
Feb 1 at 4:47
That, in fact was what I needed to do! Thanks for your help. If you wan to put your comment in the form of an answer, I will accept that as the solution. Thanks again!
â bvz
Feb 1 at 4:53
That, in fact was what I needed to do! Thanks for your help. If you wan to put your comment in the form of an answer, I will accept that as the solution. Thanks again!
â bvz
Feb 1 at 4:53
1
1
It would be better if you posted how you fixed the function using that as an answer!
â muru
Feb 1 at 5:03
It would be better if you posted how you fixed the function using that as an answer!
â muru
Feb 1 at 5:03
I did edit my post above. Should I post it as a separate answer? Thanks again for your help. This had me spinning for a few days!
â bvz
Feb 1 at 5:04
I did edit my post above. Should I post it as a separate answer? Thanks again for your help. This had me spinning for a few days!
â bvz
Feb 1 at 5:04
 |Â
show 2 more comments
2 Answers
2
active
oldest
votes
up vote
3
down vote
Thanks to Muru for pointing me to the solution.
Apparently my issue was that every time my function was called it always returned the full list of possible matches. I needed to only return those possible completions that match what the user has typed so far. Once I return only a single item, then bash will auto-complete the rest of the line.
This is the function that works. Before adding each possible completion, I do a quick check to see if the completion starts with the word that was typed originally. I do this using regular expressions. I also had to test to see if they haven't entered anything yet - in which case I always return everything.
I also changed it to make some more variables "local".
_use ()
local word="$COMP_WORDS[$COMP_CWORD]"
local files=( `compgen -f -X "!*.use" /opt/use/` )
local output=()
for file in "$files[@]"; do
fileBaseName=`basename $file .use`
if [[ $fileBaseName =~ ^$word.* ]]
add a comment |Â
up vote
1
down vote
Now that I have had some time to consider this, I think the completion function can be simplified to:
_use ()
local word="$COMP_WORDS[$COMP_CWORD]"
local IFS=$'n'
COMPREPLY=( $(find /opt/use/ -type f -name "$word*.use" -exec basename -as .use +) )
Assuming your basename
is new enough to support -a
, otherwise do -exec basename .use ;
instead.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
Thanks to Muru for pointing me to the solution.
Apparently my issue was that every time my function was called it always returned the full list of possible matches. I needed to only return those possible completions that match what the user has typed so far. Once I return only a single item, then bash will auto-complete the rest of the line.
This is the function that works. Before adding each possible completion, I do a quick check to see if the completion starts with the word that was typed originally. I do this using regular expressions. I also had to test to see if they haven't entered anything yet - in which case I always return everything.
I also changed it to make some more variables "local".
_use ()
local word="$COMP_WORDS[$COMP_CWORD]"
local files=( `compgen -f -X "!*.use" /opt/use/` )
local output=()
for file in "$files[@]"; do
fileBaseName=`basename $file .use`
if [[ $fileBaseName =~ ^$word.* ]]
add a comment |Â
up vote
3
down vote
Thanks to Muru for pointing me to the solution.
Apparently my issue was that every time my function was called it always returned the full list of possible matches. I needed to only return those possible completions that match what the user has typed so far. Once I return only a single item, then bash will auto-complete the rest of the line.
This is the function that works. Before adding each possible completion, I do a quick check to see if the completion starts with the word that was typed originally. I do this using regular expressions. I also had to test to see if they haven't entered anything yet - in which case I always return everything.
I also changed it to make some more variables "local".
_use ()
local word="$COMP_WORDS[$COMP_CWORD]"
local files=( `compgen -f -X "!*.use" /opt/use/` )
local output=()
for file in "$files[@]"; do
fileBaseName=`basename $file .use`
if [[ $fileBaseName =~ ^$word.* ]]
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Thanks to Muru for pointing me to the solution.
Apparently my issue was that every time my function was called it always returned the full list of possible matches. I needed to only return those possible completions that match what the user has typed so far. Once I return only a single item, then bash will auto-complete the rest of the line.
This is the function that works. Before adding each possible completion, I do a quick check to see if the completion starts with the word that was typed originally. I do this using regular expressions. I also had to test to see if they haven't entered anything yet - in which case I always return everything.
I also changed it to make some more variables "local".
_use ()
local word="$COMP_WORDS[$COMP_CWORD]"
local files=( `compgen -f -X "!*.use" /opt/use/` )
local output=()
for file in "$files[@]"; do
fileBaseName=`basename $file .use`
if [[ $fileBaseName =~ ^$word.* ]]
Thanks to Muru for pointing me to the solution.
Apparently my issue was that every time my function was called it always returned the full list of possible matches. I needed to only return those possible completions that match what the user has typed so far. Once I return only a single item, then bash will auto-complete the rest of the line.
This is the function that works. Before adding each possible completion, I do a quick check to see if the completion starts with the word that was typed originally. I do this using regular expressions. I also had to test to see if they haven't entered anything yet - in which case I always return everything.
I also changed it to make some more variables "local".
_use ()
local word="$COMP_WORDS[$COMP_CWORD]"
local files=( `compgen -f -X "!*.use" /opt/use/` )
local output=()
for file in "$files[@]"; do
fileBaseName=`basename $file .use`
if [[ $fileBaseName =~ ^$word.* ]]
answered Feb 1 at 5:17
bvz
1464
1464
add a comment |Â
add a comment |Â
up vote
1
down vote
Now that I have had some time to consider this, I think the completion function can be simplified to:
_use ()
local word="$COMP_WORDS[$COMP_CWORD]"
local IFS=$'n'
COMPREPLY=( $(find /opt/use/ -type f -name "$word*.use" -exec basename -as .use +) )
Assuming your basename
is new enough to support -a
, otherwise do -exec basename .use ;
instead.
add a comment |Â
up vote
1
down vote
Now that I have had some time to consider this, I think the completion function can be simplified to:
_use ()
local word="$COMP_WORDS[$COMP_CWORD]"
local IFS=$'n'
COMPREPLY=( $(find /opt/use/ -type f -name "$word*.use" -exec basename -as .use +) )
Assuming your basename
is new enough to support -a
, otherwise do -exec basename .use ;
instead.
add a comment |Â
up vote
1
down vote
up vote
1
down vote
Now that I have had some time to consider this, I think the completion function can be simplified to:
_use ()
local word="$COMP_WORDS[$COMP_CWORD]"
local IFS=$'n'
COMPREPLY=( $(find /opt/use/ -type f -name "$word*.use" -exec basename -as .use +) )
Assuming your basename
is new enough to support -a
, otherwise do -exec basename .use ;
instead.
Now that I have had some time to consider this, I think the completion function can be simplified to:
_use ()
local word="$COMP_WORDS[$COMP_CWORD]"
local IFS=$'n'
COMPREPLY=( $(find /opt/use/ -type f -name "$word*.use" -exec basename -as .use +) )
Assuming your basename
is new enough to support -a
, otherwise do -exec basename .use ;
instead.
answered Feb 2 at 8:25
muru
33.5k577143
33.5k577143
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f421132%2fcustom-bash-tab-completion-showing-possible-completions-but-not-actually-comple%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Your function is not making any use of the partial word being completed, which should be in
$COMP_WORDS[$COMP_CWORD]
.â muru
Feb 1 at 3:49
So, I should filter my results to only show those that match what was typed? I.e. I would use something like: word="$COMP_WORDS[$COMP_CWORD]" and then only add to my output array those elements that start with $word?
â bvz
Feb 1 at 4:47
That, in fact was what I needed to do! Thanks for your help. If you wan to put your comment in the form of an answer, I will accept that as the solution. Thanks again!
â bvz
Feb 1 at 4:53
1
It would be better if you posted how you fixed the function using that as an answer!
â muru
Feb 1 at 5:03
I did edit my post above. Should I post it as a separate answer? Thanks again for your help. This had me spinning for a few days!
â bvz
Feb 1 at 5:04