> Why cannot your my/compile function do this: > > (setq-local shell-file-name "C:/msys64/usr/bin/bash") > > instead of let-binding it? This is only for the current file buffer. For example, if you focus on a project file buffer (e.g. test.hs) and M-x my/compile, it only sets `shell-file-name' for that file buffer. However, the `compile` actually using the `shell-file-name' belongs to the *compilation* buffer. ``` (defun compilation-start (command &optional mode name-function highlight-regexp continue) ... (with-current-buffer outbuf ; <--- The `outbuf' is the *compilation* buffer ... (comint-exec outbuf (compilation--downcase-mode-name mode-name) shell-file-name ; <--- use the buffer local variable shell-file-name in the *compilation* buffer nil `(,shell-command-switch ,command)) ... ) ... ) ``` So the following code doesn't work: ``` (defun my/compile () (interactive) (let ( (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") ) (setq-local shell-file-name "C:/msys64/usr/bin/bash") (compile "ls") )) ``` M-x my/compile Compilation exited abnormally. Best regards, Siyuan Chen On Tue, Apr 1, 2025 at 10:46 PM Eli Zaretskii wrote: > > From: Siyuan Chen > > Date: Tue, 1 Apr 2025 21:42:21 +0800 > > > > 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") > > )) > > ``` > > Why cannot your my/compile function do this: > > (setq-local shell-file-name "C:/msys64/usr/bin/bash") > > instead of let-binding it? > > > 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, but I don't think it's TRT for 'compile' to record the shell > by default. In your case, you want to use the same shell each time, > but that is not always true. Since you already have a tailored > compilation command, I suggest that the same command does this job > for you. >