aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2016-02-22 00:26:24 +0200
committerDmitry Gutov2016-02-22 00:57:40 +0200
commit5698947ff9335cf150c73cca257a5e7e5951b045 (patch)
tree9ef897ef79fe16778893f968dd32b56d4229435a
parente34fbdee8aca84b98393b06b2450837d175999ca (diff)
downloademacs-5698947ff9335cf150c73cca257a5e7e5951b045.tar.gz
emacs-5698947ff9335cf150c73cca257a5e7e5951b045.zip
Keep the xref buffer visible until the user quits it explicitly
* lisp/progmodes/xref.el (xref--pop-to-location): Rename WINDOW argument to ACTION. (xref--with-dedicated-window): New macro. (xref--show-pos-in-buf): Rename from `xref--display-position'. Add and handle new argument, SELECTED. Use the above macro. (xref--show-location): Add SELECTED argument. (xref-show-location-at-point): Make an effort to avoid the original window when showing the location. (xref-goto-xref): Don't quit the xref window (bug#20487 and http://lists.gnu.org/archive/html/emacs-devel/2016-01/msg01133.html). (xref--query-replace-1): Use xref--with-dedicated-window as well. (xref--next-error-function): Call xref--show-location instead of xref--pop-to-location. (xref--show-xrefs): Rename WINDOW argument to DISPLAY-ACTION. Only pass that value to xref--pop-to-location. Pass the current selected window to xref-show-xrefs-function as the `window' property. (xref--find-xrefs, xref--find-definitions): Rename WINDOW argument to DISPLAY-ACTION as well.
-rw-r--r--lisp/progmodes/xref.el84
1 files changed, 52 insertions, 32 deletions
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 2fd7297a2e8..31a03d9d1e9 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -414,16 +414,17 @@ elements is negated."
414 (set-buffer (marker-buffer marker)) 414 (set-buffer (marker-buffer marker))
415 (xref--goto-char marker))) 415 (xref--goto-char marker)))
416 416
417(defun xref--pop-to-location (item &optional window) 417(defun xref--pop-to-location (item &optional action)
418 "Go to the location of ITEM and display the buffer. 418 "Go to the location of ITEM and display the buffer.
419WINDOW controls how the buffer is displayed: 419ACTION controls how the buffer is displayed:
420 nil -- switch-to-buffer 420 nil -- switch-to-buffer
421 `window' -- pop-to-buffer (other window) 421 `window' -- pop-to-buffer (other window)
422 `frame' -- pop-to-buffer (other frame)" 422 `frame' -- pop-to-buffer (other frame)
423If SELECT is non-nil, select the target window."
423 (let* ((marker (save-excursion 424 (let* ((marker (save-excursion
424 (xref-location-marker (xref-item-location item)))) 425 (xref-location-marker (xref-item-location item))))
425 (buf (marker-buffer marker))) 426 (buf (marker-buffer marker)))
426 (cl-ecase window 427 (cl-ecase action
427 ((nil) (switch-to-buffer buf)) 428 ((nil) (switch-to-buffer buf))
428 (window (pop-to-buffer buf t)) 429 (window (pop-to-buffer buf t))
429 (frame (let ((pop-up-frames t)) (pop-to-buffer buf t)))) 430 (frame (let ((pop-up-frames t)) (pop-to-buffer buf t))))
@@ -446,41 +447,61 @@ WINDOW controls how the buffer is displayed:
446 (when (and restore (not (eq (car restore) 'same))) 447 (when (and restore (not (eq (car restore) 'same)))
447 (push (cons buf win) xref--display-history)))) 448 (push (cons buf win) xref--display-history))))
448 449
449(defun xref--display-position (pos other-window buf) 450(defmacro xref--with-dedicated-window (&rest body)
450 ;; Show the location, but don't hijack focus. 451 `(let* ((xref-w (get-buffer-window xref-buffer-name))
451 (let ((xref-buf (current-buffer))) 452 (xref-w-dedicated (window-dedicated-p xref-w)))
452 (with-selected-window (display-buffer buf other-window) 453 (unwind-protect
454 (progn
455 (when xref-w
456 (set-window-dedicated-p xref-w 'soft))
457 ,@body)
458 (when xref-w
459 (set-window-dedicated-p xref-w xref-w-dedicated)))))
460
461(defun xref--show-pos-in-buf (pos buf select)
462 (let ((xref-buf (current-buffer))
463 win)
464 (with-selected-window
465 (xref--with-dedicated-window
466 (display-buffer buf))
453 (xref--goto-char pos) 467 (xref--goto-char pos)
454 (run-hooks 'xref-after-jump-hook) 468 (run-hooks 'xref-after-jump-hook)
455 (let ((buf (current-buffer)) 469 (let ((buf (current-buffer)))
456 (win (selected-window))) 470 (setq win (selected-window))
457 (with-current-buffer xref-buf 471 (with-current-buffer xref-buf
458 (setq-local other-window-scroll-buffer buf) 472 (setq-local other-window-scroll-buffer buf)
459 (xref--save-to-history buf win)))))) 473 (xref--save-to-history buf win))))
474 (when select
475 (select-window win))))
460 476
461(defun xref--show-location (location) 477(defun xref--show-location (location &optional select)
462 (condition-case err 478 (condition-case err
463 (let* ((marker (xref-location-marker location)) 479 (let* ((marker (xref-location-marker location))
464 (buf (marker-buffer marker))) 480 (buf (marker-buffer marker)))
465 (xref--display-position marker t buf)) 481 (xref--show-pos-in-buf marker buf select))
466 (user-error (message (error-message-string err))))) 482 (user-error (message (error-message-string err)))))
467 483
468(defun xref-show-location-at-point () 484(defun xref-show-location-at-point ()
469 "Display the source of xref at point in the other window, if any." 485 "Display the source of xref at point in the appropriate window, if any."
470 (interactive) 486 (interactive)
471 (let* ((xref (xref--item-at-point)) 487 (let* ((xref (xref--item-at-point))
472 (xref--current-item xref)) 488 (xref--current-item xref))
473 (when xref 489 (when xref
474 (xref--show-location (xref-item-location xref))))) 490 ;; Try to avoid the window the current xref buffer was
491 ;; originally created from.
492 (if (window-live-p xref--window)
493 (with-selected-window xref--window
494 (xref--show-location (xref-item-location xref)))
495 (xref--show-location (xref-item-location xref))))))
475 496
476(defun xref-next-line () 497(defun xref-next-line ()
477 "Move to the next xref and display its source in the other window." 498 "Move to the next xref and display its source in the appropriate window."
478 (interactive) 499 (interactive)
479 (xref--search-property 'xref-item) 500 (xref--search-property 'xref-item)
480 (xref-show-location-at-point)) 501 (xref-show-location-at-point))
481 502
482(defun xref-prev-line () 503(defun xref-prev-line ()
483 "Move to the previous xref and display its source in the other window." 504 "Move to the previous xref and display its source in the appropriate window."
484 (interactive) 505 (interactive)
485 (xref--search-property 'xref-item t) 506 (xref--search-property 'xref-item t)
486 (xref-show-location-at-point)) 507 (xref-show-location-at-point))
@@ -491,16 +512,14 @@ WINDOW controls how the buffer is displayed:
491 (get-text-property (point) 'xref-item))) 512 (get-text-property (point) 'xref-item)))
492 513
493(defvar-local xref--window nil 514(defvar-local xref--window nil
494 "ACTION argument to call `display-buffer' with.") 515 "The original window this xref buffer was created from.")
495 516
496(defun xref-goto-xref () 517(defun xref-goto-xref ()
497 "Jump to the xref on the current line and bury the xref buffer." 518 "Jump to the xref on the current line and select its window."
498 (interactive) 519 (interactive)
499 (let ((xref (or (xref--item-at-point) 520 (let ((xref (or (xref--item-at-point)
500 (user-error "No reference at point"))) 521 (user-error "No reference at point"))))
501 (window xref--window)) 522 (xref--show-location (xref-item-location xref) t)))
502 (xref-quit)
503 (xref--pop-to-location xref window)))
504 523
505(defun xref-query-replace-in-results (from to) 524(defun xref-query-replace-in-results (from to)
506 "Perform interactive replacement of FROM with TO in all displayed xrefs. 525 "Perform interactive replacement of FROM with TO in all displayed xrefs.
@@ -573,7 +592,8 @@ references displayed in the current *xref* buffer."
573 current-beg (car pair) 592 current-beg (car pair)
574 current-end (cdr pair) 593 current-end (cdr pair)
575 current-buf (marker-buffer current-beg)) 594 current-buf (marker-buffer current-beg))
576 (pop-to-buffer current-buf) 595 (xref--with-dedicated-window
596 (pop-to-buffer current-buf))
577 (goto-char current-beg) 597 (goto-char current-beg)
578 (when (re-search-forward from current-end noerror) 598 (when (re-search-forward from current-end noerror)
579 (setq found t))) 599 (setq found t)))
@@ -614,7 +634,7 @@ references displayed in the current *xref* buffer."
614 (dotimes (_ n) 634 (dotimes (_ n)
615 (setq xref (xref--search-property 'xref-item backward))) 635 (setq xref (xref--search-property 'xref-item backward)))
616 (cond (xref 636 (cond (xref
617 (xref--pop-to-location xref)) 637 (xref--show-location (xref-item-location xref) t))
618 (t 638 (t
619 (error "No %s xref" (if backward "previous" "next")))))) 639 (error "No %s xref" (if backward "previous" "next"))))))
620 640
@@ -724,15 +744,15 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
724 744
725(defvar xref--read-pattern-history nil) 745(defvar xref--read-pattern-history nil)
726 746
727(defun xref--show-xrefs (xrefs window &optional always-show-list) 747(defun xref--show-xrefs (xrefs display-action &optional always-show-list)
728 (cond 748 (cond
729 ((and (not (cdr xrefs)) (not always-show-list)) 749 ((and (not (cdr xrefs)) (not always-show-list))
730 (xref-push-marker-stack) 750 (xref-push-marker-stack)
731 (xref--pop-to-location (car xrefs) window)) 751 (xref--pop-to-location (car xrefs) display-action))
732 (t 752 (t
733 (xref-push-marker-stack) 753 (xref-push-marker-stack)
734 (funcall xref-show-xrefs-function xrefs 754 (funcall xref-show-xrefs-function xrefs
735 `((window . ,window)))))) 755 `((window . ,(selected-window)))))))
736 756
737(defun xref--prompt-p (command) 757(defun xref--prompt-p (command)
738 (or (eq xref-prompt-for-identifier t) 758 (or (eq xref-prompt-for-identifier t)
@@ -761,16 +781,16 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
761 781
762;;; Commands 782;;; Commands
763 783
764(defun xref--find-xrefs (input kind arg window) 784(defun xref--find-xrefs (input kind arg display-action)
765 (let ((xrefs (funcall (intern (format "xref-backend-%s" kind)) 785 (let ((xrefs (funcall (intern (format "xref-backend-%s" kind))
766 (xref-find-backend) 786 (xref-find-backend)
767 arg))) 787 arg)))
768 (unless xrefs 788 (unless xrefs
769 (user-error "No %s found for: %s" (symbol-name kind) input)) 789 (user-error "No %s found for: %s" (symbol-name kind) input))
770 (xref--show-xrefs xrefs window))) 790 (xref--show-xrefs xrefs display-action)))
771 791
772(defun xref--find-definitions (id window) 792(defun xref--find-definitions (id display-action)
773 (xref--find-xrefs id 'definitions id window)) 793 (xref--find-xrefs id 'definitions id display-action))
774 794
775;;;###autoload 795;;;###autoload
776(defun xref-find-definitions (identifier) 796(defun xref-find-definitions (identifier)