Subject: bug#38648: 27.0.50; Emacs `compile' command does not handle remote (over TRAMP) file name correctly

From: Michael Albinus <[email-masked]>
Date: Tue, 17 Dec 2019 17:02:12 +0100

Fan Yang <[email-masked]> writes:

Hi,

> Re-produce steps:
>
> 1. `find-file' to my project root directory on a remote machine,
>    namely, "/scp:vm00:pmdk-balloon/".
> 2. `M-x compile', and give compile command "make".
> 3. (Previously I have injected some typos in some of my source files,
>    say "obj.c").
> 4. In the *compilation* buffer, the "obj.c" file appears.  But when I
>    click the underlined text (or <RET> on it), an error occurs in the
>    minibuffer:
>
>    "Find this error in (default obj.c): /scp:vm00:/System/Volumes/Data/home/fan/pmdk-balloon/src/libpmemobj"
>
>    The "/System/Volumes/Data/" is actually a path on my local machine.

> It appears that when compile.el was handling the remote path, it
> mixed-up part of my local machine path with the
> remote machine path, resulting the error.
>
> Then I find that in my environment, `(file-symlink-p "/home")' is
> evaluated to "/System/Volumes/Data/home".  Now I stuck here since I know
> little about TRAMP and how a remote file path should be handled.

Could you pls check, whether the appended patch fixes the problem?

Best regards, Michael.

diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 3fbd6eb2c7..197d52b2de 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -2936,21 +2936,15 @@ compilation-get-file-structure
       ;; Let's normalize it and look again.
       (let ((filename (car file))
 	    ;; Get the specified directory from FILE.
-	    (spec-directory (if (cdr file)
-				(file-truename (cdr file)))))
+	    (spec-directory
+             (if (cdr file)
+		 (file-truename (concat comint-file-name-prefix (cdr file))))))

 	;; Check for a comint-file-name-prefix and prepend it if appropriate.
 	;; (This is very useful for compilation-minor-mode in an rlogin-mode
 	;; buffer.)
-	(when (and (boundp 'comint-file-name-prefix)
-		   (not (equal comint-file-name-prefix "")))
-	  (if (file-name-absolute-p filename)
-	      (setq filename
-		    (concat comint-file-name-prefix filename))
-	    (if spec-directory
-		(setq spec-directory
-		      (file-truename
-		       (concat comint-file-name-prefix spec-directory))))))
+	(if (file-name-absolute-p filename)
+	    (setq filename (concat comint-file-name-prefix filename)))

 	;; If compilation-parse-errors-filename-function is
 	;; defined, use it to process the filename.  The result might be a