[Top][All Lists]

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

[elpa] externals/gnorb 0a138f9 251/449: Reuse existing frames/windows wh

From: Stefan Monnier
Subject: [elpa] externals/gnorb 0a138f9 251/449: Reuse existing frames/windows when following links
Date: Fri, 27 Nov 2020 23:15:49 -0500 (EST)

branch: externals/gnorb
commit 0a138f937ec7f2115fb0d61f0a55c63b1b8ab1dc
Author: Eric Abrahamsen <eric@ericabrahamsen.net>
Commit: Eric Abrahamsen <eric@ericabrahamsen.net>

    Reuse existing frames/windows when following links
    When opening a Gnus link to start a reply, try not to open extra windows
    if the buffers in question are already visible somewhere.
    * lisp/gnorb-utils.el (gnorb-open-gnus-link): New function for locating
      the right frame/window to open a link in.
    * lisp/gnorb-org.el (gnorb-org-setup-message): Use the new function.
 gnorb-org.el   | 28 +++++++++++-----------------
 gnorb-utils.el | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 17 deletions(-)

diff --git a/gnorb-org.el b/gnorb-org.el
index 86dba6e..a27cc1f 100644
--- a/gnorb-org.el
+++ b/gnorb-org.el
@@ -256,26 +256,20 @@ headings."
   (require 'gnorb-gnus)
   (if (not messages)
       ;; Either compose new message...
-      (compose-mail (mapconcat 'identity mails ", "))
+      (compose-mail)
     ;; ...or follow link and start reply.
     (condition-case err
-       (let ((ret-val (org-gnus-open (org-link-unescape (car messages)))))
-         ;; We failed to open the link (probably), ret-val would be
-         ;; t otherwise
-         (when (stringp ret-val)
-           (error ret-val))
+       (progn
+         (gnorb-open-gnus-link (car messages))
-          'gnus-summary-wide-reply-with-original)
-         ;; Add MAILS to message To header.
-         (when mails
-           (message-goto-to)
-           (insert ", ")
-           (insert (mapconcat 'identity mails ", "))))
-      (error (when (and (window-configuration-p gnorb-window-conf)
-                       gnorb-return-marker)
-              (set-window-configuration gnorb-window-conf)
-              (goto-char gnorb-return-marker))
+         'gnus-summary-wide-reply-with-original))
+      (error (gnorb-restore-layout)
             (signal (car err) (cdr err)))))
+  ;; Add MAILS to message To header.
+  (when mails
+    (message-goto-to)
+    (insert ", ")
+    (insert (mapconcat 'identity mails ", ")))
   ;; Return us after message is sent.
   (add-to-list 'message-exit-actions
               'gnorb-org-restore-after-send t)
@@ -324,7 +318,7 @@ headings."
   (if (or mails messages)
       (if (not messages)
-       (message-goto-body))
+       (message-goto-body))
   (run-hooks 'gnorb-org-after-message-setup-hook))
diff --git a/gnorb-utils.el b/gnorb-utils.el
index bbb2211..880e571 100644
--- a/gnorb-utils.el
+++ b/gnorb-utils.el
@@ -116,6 +116,57 @@ and Gnus and BBDB maps."
     (when (buffer-live-p (marker-buffer gnorb-return-marker))
       (goto-char gnorb-return-marker))))
+(defun gnorb-open-gnus-link (link)
+  "Be a little clever about following gnus links.
+The goal here is reuse frames and windows as much as possible, so
+we're not opening multiple windows on the *Group* buffer, for
+instance, and messing up people's layouts. There also seems to be
+an issue when opening a link to a message whose *Summary* buffer
+is already visible: somehow, after following the link, point ends
+up on the message _after_ the one we want, and things go haywire.
+So we try to be a little clever. The logical progression here is
+1. If the link's target group is already open in a *Summary*
+buffer, just switch to that buffer (if it's visible in any frame
+then raise it and switch focus, otherwise pull it into the
+current window) and go to the message with
+2. If the Gnus *Group* buffer is visible in any window or frame,
+raise that frame/window and give it focus before following the
+3. Otherwise just follow the link as usual, in the current
+  (let* ((link (org-link-unescape link))
+        (group (car (org-split-string link "#")))
+        (id (second (org-split-string link "#")))
+        (sum-buffer (gnus-summary-buffer-name group))
+        (target-buffer
+         (cond
+          ((gnus-buffer-exists-p sum-buffer)
+           sum-buffer)
+          ((gnus-buffer-exists-p gnus-group-buffer)
+           gnus-group-buffer)
+          (t nil)))
+        (target-window (when target-buffer
+                         (get-buffer-window target-buffer t))))
+    (if target-window
+       ;; Our target buffer is displayed somewhere: just go there.
+       (progn
+         (select-frame-set-input-focus
+          (window-frame target-window))
+         (switch-to-buffer target-buffer))
+      ;; Our target buffer exists, but isn't displayed: pull it up.
+      (if target-buffer
+         (switch-to-buffer target-buffer)))
+    (if (gnus-buffer-exists-p sum-buffer)
+       (gnus-summary-goto-article id nil t)
+      (org-gnus-open link))))
 (defun gnorb-trigger-todo-action (arg &optional id)
   "Do the actual restore action. Two main things here. First: if
 we were in the agenda when this was called, then keep us in the

reply via email to

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