all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: charles@aurox.ch (Charles A. Roelli)
To: Dima Kogan <dima@secretsauce.net>
Cc: 21262@debbugs.gnu.org
Subject: bug#21262: 25.0.50; Diff-mode gets confused about its narrowing if hunk source not found
Date: Mon, 21 Aug 2017 21:49:50 +0200	[thread overview]
Message-ID: <m2y3qcpuox.fsf@aurox.ch> (raw)
In-Reply-To: <87lhdd5e52.fsf@secretsauce.net> (message from Dima Kogan on Fri,  14 Aug 2015 22:12:09 -0700)

[-- Attachment #1: Type: text/plain, Size: 2394 bytes --]

> From: Dima Kogan <dima@secretsauce.net>
> Date: Fri, 14 Aug 2015 22:12:09 -0700
> 
> Hi. This bug has been there since at least emacs23 it seems like. To
> reproduce:
> 
> 1. emacs -Q
> 
> 2. Open any patch file that has hunks from more than one file in it. For
> instance, the attached patch file works, but it really doesn't matter
> 
> 3. Narrow to just the second file's diffs. For instance: M-N M-N C-SPC
> C-> C-x n n SPC (last SPC to confirm the narrowing)
> 
> 4. Try to see the source of the hunk. Move the point to the guts of the
> hunk, and M-enter. Emacs asks for the directory where the sources live.
> In the process, it changes the narrowing to the wrong hunk. This is
> wrong. The narrowing shouldn't change.
> 
> 5. If we cancel with C-g, the wrong narrowing persists
> 
> 
> 
> diff --git a/src/charset.c b/src/charset.c
> index b19e344..eeebf17 100644
> --- a/src/charset.c
> +++ b/src/charset.c
> @@ -555,7 +555,7 @@ load_charset_map_from_vector (struct charset *charset, Lisp_Object vec, int cont
>  
>    if (len % 2 == 1)
>      {
> -      add_to_log ("Failure in loading charset map: %V", vec, Qnil);
> +      add_to_log ("Failure in loading charset map: %V", vec);
>        return;
>      }
>  
> diff --git a/src/image.c b/src/image.c
> index 066db74..313419b 100644
> --- a/src/image.c
> +++ b/src/image.c
> @@ -629,16 +629,19 @@ valid_image_p (Lisp_Object object)
>  }
>  
>  
> -/* Log error message with format string FORMAT and argument ARG.
> +/* Log error message with format string FORMAT and trailing arguments.
>     Signaling an error, e.g. when an image cannot be loaded, is not a
>     good idea because this would interrupt redisplay, and the error
>     message display would lead to another redisplay.  This function
>     therefore simply displays a message.  */
>  
>  static void
> -image_error (const char *format, Lisp_Object arg1, Lisp_Object arg2)
> +image_error (const char *format, ...)
>  {
> -  add_to_log (format, arg1, arg2);
> +  va_list ap;
> +  va_start (ap, format);
> +  vadd_to_log (format, ap);
> +  va_end (ap);
>  }
>  
>  

This still affects 26.0.50.

The attached change fixes it -- but I know nothing of diff-mode, so
better ideas are welcome.  Note that the buffer will be widened while
Emacs asks where to look for the sources, but it will return to the
original narrowing after the user has selected a file or hit C-g.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 01-emacs-bug-21262-draft.patch --]
[-- Type: text/x-patch, Size: 4937 bytes --]

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index aa8d778..b470406 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -874,52 +874,54 @@ diff-find-file-name
     ;; Flush diff-remembered-files-alist if the default-directory is changed.
     (set (make-local-variable 'diff-remembered-defdir) default-directory)
     (set (make-local-variable 'diff-remembered-files-alist) nil))
-  (save-excursion
-    (unless (looking-at diff-file-header-re)
-      (or (ignore-errors (diff-beginning-of-file))
-	  (re-search-forward diff-file-header-re nil t)))
-    (let ((fs (diff-hunk-file-names old)))
-      (if prefix (setq fs (mapcar (lambda (f) (concat prefix f)) fs)))
-      (or
-       ;; use any previously used preference
-       (cdr (assoc fs diff-remembered-files-alist))
-       ;; try to be clever and use previous choices as an inspiration
-       (cl-dolist (rf diff-remembered-files-alist)
-	 (let ((newfile (diff-merge-strings (caar rf) (car fs) (cdr rf))))
-	   (if (and newfile (file-exists-p newfile)) (cl-return newfile))))
-       ;; look for each file in turn.  If none found, try again but
-       ;; ignoring the first level of directory, ...
-       (cl-do* ((files fs (delq nil (mapcar 'diff-filename-drop-dir files)))
-                (file nil nil))
-	   ((or (null files)
-		(setq file (cl-do* ((files files (cdr files))
-                                    (file (car files) (car files)))
-			       ;; Use file-regular-p to avoid
-			       ;; /dev/null, directories, etc.
-			       ((or (null file) (file-regular-p file))
-				file))))
-	    file))
-       ;; <foo>.rej patches implicitly apply to <foo>
-       (and (string-match "\\.rej\\'" (or buffer-file-name ""))
-	    (let ((file (substring buffer-file-name 0 (match-beginning 0))))
-	      (when (file-exists-p file) file)))
-       ;; If we haven't found the file, maybe it's because we haven't paid
-       ;; attention to the PCL-CVS hint.
-       (and (not prefix)
-	    (boundp 'cvs-pcl-cvs-dirchange-re)
-	    (save-excursion
-	      (re-search-backward cvs-pcl-cvs-dirchange-re nil t))
-	    (diff-find-file-name old noprompt (match-string 1)))
-       ;; if all else fails, ask the user
-       (unless noprompt
-         (let ((file (expand-file-name (or (car fs) ""))))
-	   (setq file
-		 (read-file-name (format "Use file %s: " file)
-				 (file-name-directory file) file t
-				 (file-name-nondirectory file)))
-           (set (make-local-variable 'diff-remembered-files-alist)
-                (cons (cons fs file) diff-remembered-files-alist))
-           file))))))
+  (save-restriction
+    (widen)
+    (save-excursion
+      (unless (looking-at diff-file-header-re)
+        (or (ignore-errors (diff-beginning-of-file))
+	    (re-search-forward diff-file-header-re nil t)))
+      (let ((fs (diff-hunk-file-names old)))
+        (if prefix (setq fs (mapcar (lambda (f) (concat prefix f)) fs)))
+        (or
+         ;; use any previously used preference
+         (cdr (assoc fs diff-remembered-files-alist))
+         ;; try to be clever and use previous choices as an inspiration
+         (cl-dolist (rf diff-remembered-files-alist)
+	   (let ((newfile (diff-merge-strings (caar rf) (car fs) (cdr rf))))
+	     (if (and newfile (file-exists-p newfile)) (cl-return newfile))))
+         ;; look for each file in turn.  If none found, try again but
+         ;; ignoring the first level of directory, ...
+         (cl-do* ((files fs (delq nil (mapcar 'diff-filename-drop-dir files)))
+                  (file nil nil))
+	     ((or (null files)
+		  (setq file (cl-do* ((files files (cdr files))
+                                      (file (car files) (car files)))
+			         ;; Use file-regular-p to avoid
+			         ;; /dev/null, directories, etc.
+			         ((or (null file) (file-regular-p file))
+				  file))))
+	      file))
+         ;; <foo>.rej patches implicitly apply to <foo>
+         (and (string-match "\\.rej\\'" (or buffer-file-name ""))
+	      (let ((file (substring buffer-file-name 0 (match-beginning 0))))
+	        (when (file-exists-p file) file)))
+         ;; If we haven't found the file, maybe it's because we haven't paid
+         ;; attention to the PCL-CVS hint.
+         (and (not prefix)
+	      (boundp 'cvs-pcl-cvs-dirchange-re)
+	      (save-excursion
+	        (re-search-backward cvs-pcl-cvs-dirchange-re nil t))
+	      (diff-find-file-name old noprompt (match-string 1)))
+         ;; if all else fails, ask the user
+         (unless noprompt
+           (let ((file (expand-file-name (or (car fs) ""))))
+	     (setq file
+		   (read-file-name (format "Use file %s: " file)
+				   (file-name-directory file) file t
+				   (file-name-nondirectory file)))
+             (set (make-local-variable 'diff-remembered-files-alist)
+                  (cons (cons fs file) diff-remembered-files-alist))
+             file)))))))
 
 
 (defun diff-ediff-patch ()

  reply	other threads:[~2017-08-21 19:49 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-15  5:12 bug#21262: 25.0.50; Diff-mode gets confused about its narrowing if hunk source not found Dima Kogan
2017-08-21 19:49 ` Charles A. Roelli [this message]
2017-08-22  0:18   ` npostavs
2017-08-22 14:02     ` Charles A. Roelli
2017-08-27 12:21       ` Charles A. Roelli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m2y3qcpuox.fsf@aurox.ch \
    --to=charles@aurox.ch \
    --cc=21262@debbugs.gnu.org \
    --cc=dima@secretsauce.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.