Tab completion for command arguments fail in Cygwin due to `.exe` extension

bashcommand linecygwin;readlinetab completion

Is there a configuration option in Cygwin so that when Bash completes the name of the command, the filename’s .exe suffix is ignored (not included)?


Explanation of the problem

When using tab completion in Bash on a Cygwin system to complete the name of a command, the .exe extension is appended to the command name, e.g, typing opens and pressing Tab completes the command to openssl.exe.

The command runs fine (with MS Windows the .exe extension is optional when running a command) but the problem is that the _openssl() completion function provided by the bash-completion package is only configured to provide completions of arguments for openssl – not openssl.exe. For example:

$ complete -p openssl openssl.exe
complete -o default -F _openssl openssl
bash: complete: openssl.exe: no completion specification

The same issue exists when trying to complete arguments for all executable commands.

I currently use Bash with Emacs mode configured for Readline editing so I can press Esc followed by two Backspace presses to remove the .exe suffix before I start to type the arguments for the command. Ideally, I’d like to avoid having to do this every time I run a command.


What I’ve tried/researched

I figured that is probably not possible without modifying the source code of the Cygwin DLL or of Bash’s command completion (pcomplete.c). However, I notice that the Bash builtins, type and command automatically strip the .exe suffix from the names of executable files, e.g.,

$ type -a openssl
openssl is /usr/bin/openssl

$ command -v openssl
/usr/bin/openssl

It seems that Bash running in Cygwin has some mechanism for providing the bare command name (without the .exe extension). However, I’ve been at a loss as to how – or if – this can be used to omit the file extension when completing commands.

Best Answer

It turns out that there is a configuration option in Cygwin that configures Bash to not include a filename’s .exe extension when it completes the name of a command.

Enabling the completion_strip_exe option (specific to the Cygwin port of Bash) does what I want:

shopt -s completion_strip_exe

This feature is not very obviously documented: it gets a cursory mention in the Pathname Expansion section of the Cygwin man page for Bash (it is not included in the upstream source code so is not documented in the official man page or documentation for Bash). I came across it while perusing /usr/share/doc/Cygwin/bash.README (some 4 months after asking this question):

7b. using 'shopt -s completion_strip_exe' makes completion strip .exe suffixes.

It seems that this option has been available in Cygwin Bash for over 5 years:

----- version 4.1.9-1 -- 2010-12-29 -----
Add EXECIGNORE and completion_strip_exe patches from Dan Colascione.

Further research shows that the patch for this feature was submitted by Dan Colascione back in November 2010 with the following description:

completion_strip_exe is a new shell option. When enabled, bash tries to use the short name of a program instead of its longer ".-exe"-suffixed one. With this on, pin completes to "ping".

Many thanks to Dan Colascione (I've just sent him a personal email to thank him personally) for this feature and the Bash maintainers for providing such a great shell.

Related Question