Subject: bug#77430: compilation-start should remember shell-file-name

From: Siyuan Chen <[email-masked]>
Date: Tue, 1 Apr 2025 21:42:21 +0800

Background:

Recently, I've been setting up a Haskell compilation environment with Emacs
on Windows. The project depends on diagrams-cairo, which depends on GTK+,
so I have to build it via msys64 with MINGW. It works well in a non Emacs
environment, so I'd like to adapt it to the Emacs environment.

Everything is OK, except when I press 'g' in the *compilation* buffer.

To simplify the problem, below only the minimal test is provided.

Reproduce steps:

1. Create a file test.el in E:/tmp

2. Open that file and paste the following code
```
(defun my/compile ()
  (interactive)
  (let ((shell-file-name "C:/msys64/usr/bin/bash")
        (compilation-environment
"PATH=/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/c/Windows/System32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl")
        )
    (compile "ls")
    ))
```
NOTE: You can think of "ls" as a compilation command such as "stack build"
in Haskell.

3. Evaluate Last S-expression.

4. M-x my/compile

The *compilation* buffer lists the files normally.

5. Press 'g' in the *compilation* buffer, i.e. `recompile'.

The expected behavior: List the files again.

The actual behavior: Compilation exited abnormally.

The problem is that `recompile' does not realize that `shell-file-name' has
been updated to bash. It still uses the default cmdproxy.

I have created a patch to workaround the issue. It remembers the original
`shell-file-name' in `compilation-start', so we can use it when we
`recompile'.

Thanks.

Best regards,
Siyuan Chen
From 027e2f57af984478ef2cc09bf09628b1f65dc5dc Mon Sep 17 00:00:00 2001
From: Siyuan Chen <[email-masked]>
Date: Tue, 1 Apr 2025 21:06:01 +0800
Subject: [PATCH] Remember the original shell-file-name, so we can use it when
 we recompile.

---
 lisp/progmodes/compile.el | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 1ca58b3ac7d..13f20311a83 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -1973,6 +1973,7 @@ Returns the compilation buffer created."
 	    (replace-regexp-in-string "-mode\\'" "" (symbol-name mode))))
 	 (thisdir default-directory)
 	 (thisenv compilation-environment)
+         (thishell shell-file-name)
          (buffer-path (and (local-variable-p 'exec-path) exec-path))
          (buffer-env (and (local-variable-p 'process-environment)
                           process-environment))
@@ -2048,6 +2049,7 @@ Returns the compilation buffer created."
         ;; NB: must be done after (funcall mode) as that resets local variables
         (setq-local compilation-directory thisdir)
         (setq-local compilation-environment thisenv)
+        (setq-local shell-file-name thishell)
         (if buffer-path
             (setq-local exec-path buffer-path)
           (kill-local-variable 'exec-path))
-- 
2.32.0.windows.2