Subject: Re: bug#44611: Prefix arg for xref-goto-xref

From: Juri Linkov <[email-masked]>
Date: Sat, 19 Dec 2020 22:38:12 +0200

>> I'd expect TAB rather to iterate over multiple matches,
>> i.e. like TAB in browsers go to the next match.  Even in the *Completions*
>> buffer TAB moves to the next completion.  And in icomplete-mode
>> the closest analogy to picking one result is 'C-j'
>> (icomplete-force-complete-and-exit).
>
> If people like it, I'm totally fine with changing the binding to 'C-j'.

I'm very sorry for beating this horse again, but after trying to use xref
as a replacement of grep, typing 'C-x p g' pops up a grep-like buffer
and due to habit of typing the same keys that are supported by grep-mode
where among them is TAB bound to compilation-next-error to browse the
results forward, but instead of going to the next match, it does the
worst thing imaginable - kills the output buffer.

Therefore, I propose this patch that binds TAB and S-TAB to command
that behave like compilation-next-error and compilation-previous-error:

diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 6e99e9d8ac..6c333fc8c1 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -581,16 +581,26 @@ xref-show-location-at-point
     (when xref
       (xref--show-location (xref-item-location xref)))))
 
+(defun xref-next-line-no-select ()
+  "Move to the next xref but don't display its source."
+  (interactive)
+  (xref--search-property 'xref-item))
+
 (defun xref-next-line ()
   "Move to the next xref and display its source in the appropriate window."
   (interactive)
-  (xref--search-property 'xref-item)
+  (xref-next-line-no-select)
   (xref-show-location-at-point))
 
+(defun xref-prev-line-no-select ()
+  "Move to the previous xref but don't display its source."
+  (interactive)
+  (xref--search-property 'xref-item t))
+
 (defun xref-prev-line ()
   "Move to the previous xref and display its source in the appropriate window."
   (interactive)
-  (xref--search-property 'xref-item t)
+  (xref-prev-line-no-select)
   (xref-show-location-at-point))
 
 (defun xref-next-group ()
@@ -761,7 +771,8 @@ xref--xref-buffer-mode-map
     (define-key map (kbd "P") #'xref-prev-group)
     (define-key map (kbd "r") #'xref-query-replace-in-results)
     (define-key map (kbd "RET") #'xref-goto-xref)
-    (define-key map (kbd "TAB")  #'xref-quit-and-goto-xref)
+    (define-key map "\t" 'xref-next-line-no-select) ; like compilation-next-error
+    (define-key map [backtab] 'xref-prev-line-no-select) ; like compilation-previous-error
     (define-key map (kbd "C-o") #'xref-show-location-at-point)
     ;; suggested by Johan Claesson "to further reduce finger movement":
     (define-key map (kbd ".") #'xref-next-line)