mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-02 08:22:22 +00:00
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)
This commit is contained in:
parent
d12800303f
commit
0c9e3df3c2
@ -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))))))
|
||||
|
||||
|
@ -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."
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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))))
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user