Skip to main content
2 of 4
added 133 characters in body
Craig Hicks
  • 756
  • 8
  • 14

I provide an answer which enables the OP to directly observe the behavior of line completion after tab, and for comparison, the behavior of parsing after return.

The following bash script enables the diagnostics:

#!/bin/bash

confirm_args(){
    logger -t "confirm_args" -- "#=${#}"
    for index in `seq 0 ${#}` ; do
        eval item=\$$index
        logger -t "confirm_args" -- "[$index] ${item}"
    done    
}

_foo_completion(){
    logger -t "_foo_completion" -- "COMP_CWORD=${COMP_CWORD}" 
    logger -t "_foo_completion" -- "#COMP_WORDS=${#COMP_WORDS[@]}"
    for index in `seq 0 $((${#COMP_WORDS[@]}-1))` ; do
        logger -t "_foo_completion" -- "[$index] ${COMP_WORDS[$index]}"
    done
}
declare -f _foo_completion
complete -F _foo_completion "foo"
alias foo=confirm_args

I have made it available as a gist foo-completion.sh.

Copy and paste it into a file /tmp/foo-completion.sh.

Create two dummy files

touch /tmp/a.{1,2}

In order for the diagnostics to function correctly, logger must write to the system log. Then the OP will be able to view the diagnostic output by following the system log file. If the OP is running systemd it can viewed by opening a new window and entering

sudo journalctl -f

Activate the line completion and diagnostic output:

source /tmp/foo-completion.sh

Note that the _foo_completion does NOT perform any completion, thus no candidates are return to the user. All it does is show what data is passed to the line completion function.

Test some inputs and observe the outputs:

INPUT 1

foo a.*[SPACE][TAB]

OUTPUT

Jul 23 12:10:34 ub18 _foo_completion[17672]: COMP_CWORD=2
Jul 23 12:10:34 ub18 _foo_completion[17673]: #COMP_WORDS=3
Jul 23 12:10:34 ub18 _foo_completion[17675]: [0] foo
Jul 23 12:10:34 ub18 _foo_completion[17676]: [1] /tmp/a.*
Jul 23 12:10:34 ub18 _foo_completion[17677]: [2]

INPUT 2

foo a.*[SPACE][RETURN]

OUTPUT

Jul 23 12:19:43 ub18 confirm_args[18487]: #=2
Jul 23 12:19:43 ub18 confirm_args[18489]: [0] bash
Jul 23 12:19:43 ub18 confirm_args[18490]: [1] /tmp/a.1
Jul 23 12:19:43 ub18 confirm_args[18491]: [2] /tmp/a.2

INPUT 3

foo a.{1,2}[SPACE][TAB]

OUTPUT

NOTE - no output!

INPUT 4

foo a.{1,2}[SPACE][RETURN]

OUTPUT

Jul 23 12:28:42 ub18 confirm_args[19098]: #=2
Jul 23 12:28:42 ub18 confirm_args[19100]: [0] bash
Jul 23 12:28:42 ub18 confirm_args[19101]: [1] /tmp/a.1
Jul 23 12:28:42 ub18 confirm_args[19102]: [2] /tmp/a.2

Analysis

In "INPUT 1" the * is passed to the line completion function as a literal character '*'. However, in "INPUT 3" the line completion function is not even called. Apparently the curly brackets cause bash to suppress any further calls to the line completion function.

On the other hand, in the post [RETURN] parsing cases INPUT 2 and INPUT 4, bash expands both cases a.* and a.{1,2} to the same result.

One more test case:

INPUT 5

foo a.{[TAB]

OUTPUT

Jul 23 12:56:52 ub18 _foo_completion[21059]: COMP_CWORD=1
Jul 23 12:56:52 ub18 _foo_completion[21060]: #COMP_WORDS=2
Jul 23 12:56:52 ub18 _foo_completion[21062]: [0] foo
Jul 23 12:56:52 ub18 _foo_completion[21063]: [1] /tmp/a.{

Analysis

In "INPUT 5", with no space before the tab, bash DOES call line completion. So a line completion could theoretically return a single candidate

/tmp/a.{1,2}

which should result in auto-completion (although I haven't tested).

The problem with that would be that further files could not be added with line completion, because the curly brackets suppress line completion.

Testing with a preexisting line completion function, e.g.,

INPUT CHECK

ls /tmp/a.{[TAB][TAB][TAB][TAB][TAB][TAB]

OUTPUT

(nothing)

seems to support the thesis that it's not worth supporting curlies in a line completion function until/unless bash doesn't suppress line completion after curlies.

Craig Hicks
  • 756
  • 8
  • 14