From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: joaotavora@gmail.com (=?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?=) Newsgroups: gmane.emacs.bugs Subject: bug#28814: 26.0.90; When *xref* window is needed, original window-switching intent is lost Date: Fri, 13 Oct 2017 17:07:36 +0100 Message-ID: <87infjm3p3.fsf@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1507910908 20175 195.159.176.226 (13 Oct 2017 16:08:28 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 13 Oct 2017 16:08:28 +0000 (UTC) To: 28814@debbugs.gnu.org, dgutov@yandex.ru Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Oct 13 18:08:24 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e32VK-0002rS-Jp for geb-bug-gnu-emacs@m.gmane.org; Fri, 13 Oct 2017 18:08:06 +0200 Original-Received: from localhost ([::1]:50955 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e32VR-0005KJ-MB for geb-bug-gnu-emacs@m.gmane.org; Fri, 13 Oct 2017 12:08:13 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36997) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e32VK-0005K2-MG for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 12:08:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e32VH-00029J-5A for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 12:08:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:57839) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e32VG-00029D-Vp for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 12:08:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1e32VG-0005QJ-NZ for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 12:08:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: joaotavora@gmail.com (=?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?=) Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 13 Oct 2017 16:08:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 28814 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: X-Debbugs-Original-To: bug-gnu-emacs@gnu.org, dgutov@yandex.ru Original-Received: via spool by submit@debbugs.gnu.org id=B.150791088020837 (code B ref -1); Fri, 13 Oct 2017 16:08:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 13 Oct 2017 16:08:00 +0000 Original-Received: from localhost ([127.0.0.1]:38287 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e32VB-0005Pz-GV for submit@debbugs.gnu.org; Fri, 13 Oct 2017 12:07:57 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:45984) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e32V9-0005Pj-0j for submit@debbugs.gnu.org; Fri, 13 Oct 2017 12:07:55 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e32V2-00025d-7X for submit@debbugs.gnu.org; Fri, 13 Oct 2017 12:07:49 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:55741) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e32V2-00025U-1S for submit@debbugs.gnu.org; Fri, 13 Oct 2017 12:07:48 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36936) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e32V0-0005IZ-01 for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 12:07:47 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e32Uw-00023b-Q6 for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 12:07:45 -0400 Original-Received: from mail-wr0-x22a.google.com ([2a00:1450:400c:c0c::22a]:56532) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e32Uw-00022o-Cy for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 12:07:42 -0400 Original-Received: by mail-wr0-x22a.google.com with SMTP id r79so1395857wrb.13 for ; Fri, 13 Oct 2017 09:07:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version; bh=hUml4e8VmZkFLaI0DuMwzEiipXP8F2WjyjHswnXKxoM=; b=WGBQUg87ow3tKT6jqlCc9E4V1YB010Dn/W+L7ByBPeyijnWUojqHsQo9aoadWjep7J Po9umFRgWHnYrm6V7kj4w05zmlJdzRg2bWfqLorjdqSFf5+1we4v1QqntHqD9chvEIqn +R1M4moskAaD4uSftzzPIera8kgpHLaBQolH+uCJaf9y5fIdzDxYgEC5qs9U3X7DI0bB s5jOoCaTGZBEwbhJzjSQQhB/UwokuYQMtqbWrbkm4UL4CNj3vRWfIo2sQAzhOs/Si4WB YtvR1cUsx90S7iJr8vosG/RAJv2l+fUcRKkjmBAtE6jbYGMqaKWL9/5MJXeWrt12kS5Y RJKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version; bh=hUml4e8VmZkFLaI0DuMwzEiipXP8F2WjyjHswnXKxoM=; b=rNI7AiwM0gplG4SwMGS8vyc+rYFzlzIpZZklWNDpdNATZn+eh08syCXIdtxyIzrmfT rXhkkrzftYaXVjWogmPRnoy+DJbmiktpfBceK8+8wpIWeKUpoUGOVw0YZ/aDROgjFRfC l+gvYQ8D3hzAkyvHf30oj5go7lkc9990hj+D8PQ93LpKOHrFbBV8RCH/gBsXQDinfIGH LCkq83OhkxBoGN9DRjVesgRw22RAcCpa0xkK006A+vJQMforFrYZ4kkZhl00MOXsE8bk RLB/WnjdPQbNscx02g9dL7dzSW98xEr/elOSIaV59WqvHxatitMtq6t1Jx6kUZRRqXtX 176A== X-Gm-Message-State: AMCzsaW8P6vmy4pNh/pkJVUVUr2bu/NBsfasVhCZkSL8PIlXNc2asaGt 3DCxhPSr1nfQpVnEUYbOS9Y= X-Google-Smtp-Source: AOwi7QBFrhGJ4Nm61kegV7MF81faXHr+qQqWxbX5VDJXOPHGByJPnY5kPifSNtpfCDD3Pp4XFO16+g== X-Received: by 10.223.151.143 with SMTP id s15mr2062285wrb.7.1507910860006; Fri, 13 Oct 2017 09:07:40 -0700 (PDT) Original-Received: from lolita.yourcompany.com (188.139.62.94.rev.vodafone.pt. [94.62.139.188]) by smtp.gmail.com with ESMTPSA id r44sm1658045wrb.37.2017.10.13.09.07.38 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 13 Oct 2017 09:07:38 -0700 (PDT) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:138349 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Dmitry, maintainters, Here are two patches to fix what I believe is a small but annoying bug in xref.el. I'll try to explain as clearly as possible: As you know, if the user presses 'M-.' in a single-ref definition, he/she is transported to a new buffer. But there are other situations: when xref-find-definitions finds more than one definition, a list is shown in an *xref* buffer, normally in a new window. When the user selects an "xref" with xref-goto-xref, a buffer and window switch happen. Anyway, so far so good. The problem is there is also 'C-x 4 .' and 'C-x 5 .' for xref-find-definitions-other-window and xref-find-definitions-other-frame respectively. These work just fine when an *xref* buffer isn't needed, but when it is, the original intent of using another window or frame will be lost when the user eventually selects a definition. It shouldn't be so, in my opinion. The first patch I attach (0001-Honor-window....patch) fixes this bug. I hope it is readable enough but I can explain how it works in detail. I also attach a second patch (0002-Quit-the....patch), that does not really fix a bug, but changes the behavior of xref-goto-xref to something much nicer: it quits the *xref* window before going to the reference. This brings a nice result: As always 'M-.' switches buffers if there is only one definition. Now, if there is more than one, the final state after selecting one of these definitions is the same as if there had only been one in the first place. I think this makes sense because it preserves the expectations of the user who probably wants M-. to behave as predictably as possible. Here's hoping you're not really confused by this report, Jo=C3=A3o --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-Honor-window-switching-intents-in-xref-find-definiti.patch >From 1cba860d6a2c45e0fa690065b2bf4e6658e87628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Fri, 13 Oct 2017 15:13:14 +0100 Subject: [PATCH 1/2] Honor window-switching intents in xref-find-definitions When there is more than one xref to jump to, and an *xref* window appears to help the user choose, the original intent to open a definition another window or frame is remembered when the choice to go to or show a reference is finally made. * lisp/progmodes/xref.el (xref--show-pos-in-buf): Rewrite. (xref--original-window-intent): New variable. (xref--original-window): Rename from xref--window and move up here for clarity. (xref--show-pos-in-buf): Rewrite. Don't take SELECT arg here. (xref--show-location): Handle window selection decision here. (xref--window): Rename to xref--original-window. (xref-show-location-at-point): Don't attempt window management here. (xref--show-xrefs): Ensure display-action intent is saved. --- lisp/progmodes/xref.el | 73 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 80cdcb3f18..768fa15a6b 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -449,43 +449,72 @@ xref--with-dedicated-window (when xref-w (set-window-dedicated-p xref-w xref-w-dedicated))))) -(defun xref--show-pos-in-buf (pos buf select) - (let ((xref-buf (current-buffer)) - win) +(defvar-local xref--original-window-intent nil + "Original window-switching intent before xref buffer creation.") + +(defvar-local xref--original-window nil + "The original window this xref buffer was created from.") + +(defun xref--show-pos-in-buf (pos buf) + "Goto and display position POS of buffer BUF in a window. +Honour `xref--original-window-intent', run `xref-after-jump-hook' +and finally return the window." + (let* ((xref-buf (current-buffer)) + (pop-up-frames + (or (eq xref--original-window-intent 'frame) + pop-up-frames)) + (action + (cond ((memq + xref--original-window-intent + '(window frame)) + t) + ((and + (window-live-p xref--original-window) + (or (not (window-dedicated-p xref--original-window)) + (eq (window-buffer xref--original-window) buf))) + `(,(lambda (buf _alist) + (set-window-buffer xref--original-window buf) + xref--original-window)))))) (with-selected-window - (xref--with-dedicated-window - (display-buffer buf)) + (with-selected-window + ;; Just before `display-buffer', place ourselves in the + ;; original window to suggest preserving it. Of course, if + ;; user has deleted the original window, all bets are off, + ;; just use the selected one. + (or (and (window-live-p xref--original-window) + xref--original-window) + (selected-window)) + (display-buffer buf action)) (xref--goto-char pos) (run-hooks 'xref-after-jump-hook) (let ((buf (current-buffer))) - (setq win (selected-window)) (with-current-buffer xref-buf - (setq-local other-window-scroll-buffer buf)))) - (when select - (select-window win)))) + (setq-local other-window-scroll-buffer buf))) + (selected-window)))) (defun xref--show-location (location &optional select) (condition-case err (let* ((marker (xref-location-marker location)) (buf (marker-buffer marker))) - (xref--show-pos-in-buf marker buf select)) + (cond (select + (select-window (xref--show-pos-in-buf marker buf))) + (t + (save-selected-window + (xref--with-dedicated-window + (let (;; save-selected-window doesn't resist frame + ;; raises + (display-buffer-overriding-action + '(nil . ((inhibit-switch-frame . t))))) + (xref--show-pos-in-buf marker buf))))))) (user-error (message (error-message-string err))))) -(defvar-local xref--window nil - "The original window this xref buffer was created from.") - (defun xref-show-location-at-point () "Display the source of xref at point in the appropriate window, if any." (interactive) (let* ((xref (xref--item-at-point)) (xref--current-item xref)) (when xref - ;; Try to avoid the window the current xref buffer was - ;; originally created from. - (if (window-live-p xref--window) - (with-selected-window xref--window - (xref--show-location (xref-item-location xref))) - (xref--show-location (xref-item-location xref)))))) + (xref--show-location (xref-item-location xref))))) (defun xref-next-line () "Move to the next xref and display its source in the appropriate window." @@ -727,7 +756,8 @@ xref--show-xref-buffer (xref--xref-buffer-mode) (pop-to-buffer (current-buffer)) (goto-char (point-min)) - (setq xref--window (assoc-default 'window alist)) + (setq xref--original-window (assoc-default 'window alist) + xref--original-window-intent (assoc-default 'display-action alist)) (current-buffer))))) @@ -754,7 +784,8 @@ xref--show-xrefs (t (xref-push-marker-stack) (funcall xref-show-xrefs-function xrefs - `((window . ,(selected-window))))))) + `((window . ,(selected-window)) + (display-action . ,display-action)))))) (defun xref--prompt-p (command) (or (eq xref-prompt-for-identifier t) -- 2.11.0 --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0002-Quit-the-xref-window-if-user-decides-to-go-to-a-ref.patch >From 228cb812197bd68b2fb6eccc60d7956675a728f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Fri, 13 Oct 2017 16:37:47 +0100 Subject: [PATCH 2/2] Quit the *xref* window if user decides to go to a ref * lisp/progmodes/xref.el (xref--show-location): When SELECT is t, quit window. --- lisp/progmodes/xref.el | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 768fa15a6b..3a5e9e53ed 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -495,9 +495,12 @@ xref--show-pos-in-buf (defun xref--show-location (location &optional select) (condition-case err (let* ((marker (xref-location-marker location)) - (buf (marker-buffer marker))) + (buf (marker-buffer marker)) + (xref-buffer (current-buffer))) (cond (select - (select-window (xref--show-pos-in-buf marker buf))) + (quit-window nil nil) + (with-current-buffer xref-buffer + (select-window (xref--show-pos-in-buf marker buf)))) (t (save-selected-window (xref--with-dedicated-window -- 2.11.0 --=-=-=--