Mail Archives: cygwin/2014/02/09/21:47:53
On 2/9/2014 12:11 PM, carolus wrote:
> Is there some configuration that will let me open a text file
> in Cygwin vim by clicking on the file in an Explorer window?
I wonder if anyone else needs Windows file associations for sequences of
Cygwin commands as well. If this is useful to many, maybe a nice
utility can be whipped up. I ran into this with emacs-w32.exe which is
the Cygwin emacs compiled for Win32 (not run under X).
(I require native Cygwin emacs, not the one downloaded from ftp.gnu.org,
because version control things like bzr which are Python scripts aren't
supported by Windows emacs, and because in general I want Cygwin, not
Windows filenames, and so forth.)
The first problem is that Windows file associations have to be a single
exe with no arguments. When you run that file (double click in
Explorer), Windows passes the filename to that single .exe program.
The second problem is that it might need to be started from a full login
shell (run from bash, after .bashrc and .bash_profile are loaded) to get
right env vars and paths and other things to be set. No, I don't want to
pollute Windows environment by duplicating everything I do in .bashrc
and .bash_profile. So yes, I really need to run emacs from bash run as
full login shell.
Why full login shell? When I run emacs-w32.exe, things like version
control programs need the full login shell env vars, because checking
the current directory under vc-dir doesn't run a shell, it runs "cvs" or
"svn" or "git" directly. Without the full login shell, you don't have
an env vars set. Fail.
No, I don't want to pollute my ~/.emacs with lots of (setenv "MYVAR"
"myvalue") to mirror what's in .bashrc and .bash_profile, then monkeying
with load-path and many other ugly hacks. Again, duplicating .bashrc
and .bash_profile I dislike.
So in the end, my emacs start menu link is normally this:
Target: C:\Apps\Cyg\usr\local\bin\run.exe /bin/bash --login -i -c emacs
Start in: C:\Apps\Cyg\bin
(The patch for run.exe for quoting args better is accepted but not yet
out there, so it's a locally compiled one for now. Because
/usr/local/bin/run doesn't have the cygwin1.dll it won't start when
located elsewhere. Ignore, secondary issue.)
The third problem is that the file passed to the Windows file
association program is in Windows form, not Cygwin form with mounted
filename substitutions (eg, I have /c for C:\). Many Cygwin programs if
you pass C:\X\y will see C:Xy.
So to get a .txt file association to work with emacs-w32.exe, and also
to get it to run under a full bash shell, and also to replace Windows
with Cygwin file format, we need a single .exe that does all that. I
ask, are others wanting to run random sequences of Cygwin programs as
file associations? If so, maybe a little utility is in order.
I wrote a little utility of my own, a C++ program that essentially does:
cd C:\Apps\Cyg\bin
C:\Apps\Cyg\usr\local\bin\run.exe /bin/bash --login -i -c "emacs
C:/X/My\ File.txt"
The "C:\X\My File.txt" replaced back with forward slashes, so slashed
aren't lost to the Cygwin application, and escapes space with backslash
space so it doesn't look like separate files to emacs.
After assembling where cygwin lives based on a personal env var
"CYGROOT" into cygbin ostringstream:
if (chdir (cygbin.str ().c_str ())) { ...error... }
After assembling the run argument as "runexe" ostringstream, and the
bash login emacs argument as "cmd" ostringstream, in the end it did
this, which might be useful for a little utility if someone wants to run
with this:
// Create an array with length 3 (2 plus null array terminator)
char ** newAv = (char **)malloc (sizeof (char *) * 3);
// First element of array is 'run'
newAv[0] = (char *)malloc (strlen (runexe.c_str ()) + 1);
strcpy (newAv[0], runexe.c_str ());
// Second element of array is the bash command to launch emacs with
args
newAv[1] = (char *)malloc (strlen (cmd.str ().c_str ()) + 1);
strcpy (newAv[1], cmd.str ().c_str ());
// Third element of array is null terminator
newAv[2] = 0;
// Report what we are doing in case someone is watching
printf ("%s\n", newAv[1]);
// Replace this process with 'run' process
execve (newAv[0], newAv, env);
To get emacs to parse the C:\whatever as /c/whatever (since I mounted /c
as C:\):
; When in cygwin, allow C:\whatever to turn into /c/whatever
(defun cygwin-name-hook (operation &rest args)
"Turn Windows filenames into Cygwin filenames."
;; Handle all operations the same
(let ((first (car args))
(inhibit-file-name-handlers
(cons 'cygwin-name-hook
(and (eq inhibit-file-name-operation operation)
inhibit-file-name-handlers)))
(inhibit-file-name-operation operation))
(setq first (replace-regexp-in-string "^C:" "/c" first t))
(setq first (replace-regexp-in-string "\\\\" "/" first t))
(apply operation (cons first (cdr args)))))
(add-to-list 'file-name-handler-alist '("^[Cc]:" . cygwin-name-hook))
This also lets emacs be passed a Windows filename from places like
compiler output errors, and it loads the right one.
For my C++ little utility I copied the emacs.ico and created a tiny
LaunchEmacs.rc referencing it (so the "launch" file association looks
like Emacs). Finally the Makefile was:
i686-pc-mingw32-windres LaunchEmacs.rc -O coff -o LaunchEmacs.res
i686-pc-mingw32-g++ -static -mwindows -o LaunchEmacs.exe
LaunchEmacs.cc LaunchEmacs.res
As you can see, this is a lot of work, and it may be useful to have
Cygwin support file associations where some utility will go all the way
with filename conversion, launching, full login shell support, and whatnot.
Are people interested? Enough to start a little utility for this?
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
- Raw text -