emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 0c9e3df: Use next-error-found to set next-error-las


From: Juri Linkov
Subject: [Emacs-diffs] master 0c9e3df: Use next-error-found to set next-error-last-buffer.
Date: Tue, 17 Apr 2018 15:27:58 -0400 (EDT)

branch: master
commit 0c9e3df3c2088b61feb4b4e00d24419459962273
Author: Juri Linkov <address@hidden>
Commit: Juri Linkov <address@hidden>

    Use next-error-found to set next-error-last-buffer.
    
    https://lists.gnu.org/archive/html/emacs-devel/2018-04/msg00207.html
    
    * lisp/simple.el (next-error-buffer): New buffer-local variable
    instead of making buffer-local next-error-last-buffer.  (Bug#20489)
    (next-error-found-function): New defcustom.
    (next-error-buffer-on-selected-frame): Use t for avoid-current arg
    of next-error-buffer-p.
    (next-error-find-buffer): Add second rule for using the current
    next-error-buffer if it's not visited by other navigation.
    (next-error, next-error-internal): Call next-error-found.
    (next-error-found): New function with body extracted mostly from
    next-error.
    
    * lisp/vc/add-log.el (change-log-goto-source-internal): New function
    with body from change-log-goto-source.
    (change-log-goto-source): Call change-log-goto-source-internal and
    next-error-found.
    (change-log-next-error): Call change-log-goto-source-internal
    instead of change-log-goto-source.
    (change-log-mode): Don't set next-error-last-buffer.  (Bug#28864)
    
    * lisp/vc/diff-mode.el (diff-goto-source): Call next-error-found.
    
    * lisp/progmodes/xref.el (xref-goto-xref): Call next-error-found.
    
    * lisp/replace.el (occur-mode-goto-occurrence)
    (occur-mode-goto-occurrence-other-window)
    (occur-mode-display-occurrence): Call next-error-found.
    (occur-next-error): Remove unnecessary with-current-buffer.
    (Bug#27362, bug#30646)
---
 lisp/progmodes/grep.el | 12 +-------
 lisp/progmodes/xref.el |  6 ++--
 lisp/replace.el        | 49 ++++++++++++++---------------
 lisp/simple.el         | 84 ++++++++++++++++++++++++++++++--------------------
 lisp/vc/add-log.el     | 10 ++++--
 lisp/vc/diff-mode.el   |  4 ++-
 6 files changed, 88 insertions(+), 77 deletions(-)

diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index ee8886a..b7c44d6 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -354,17 +354,6 @@ See `compilation-error-screen-columns'"
 
 (defalias 'kill-grep 'kill-compilation)
 
-;;;; TODO --- refine this!!
-
-;; (defcustom grep-use-compilation-buffer t
-;;   "When non-nil, grep specific commands update `compilation-last-buffer'.
-;; This means that standard compile commands like \\[next-error] and 
\\[compile-goto-error]
-;; can be used to navigate between grep matches (the default).
-;; Otherwise, the grep specific commands like \\[grep-next-match] must
-;; be used to navigate between grep matches."
-;;   :type 'boolean
-;;   :group 'grep)
-
 ;; override compilation-last-buffer
 (defvar grep-last-buffer nil
   "The most recent grep buffer.
@@ -1083,6 +1072,7 @@ This command shares argument histories with \\[rgrep] and 
\\[grep]."
                                 (concat command " " null-device)
                               command)
                             'grep-mode))
+       ;; Set default-directory if we started lgrep in the *grep* buffer.
        (if (eq next-error-last-buffer (current-buffer))
            (setq default-directory dir))))))
 
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 5a9a7a9..9a437b6 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -540,9 +540,11 @@ SELECT is `quit', also quit the *xref* window."
 Non-interactively, non-nil QUIT means to first quit the *xref*
 buffer."
   (interactive)
-  (let ((xref (or (xref--item-at-point)
+  (let ((buffer (current-buffer))
+        (xref (or (xref--item-at-point)
                   (user-error "No reference at point"))))
-    (xref--show-location (xref-item-location xref) (if quit 'quit t))))
+    (xref--show-location (xref-item-location xref) (if quit 'quit t))
+    (next-error-found buffer (current-buffer))))
 
 (defun xref-quit-and-goto-xref ()
   "Quit *xref* buffer, then jump to xref on current line."
diff --git a/lisp/replace.el b/lisp/replace.el
index 4916cb1..058e144 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1192,7 +1192,8 @@ To return to ordinary Occur mode, use 
\\[occur-cease-edit]."
 (defun occur-mode-goto-occurrence (&optional event)
   "Go to the occurrence on the current line."
   (interactive (list last-nonmenu-event))
-  (let ((pos
+  (let ((buffer (when event (current-buffer)))
+        (pos
          (if (null event)
              ;; Actually `event-end' works correctly with a nil argument as
              ;; well, so we could dispense with this test, but let's not
@@ -1204,26 +1205,31 @@ To return to ordinary Occur mode, use 
\\[occur-cease-edit]."
                (occur-mode-find-occurrence))))))
     (pop-to-buffer (marker-buffer pos))
     (goto-char pos)
+    (when buffer (next-error-found buffer (current-buffer)))
     (run-hooks 'occur-mode-find-occurrence-hook)))
 
 (defun occur-mode-goto-occurrence-other-window ()
   "Go to the occurrence the current line describes, in another window."
   (interactive)
-  (let ((pos (occur-mode-find-occurrence)))
+  (let ((buffer (current-buffer))
+        (pos (occur-mode-find-occurrence)))
     (switch-to-buffer-other-window (marker-buffer pos))
     (goto-char pos)
+    (next-error-found buffer (current-buffer))
     (run-hooks 'occur-mode-find-occurrence-hook)))
 
 (defun occur-mode-display-occurrence ()
   "Display in another window the occurrence the current line describes."
   (interactive)
-  (let ((pos (occur-mode-find-occurrence))
+  (let ((buffer (current-buffer))
+        (pos (occur-mode-find-occurrence))
        window)
     (setq window (display-buffer (marker-buffer pos) t))
     ;; This is the way to set point in the proper window.
     (save-selected-window
       (select-window window)
       (goto-char pos)
+      (next-error-found buffer (current-buffer))
       (run-hooks 'occur-mode-find-occurrence-hook))))
 
 (defun occur-find-match (n search message)
@@ -1253,29 +1259,20 @@ To return to ordinary Occur mode, use 
\\[occur-cease-edit]."
   "Move to the Nth (default 1) next match in an Occur mode buffer.
 Compatibility function for \\[next-error] invocations."
   (interactive "p")
-  ;; we need to run occur-find-match from within the Occur buffer
-  (with-current-buffer
-      ;; Choose the buffer and make it current.
-      (if (next-error-buffer-p (current-buffer))
-         (current-buffer)
-       (next-error-find-buffer nil nil
-                               (lambda ()
-                                 (eq major-mode 'occur-mode))))
-
-    (goto-char (cond (reset (point-min))
-                    ((< argp 0) (line-beginning-position))
-                    ((> argp 0) (line-end-position))
-                    ((point))))
-    (occur-find-match
-     (abs argp)
-     (if (> 0 argp)
-        #'previous-single-property-change
-       #'next-single-property-change)
-     "No more matches")
-    ;; In case the *Occur* buffer is visible in a nonselected window.
-    (let ((win (get-buffer-window (current-buffer) t)))
-      (if win (set-window-point win (point))))
-    (occur-mode-goto-occurrence)))
+  (goto-char (cond (reset (point-min))
+                  ((< argp 0) (line-beginning-position))
+                  ((> argp 0) (line-end-position))
+                  ((point))))
+  (occur-find-match
+   (abs argp)
+   (if (> 0 argp)
+       #'previous-single-property-change
+     #'next-single-property-change)
+   "No more matches")
+  ;; In case the *Occur* buffer is visible in a nonselected window.
+  (let ((win (get-buffer-window (current-buffer) t)))
+    (if win (set-window-point win (point))))
+  (occur-mode-goto-occurrence))
 
 (defface match
   '((((class color) (min-colors 88) (background light))
diff --git a/lisp/simple.el b/lisp/simple.el
index 7d94b64..b51be3a 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -122,11 +122,13 @@ A buffer becomes most recent when its compilation, grep, 
or
 similar mode is started, or when it is used with \\[next-error]
 or \\[compile-goto-error].")
 
-;; next-error-last-buffer is made buffer-local to keep the reference
+(defvar next-error-buffer nil
+  "The buffer-local value of the most recent `next-error' buffer.")
+;; next-error-buffer is made buffer-local to keep the reference
 ;; to the parent buffer used to navigate to the current buffer, so the
 ;; next call of next-buffer will use the same parent buffer to
 ;; continue navigation from it.
-(make-variable-buffer-local 'next-error-last-buffer)
+(make-variable-buffer-local 'next-error-buffer)
 
 (defvar next-error-function nil
   "Function to use to find the next error in the current buffer.
@@ -177,14 +179,23 @@ rejected, and the function returns nil."
 
 (defcustom next-error-find-buffer-function #'ignore
   "Function called to find a `next-error' capable buffer."
-  :type '(choice (const :tag "Single next-error capable buffer on selected 
frame"
+  :type '(choice (const :tag "No default" ignore)
+                 (const :tag "Single next-error capable buffer on selected 
frame"
                         next-error-buffer-on-selected-frame)
-                 (const :tag "No default" ignore)
                  (function :tag "Other function"))
   :group 'next-error
   :version "27.1")
 
-(defun next-error-buffer-on-selected-frame (&optional avoid-current
+(defcustom next-error-found-function #'ignore
+  "Function called when a next locus is found and displayed.
+Function is called with two arguments: a FROM-BUFFER buffer
+from which next-error navigated, and a target buffer TO-BUFFER."
+  :type '(choice (const :tag "No default" ignore)
+                 (function :tag "Other function"))
+  :group 'next-error
+  :version "27.1")
+
+(defun next-error-buffer-on-selected-frame (&optional _avoid-current
                                                       extra-test-inclusive
                                                       extra-test-exclusive)
   "Return a single visible next-error buffer on the selected frame."
@@ -193,7 +204,7 @@ rejected, and the function returns nil."
           (delq nil (mapcar (lambda (w)
                               (if (next-error-buffer-p
                                   (window-buffer w)
-                                   avoid-current
+                                   t
                                    extra-test-inclusive extra-test-exclusive)
                                   (window-buffer w)))
                             (window-list))))))
@@ -220,16 +231,24 @@ that buffer is rejected."
    (funcall next-error-find-buffer-function avoid-current
                                             extra-test-inclusive
                                             extra-test-exclusive)
-   ;; 2. If next-error-last-buffer is an acceptable buffer, use that.
+   ;; 2. If next-error-buffer has no buffer-local value
+   ;; (i.e. never navigated to the current buffer from another),
+   ;; and the current buffer is a `next-error' capable buffer,
+   ;; use it unconditionally, so next-error will always use it.
+   (if (and (not (local-variable-p 'next-error-buffer))
+            (next-error-buffer-p (current-buffer) avoid-current
+                                extra-test-inclusive extra-test-exclusive))
+       (current-buffer))
+   ;; 3. If next-error-last-buffer is an acceptable buffer, use that.
    (if (and next-error-last-buffer
             (next-error-buffer-p next-error-last-buffer avoid-current
                                  extra-test-inclusive extra-test-exclusive))
        next-error-last-buffer)
-   ;; 3. If the current buffer is acceptable, choose it.
+   ;; 4. If the current buffer is acceptable, choose it.
    (if (next-error-buffer-p (current-buffer) avoid-current
                            extra-test-inclusive extra-test-exclusive)
        (current-buffer))
-   ;; 4. Look for any acceptable buffer.
+   ;; 5. Look for any acceptable buffer.
    (let ((buffers (buffer-list)))
      (while (and buffers
                  (not (next-error-buffer-p
@@ -237,7 +256,7 @@ that buffer is rejected."
                       extra-test-inclusive extra-test-exclusive)))
        (setq buffers (cdr buffers)))
      (car buffers))
-   ;; 5. Use the current buffer as a last resort if it qualifies,
+   ;; 6. Use the current buffer as a last resort if it qualifies,
    ;; even despite AVOID-CURRENT.
    (and avoid-current
        (next-error-buffer-p (current-buffer) nil
@@ -245,7 +264,7 @@ that buffer is rejected."
        (progn
          (message "This is the only buffer with error message locations")
          (current-buffer)))
-   ;; 6. Give up.
+   ;; 7. Give up.
    (error "No buffers contain error message locations")))
 
 (defun next-error (&optional arg reset)
@@ -284,37 +303,35 @@ To control which errors are matched, customize the 
variable
     (when buffer
       ;; We know here that next-error-function is a valid symbol we can funcall
       (with-current-buffer buffer
-        ;; Allow next-error to be used from the next-error capable buffer.
-        (setq next-error-last-buffer buffer)
         (funcall next-error-function (prefix-numeric-value arg) reset)
-        ;; Override possible change of next-error-last-buffer in 
next-error-function
-        (setq next-error-last-buffer buffer)
-        (setq-default next-error-last-buffer buffer)
-        (when next-error-recenter
-          (recenter next-error-recenter))
-        (message "%s error from %s"
+        (next-error-found buffer (current-buffer))
+        (message "%s locus from %s"
                  (cond (reset                             "First")
                        ((eq (prefix-numeric-value arg) 0) "Current")
                        ((< (prefix-numeric-value arg) 0)  "Previous")
                        (t                                 "Next"))
-                 next-error-last-buffer)
-        (run-hooks 'next-error-hook)))))
+                 next-error-last-buffer)))))
 
 (defun next-error-internal ()
   "Visit the source code corresponding to the `next-error' message at point."
   (let ((buffer (current-buffer)))
     ;; We know here that next-error-function is a valid symbol we can funcall
-    (with-current-buffer buffer
-      ;; Allow next-error to be used from the next-error capable buffer.
-      (setq next-error-last-buffer buffer)
-      (funcall next-error-function 0 nil)
-      ;; Override possible change of next-error-last-buffer in 
next-error-function
-      (setq next-error-last-buffer buffer)
-      (setq-default next-error-last-buffer buffer)
-      (when next-error-recenter
-        (recenter next-error-recenter))
-      (message "Current error from %s" next-error-last-buffer)
-      (run-hooks 'next-error-hook))))
+    (funcall next-error-function 0 nil)
+    (next-error-found buffer (current-buffer))
+    (message "Current locus from %s" next-error-last-buffer)))
+
+(defun next-error-found (&optional from-buffer to-buffer)
+  "Function to call when the next locus is found and displayed.
+FROM-BUFFER is a buffer from which next-error navigated,
+and TO-BUFFER is a target buffer."
+  (setq next-error-last-buffer (or from-buffer (current-buffer)))
+  (when to-buffer
+    (with-current-buffer to-buffer
+      (setq next-error-buffer from-buffer)))
+  (when next-error-recenter
+    (recenter next-error-recenter))
+  (funcall next-error-found-function from-buffer to-buffer)
+  (run-hooks 'next-error-hook))
 
 (defun next-error-select-buffer (buffer)
   "Select a `next-error' capable buffer and set it as the last used."
@@ -322,8 +339,7 @@ To control which errors are matched, customize the variable
    (list (get-buffer
           (read-buffer "Select next-error buffer: " nil nil
                        (lambda (b) (next-error-buffer-p (cdr b)))))))
-  (setq next-error-last-buffer buffer)
-  (setq-default next-error-last-buffer buffer))
+  (setq next-error-last-buffer buffer))
 
 (defalias 'goto-next-locus 'next-error)
 (defalias 'next-match 'next-error)
diff --git a/lisp/vc/add-log.el b/lisp/vc/add-log.el
index 175c82f..41a9991 100644
--- a/lisp/vc/add-log.el
+++ b/lisp/vc/add-log.el
@@ -471,6 +471,11 @@ A change log tag is a symbol within a parenthesized,
 comma-separated list.  If no suitable tag can be found nearby,
 try to visit the file for the change under `point' instead."
   (interactive)
+  (let ((buffer (current-buffer)))
+    (change-log-goto-source-internal)
+    (next-error-found buffer (current-buffer))))
+
+(defun change-log-goto-source-internal ()
   (if (and (eq last-command 'change-log-goto-source)
           change-log-find-tail)
       (setq change-log-find-tail
@@ -539,7 +544,7 @@ Compatibility function for \\[next-error] invocations."
   ;; if we found a place to visit...
   (when (looking-at change-log-file-names-re)
     (let (change-log-find-window)
-      (change-log-goto-source)
+      (change-log-goto-source-internal)
       (when change-log-find-window
        ;; Select window displaying source file.
        (select-window change-log-find-window)))))
@@ -1067,8 +1072,7 @@ Runs `change-log-mode-hook'.
   (set (make-local-variable 'end-of-defun-function)
        'change-log-end-of-defun)
   ;; next-error function glue
-  (setq next-error-function 'change-log-next-error)
-  (setq next-error-last-buffer (current-buffer)))
+  (setq next-error-function 'change-log-next-error))
 
 (defun change-log-next-buffer (&optional buffer wrap)
   "Return the next buffer in the series of ChangeLog file buffers.
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index ef13f55..1e2fbb9 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -1874,11 +1874,13 @@ then `diff-jump-to-old-file' is also set, for the next 
invocations."
   ;; the old location, and else to the new (i.e. as if reverting).
   ;; This is a convenient detail when using smerge-diff.
   (if event (posn-set-point (event-end event)))
-  (let ((rev (not (save-excursion (beginning-of-line) (looking-at "[-<]")))))
+  (let ((buffer (when event (current-buffer)))
+        (rev (not (save-excursion (beginning-of-line) (looking-at "[-<]")))))
     (pcase-let ((`(,buf ,line-offset ,pos ,src ,_dst ,switched)
                  (diff-find-source-location other-file rev)))
       (pop-to-buffer buf)
       (goto-char (+ (car pos) (cdr src)))
+      (when buffer (next-error-found buffer (current-buffer)))
       (diff-hunk-status-msg line-offset (diff-xor rev switched) t))))
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]