Search code examples
bashjavactab-completionbash-completion

Strange javac Tab Completion for Classpath


The javac command has strange tab completion with -cp and -classpath. I was under the impression -cp was an alias for -classpath. However, when I press tab after the -classpath flag, I get .jar files as expected. When I press tab with -classpath I get:

javac -classpath <tab>
javac -classpath lib/ <tab>
javac -classpath lib/test.jar

and

javac -classpath .: <tab>
javac -classpath .:lib/ <tab>
javac -classpath .:lib/test.jar

Alternatively, with -cp

javac -cp <tab>
javac -cp lib/ <tab>
javac -cp lib/

and

javac -cp .: <tab>
javac -cp .:

I'm using bash in ubuntu 16.04 and javac 1.8.0_111 if that's relevant.


Solution

  • This functionality is implemented by the bash-completion package. You can find the code for the relevant function like so:

    $ complete -p javac
    complete -F _javac javac  # the function `_javac' is used to complete the command `javac'
    $ declare -f _javac .     # this will print the function code
    

    There you'll see that the relevant code is:

    case $prev in
        ...
        -classpath|-bootclasspath|-sourcepath|-extdirs)
        ...
    

    So if you want, you can take the whole definition of _javac() from the declare -f command, modify it to include -cp in that case statement, and append it to the end of your bash init file (.bashrc or .bash_profile, etc). Then, when you start a new shell, the new _javac() will be used to complete javac commands.

    Also, the code for the latest release is also viewable on github. Other command completions defined there (java, javadoc) understand the short-hand flags so I'm sure a pull request with a fix for this issue would be welcome.


    Update: This is now fixed in the source.