Subject: bug#54606: 27.1; next/previous image command in image-mode triggers tramp connections for all remote dired buffers

From: Michael Albinus <[email-masked]>
Date: Thu, 31 Mar 2022 11:47:41 +0200

Phil Sainty <[email-masked]> writes:

Hi Phil,

> In 27.1 this code is in `image-next-file'.  In master it's now
> `image-mode--directory-buffers', but the relevant code looks
> the same:
>
>       ;; Find a dired buffer.
>       (dolist (buffer (buffer-list))
> 	(with-current-buffer buffer
> 	  (when (and (derived-mode-p 'dired-mode)
> 	             (equal (file-truename dir)
> 		            (file-truename default-directory)))
>
> That call to (file-truename default-directory) for each dired
> buffer can cause tramp to spin up for closed connections for
> entirely irrelevant dired buffers.

I've reproduced the problem. As said already (?), it is similar to
bug#54542. The solution there was to wrap the code in question by
let-binding non-essential to t, and to enhance Tramp to behave
accordingly.

The Tramp change is already in the master branch, and also in the just
released Tramp 2.5.2.3 on GNU ELPA. So I've applied the following change
in master:

diff --git a/lisp/image-mode.el b/lisp/image-mode.el
index d7dfb4336b..69af538aa7 100644
--- a/lisp/image-mode.el
+++ b/lisp/image-mode.el
@@ -1196,8 +1196,9 @@ image-mode--directory-buffers
   "Return an alist of type/buffer for all \"parent\" buffers to image FILE.
 This is normally a list of Dired buffers, but can also be archive and
 tar mode buffers."
-  (let ((buffers nil)
-        (dir (file-name-directory file)))
+  (let* ((non-essential t) ; Do not block for remote buffers.
+         (buffers nil)
+         (dir (file-name-directory file)))
     (cond
      ((and (boundp 'tar-superior-buffer)
 	   tar-superior-buffer)

This changes the behavior. Recipe:

- emacs -Q /ssh:detlef:Pictures/IMG_0040.JPG
- Disable Ethernet/WLAN connection
- Type 'n' in the image buffer.

If the last step happens shortly after disabling the connection, nothing
changes, and Emacs is blocked. This is because Emacs needs some seconds
to detect the new status of the respective Tramp process (‘exited
abnormally with code 255').

However, waiting 10 seconds or longer (in my case), typing 'n'
immediately returns with the message

--8<---------------cut here---------------start------------->8---
user-error: No next file in this directory
--8<---------------cut here---------------end--------------->8---

That sounds acceptable, isn't it?

It shall also help for other dired buffers with different, already
closed, Tramp connections.
>
> Can we put some guards in there to decide whether or not dir
> and default-directory are actually on the same host before
> comparing them via file-truename?

If you want to go *this* direction, there would be a simple change:

--8<---------------cut here---------------start------------->8---
	  (when (and (derived-mode-p 'dired-mode)
	             (equal (file-remote-p dir)
		            (file-remote-p default-directory))
	             (equal (file-truename dir)
		            (file-truename default-directory)))
--8<---------------cut here---------------end--------------->8---

file-remote-p doesn't do anything on wire.

> -Phil (who is simply testing (not (file-remote-p default-directory))
>        as an interim fix)

Best regards, Michael.