Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to Bash Complete Three-Part Pattern
    text
    copied!<p>I have a command line tool which takes arguments in an three-part form:</p> <pre><code>$ t first_second_third </code></pre> <p>I have a set of valid values for <code>first</code>, a set of valid values for <code>second</code>, and a set of valid values for <code>third</code>. I want to use Bash complete functionality to complete each <em>part</em> of the option value, as in this example:</p> <pre><code>$ t [tab][tab] # shows options for first part walk run skip bike $ t w[tab] # completes first part and appends delimiter $ t walk_[tab][tab] # shows options for second part home work park $ t walk_h[tab] # completes second part and appends delimiter $ t walk_home_[tab][tab] # shows options for second part morning afternoon evening $ t walk_home_a[tab] # completes second part and appends space $ t walk_home_afternoon </code></pre> <p>I have this code:</p> <pre><code>_tool () { local cur="${COMP_WORDS[COMP_CWORD]}" local first="walk run skip bike" local second="home work park" local third="morning afternoon evening" case "${cur}" in *_*_*) COMPREPLY=( $(compgen -W "${third}" -- "") ); return 0;; *_*) COMPREPLY=( $(compgen -W "${second}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;; *) COMPREPLY=( $(compgen -W "${first}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;; esac } complete -F _tool t </code></pre> <p>The first clause works great; nothing special there. But the second clause gives me no options or completions.</p> <pre><code>$ t [tab][tab] bike_ run_ skip_ walk_ $ t b[tab] $ t bike_[tab][tab] # nothing but bells </code></pre> <p>I replaced the second clause with the following (i.e. I replaced <code>${cur}</code> with an empty string in the <code>COMPREPLY</code> call):</p> <pre><code>COMPREPLY=( $(compgen -W "${second}" -S "_" -- "") ); compopt -o nospace; return 0;; </code></pre> <p>I get a list of <em>all</em> options on the command line, but no completions.</p> <pre><code>$ t bike_[tab][tab] home_ park_ work_ $ t bike_h[tab][tab] home_ park_ work_ $ t bike_ho[tab][tab] home_ park_ work_ </code></pre> <p>I thought there might be some bad interaction with <code>${cur}</code> and the <code>COMPREPLY</code> word list, so I changed the second clause again, adding a prefix which matches the first part of the current word:</p> <pre><code>local prefix=( $(expr "${cur}" : '\(.*_\)') ) COMPREPLY=( $(compgen -W "${second}" -P "${prefix}" -S "_" -- "") ); compopt -o nospace; return 0;; </code></pre> <p>This did not help much. With <code>${cur}</code> still in the <code>COMPREPLY</code> command, I got no options or completions again. With an empty string instead, I got the full option (not just the curent part). But, pressing tab would erase what is typed.</p> <pre><code>$ t bike_[tab][tab] bike_home_ bike_park_ bike_work_ $ t bike_ho[tab] $ t bike_ # "ho" was erased </code></pre> <p>Of course, I have the same problem with the third part, too.</p> <ol> <li>How can I get Bash to complete the current word, part by part?</li> <li>How can I get Bash to not append the delimiter until an option has been selected?</li> </ol> <p>This is similar to <a href="https://stackoverflow.com/q/3951628/1181574">another Bash complete question</a>, but I do not want to list every possible permutation of the values and they are not formatted as filenames (not sure if the filename pattern makes a difference).</p> <p>Thanks for the help!<br> --ap</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload