Question

I have a method that explains its usage when you run it without options:

Usage:
SQLbatch [database] [file] [maximum # of lines in batch] [time to sleep between batches] [who to email when finished]

Lately, I've been writing a tab-completion script in my spare time:

_SQLbatch()
{    

  local cur dbs
  COMPREPLY=()
  dbs=$(< /...directory paths.../allDbs.txt)
  cur="${COMP_WORDS[COMP_CWORD]}"

  case "$COMP_CWORD" in
  1)
     case "$cur" in
     *@*)   
        COMPREPLY=( $(compgen -W "$dbs" -- "$cur" | sed -e "s/.*@/@/") )
        return 0    
        ;;          
     *)   
        COMPREPLY=( $(compgen -W "$dbs" -- "$cur") )
        return 0    
        ;;          
     esac   
     ;;     
  2)
     COMPREPLY=( $(compgen -f -- "$cur") )
     return 0
     ;;     
  *)
  esac
}    

complete -F _SQLbatch SQLbatch

So far, this works great for completing the first and 2nd entries with the appropriate database and file. However, I've also been trying to add a way to simply print out the "Usage" information if you double-tab anywhere past the file. So, if I put this into the console:

SQLbatch server@database file.txt [TAB][TAB]

I'd like completion to remind the user what else they need without destroying what they've already typed in. My latest approach was something like this:

...
  *)
     echo -e "\nSQLbatch [database] [file] [maximum # of lines in batch] [time to sleep between batches] [who to email when finished]"
     return 0
     ;;
  esac
...

This almost does it but ultimately fails to redisplay the user input on the latest line. Is there a way to force this last step into the completion?

Was it helpful?

Solution

Here is how you do it. What we're going to do is generate the PS1 (shell prompt) and your current words to repair the broken new line. We could stick the contents of $actualPS1 inside our echo statment directly, but I figured this method was much more legible.

...
*)
    actualPS1=$(eval echo \"$PS1\")
    echo -en "\nWhatever line of text you want.\n"
    echo -en "${actualPS1}${COMP_WORDS[@]}"
    return 0
    ;;
esac
...

That will print a line of text for your specific case and then give the console back to you properly. There is no need to specify what COMPREPLY should be.

Note that you could basically add this completion to anything that can't be completed by normal means as a helpful reminder to the end user. One method that could potentially use this would be echo itself!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top