NTEmacsWithCygwin

NTEmacs is commonly used to denote Emacs compiled as a native w32 application. For precompiled versions and instructions on how to build see CategoryWThirtyTwo.

Why use NTEmacs with Cygwin?

Because Cygwin is wonderful … but the Emacsen that come with it suffer from a few problems:

Actually the third point is not strictly true, depending on what you mean by “Win32 console”. If you use a different console, such as mintty, you can have mouse support but must use the emacs-X11 binary not emacs-nox. It might even work with the MS Win32 console, but I wouldn’t put money on it. And since you don’t need to run X I think the first two points kind of fall out, too.

So I find myself using venerable NTEmacs, which is a native Win32 app (hence fast) with the Cygwin tools (again by the first author). The second editor of this page uses NTEmacs quite successfully with Cygwin with little changes.

The following code will produce a reasonable approximation of Unix Emacs on NT:

;;;;
;;;; cygwin support
;;;;

;; Sets your shell to use cygwin's bash, if Emacs finds it's running
;; under Windows and c:\cygwin exists. Assumes that C:\cygwin\bin is
;; not already in your Windows Path (it generally should not be).
;;
(let* ((cygwin-root "c:/cygwin")
       (cygwin-bin (concat cygwin-root "/bin")))
  (when (and (eq 'windows-nt system-type)
             (file-readable-p cygwin-root))

    (setq exec-path (cons cygwin-bin exec-path))
    (setenv "PATH" (concat cygwin-bin ";" (getenv "PATH")))

    ;; By default use the Windows HOME.
    ;; Otherwise, uncomment below to set a HOME
    ;;      (setenv "HOME" (concat cygwin-root "/home/eric"))

    ;; NT-emacs assumes a Windows shell. Change to bash.
    (setq shell-file-name "bash")
    (setenv "SHELL" shell-file-name) 
    (setq explicit-shell-file-name shell-file-name) 

    ;; This removes unsightly ^M characters that would otherwise
    ;; appear in the output of java applications.
    (add-hook 'comint-output-filter-functions 'comint-strip-ctrl-m)))

This code first verifies it is running under windows with cygwin installed, so this snippet can be safely placed in a .emacs file that is also used on emacs in unices.

You will also need Lisp:cygwin-mount.el if you want Emacs to understand Cygwin paths.

Note that this is substantially the same as the bit of code given in the Cygwin FAQ: http://www.cygwin.com/faq/faq.using.html#faq.using.ntemacs

See CustomizingBoth to get fancier.

FWIW, I have been using Cygwin with vanilla native GnuEmacs on Windows for years. To do that, I just load cygwin-mount.el and setup-cygwin.el, in that order.

EliZaretskii, who is very knowledgable about Emacs on Windows (among other things), advises against doing that, however. I don’t make heavy use of Cygwin, and I don’t use it much outside Emacs, so maybe that’s why I’ve never encountered a problem. HTH – DrewAdams

Issue (as of 26 Sep 2012): NTEmacs breaks cygwin bash

When using precompiled NTemacs version GNU Emacs 23.4.1 (i386-mingw-nt6.1.7601) with a Cygwin installation with Cygwin1.dll version 1.7.11-1, you have trouble running bash in emacs. On `M-x shell` you get:

  bash: cannot set terminal process group (-1): Inappropriate ioctl for device
  bash: no job control in this shell

This shell then is rather useless, because apart from the missing job control some commands called in that shell just hang.

The helpful people from the Cygwin mailing list suggest that it is an NTEmacs problem. This issue does not seem to be resolved yet(as of 15 Mar 2012).

Still a problem as of October 2014, with all Emacs versions (starting with Emacs 20, at least), including Emacs 25 dev snapshots. – DrewAdams

It would have been helpful to have links to those alleged Cygwin mailing list threads. I found a few that seem related, though from what I’m reading it doesn’t sound like something that could be fixed in Emacs.

Workarounds

Use Cygwin Emacs (package emacs-w32 uses the windows GUI, there are also X11 and console packages)

halloleo took this route (with X11 emacs). It is quite a hassle when you are coming from NTemacs: The look-and-feel (provided by X/Free) of the frame is significant less MS Windows-like, keyboard mappings are changed, no window shortcuts, no drag-n-drop, etc.

(I’d like to mention that Cygwin included a native emacs (emacs-w32) now, looks pretty good. - qun)

Don't upgrade Cygwin above, I think Cygwin1.dll, version 1.7.9.

Other?

It was suggested somewhere that one could remove the test for the terminal using a pty in bash and I tried this on the cygwin source for bash-4.2, i.e., I edited jobs.c to remove the test (on line 3703). This removes the error message, but still does not allow seem to allow any job control. I hope someone is working on this.

To avoid this, using ‘fakecygpty’[1] for ‘shell’ command, and remove “-i” option from ‘shell-command-switchs’ for ‘shell-command’ command.

A similar trick was useful in running SshWithNTEmacs.

cmd.exe can't deal with cygwin 'links'.

‘shell-file-name’ defaults to cmdproxy.exe - which simply prepends “/c “ to the args and sends that to cmd.exe or command.com (NT, 9x). But cmd.exe doesn’t understand cygwin links, so the call to any such program fails - sometimes silently. For instance: with my setup, gunzip.exe fails with Emacs reporting “(Shell command succeeded with no output)”.

Poking around, I found Cygwin’s gunzip.exe is 19 bytes long. The contents are: “!<symlink>gzip.exe” (with a trailing ^@).

to fix this, either copy gzip.exe to gunzip.exe, or use “bash” as your ‘shell-file-name’

M-x rgrep uses "NUL" (the Windows null device) rather than "/dev/null".

e.g.: C-u C-u M-x rgrep RET results in the following prompt: Run: find . -type f -exec grep -nH {} NUL \;

This causes the rgrep output to output numerous “grep: NUL: No such file or directory” errors.

We can advise the grep-compute-defaults function to make it see the cygwin null device when establishing the find command. Interestingly enough, this causes it to drop any mention of the null device, and pipe the find results through xargs instead of using -exec. I couldn’t follow the logic, but the resulting command prompt is certainly fine.

Run: find . -type f -print0 | xargs -0 -e grep -nH -e

You should restart emacs after adding this to your .emacs file (rather than just reloading .emacs), as the default find command is cached once it has been established, and will not be re-generated otherwise.

;; Prevent issues with the Windows null device (NUL)
;; when using cygwin find with rgrep.
(defadvice grep-compute-defaults (around grep-compute-defaults-advice-null-device)
  "Use cygwin's /dev/null as the null-device."
  (let ((null-device "/dev/null"))
	ad-do-it))
(ad-activate 'grep-compute-defaults)

Launch NTEmacs via Cygwin

If you want to launch NTEmacs via Cygwin (in order that it inherits your Cygwin environment variables – particularly useful if your bash profile does things like managing a ssh-agent), then you can use a shortcut like the following to enable this, while maintaining consistency with the standard (for NTEmacs) HOME directory:

C:\cygwin\bin\bash.exe --login -c "env HOME=\"`cygpath '%APPDATA%'`\" /cygdrive/c/emacs/emacs-23.2/bin/runemacs.exe"


CygWin