Cygwin File Type Association Helper
This is a Windows program that is designed to help people associate Windows file types (by file name extension) with a Cygwin program.
I quickly became frustrated at the dual- and triple-maintenence between various installations/varieties of Vim between my FreeBSD desktops, servers, and Windows desktops. I tried gVim, but under Windows it's like driving a Lotus through a corn field. I quickly realized a powerful editor like Vim also needs a lot of supporting applications to keep the workflow seamless.
Eventually, I pared everything down to one common denominator: Vim through some form of an xterm. This gives me the exact same editing environment whether I'm on a full, graphical desktop (Windows or Unix) or editing files on a remote system over SSH (of which, I do a considerable amount).
Of critical importance, I can manage the configuration of all these editing environments uniformly. With a massively configurable editor, like Vim, any time spent doing per-host configuration is a big deal.
The end result is a common Vim installation across all my Windows desktops that presents enough of a Unix-like development environment that I'm not slowed down by a GUI.
Of course, getting a rockin' Vim setup in Cygwin (using Mintty and the shell of your preference) is easy. The problem is that it basically lives in its own little Linux-y universe.
It is pretty easy to get Vim to run inside Mintty from a Windows file type association. Cygwin Vim even seems to be happy to accept Windows-style file names. The major problem is that Vim isn't running under my login shell. We're back to running some hybrid thing like gVim, only prettier.
There's pretty much no simple integration with the Windows desktop. I want to double-click on a source file, and see it pop up in Vim that happens to be running on top of a full arsenal of Unix-like development tools.
For that to happen I need Vim to be running within a complete login shell. I need all my paths, configs, and environment variables available for things like make, ctags, and complicated version control software.
After a few failed attempts at various shortcut tricks, DOS-style string manipulation, batch scripts, WSH scripts, and rain dances, I found someone in the same pickle. He mentioned writing a little program to handle the file type association, and just use it to start all the other stuff. Here's the post I found:
That got me started writing my own little shim program.
The program basically does two simple things:
- Takes a file name as input from the shell (Windows Explorer), and converts
it to a Cygwin-friendly path (using the installed
cygpath
program). - Starts execution of a console program (Mintty) that then spawns a shell (tcsh) with its initial command set to start a target program (vim) with the translated file path passed as its only argument.
Because this program is meant to only be used with Windows file type association, I chose to write the program using Win32 calls rather than any of the POSIX compatibility wrappers (that just make Win32 calls in a more generic way).
The program then operates pretty much as one would expect a native editor (that only takes one argument--currently). It can be invoked from the shell, and any "Open with..." or normal file type association configuration should work. You can even run the program without an argument, and just start Vim on its entry page.
To keep this program as minimal as possible, no run-time configuration is available. Adjusting the code and re-compiling is the currently preferred method to adapt this application to various environments. Most of the settings are found in the following files:
-
config.h
: Defines all file paths and program options. This is where you'd change your shell to bash. -
Makefile
: Includes the target-specific information. Replace the first real line (include vimassoc.Makefile
) with a different set of values or a file defining customized values from the one provided. The specific Windows resource script (vimassoc.rc
) can also be copied and customized to help Windows provide end-user details about the executable.
If someone or myself thinks up some other clever uses for such a program, I may automate the configuration procedure to select the console, shell, and target program.
The config.h
header defines a symbol CONFIG_CYGWIN_ROOT
that is used as
the starting point for all paths to binary images in the host's installation.
My installation is still in the old C:\cygwin
directory. This will need to
be changed for people using the C:\cygwin64
directory.
This program requires native Windows compiling. Under Cygwin, this can be compiled using the included Makefile with the MinGW compiler for 64-bit targets:
Devel/mingw64-i686-gcc
The Makefile should work fairly universally, but was only used with GNU make under Cygwin.
A Visual Studio 2013 solution/project is also included.
As the Visual Studio project does not use the Makefile to determine the Windows resource script, the project settings would need to be changed to use an alternate resource script.
This program was my first foray into dual support for multi-byte strings and unicode in the same program. Flipping the compiler's setting between either option should still result in a perfectly functional program. Of course, in multi-byte-string mode, you won't get wide character support.
Most of my development involved building for 64-bit targets. The only reason I know it also works for 32-bit targets is that Visual Studio 2013 Express still defaults the project to 32-bit targets.
The only file that matters is the executable output. This is either
build/vimassoc.exe
or vs2013\Release\vimassoc.exe
. Copy this somewhere
you won't delete later. The examples below assume the file was copied to
the root of the Cygwin installation (C:\cygwin).
Windows file type association is most easily managed via the assoc
and
ftype
commands.
Example (> is input):
>assoc .c
.c=CSource
>ftype CSource
CSource=notepad.exe "%1"
>ftype CSource=C:\cygwin\vimassoc.exe "%1"
The "gotcha" to using this method is that the current user will occasionally
have an override to the system's association for a given file type. The
quickest way to fix such a problem is to check the registry for the file
extension as a key under HKCU\Software\Classes
. If any of these extensions
have conflicting settings, you can delete them to fall back on the HKLM
(system-wide) setting that assoc
and ftype
manage.
Otherwise, you get to do a lot of clicking on each desired file type in Windows explorer to target the program as its default.
This can be used to associate all files that do not have an extension:
>assoc .=txtfile
Here, we're associating everything as a txtfile
which is what Windows uses
as the default file type name for plain text (.txt) files initially.
If there is great demand for an automated installer (e.g. someone besides myself wants to use this gadget), I'll probably throw together a batch script or WSH script to perform a file copy and set up file type associations with a little config file.
I've already started a little R&D on such an installer.
I do want to tackle a more automated/managed installation at some point.
I'd like to also support passing additional arguments to Vim. Windows file
type association allows all "other" arguments to be passed on using %*
after the "%1"
in the command string.
Investigate the possibility of getting server-mode Vim working under Cygwin, and open files using an existing Vim instance rather than launching the whole environment for every file.