unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Nicolas Richard <youngfrog@members.fsf.org>
To: martin rudalics <rudalics@gmx.at>
Cc: "21649@debbugs.gnu.org" <21649@debbugs.gnu.org>
Subject: bug#21649: 25.0.50; [PATCH] Allow M-x man to reuse an existing window
Date: Tue, 01 Mar 2016 16:49:07 +0100	[thread overview]
Message-ID: <861t7unqq4.fsf@members.fsf.org> (raw)
In-Reply-To: <5629E96C.3090307@gmx.at>

[-- Attachment #1: Type: text/plain, Size: 629 bytes --]

martin rudalics <rudalics@gmx.at> writes:
> (2) Allow to specify the desired (parent) mode via an ALIST ‘mode’
> entry.  As value we could allow a single mode or a list of modes.  Then
> a window showing a buffer in the same mode as the buffer we want to
> display should maybe given preference to a window showing a buffer in
> another mode, derived from the same parent mode.  If a same-mode-window
> exists on another and a derived-mode-window exists on the selected
> frame, one of these should be given preference consistently.

Well, it took a bit of time but here I am ! Could you please review the
following patch ?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-new-function-display-buffer-reuse-mode-window.patch --]
[-- Type: text/x-diff, Size: 5198 bytes --]

From 1623ed372ffce726c4f5b20ca2f333a9e5ba6f92 Mon Sep 17 00:00:00 2001
From: Nicolas Richard <youngfrog@members.fsf.org>
Date: Tue, 1 Mar 2016 12:33:05 +0100
Subject: [PATCH] Add new function display-buffer-reuse-mode-window

* lisp/window.el (display-buffer-reuse-mode-window): New function.
* doc/lispref/windows.texi (Display Action Functions): Document it.
---
 doc/lispref/windows.texi | 17 ++++++++++++
 lisp/window.el           | 68 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)

diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 7186791..c52bf0e 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -2395,6 +2395,23 @@ Display Action Functions
 entry (@pxref{Choosing Window Options}), raises that frame if necessary.
 @end defun
 
+@defun display-buffer-reuse-mode-window buffer alist
+This function tries to display @var{buffer} by finding a window
+that is displaying a buffer in a given mode.
+
+If @var{alist} contains a @code{mode} entry, its value is a major mode
+(a symbol) or a list of major modes.  If @var{alist} contains no
+@code{mode} entry, the current major mode of @var{buffer} is used.  A
+window is a candidate if it displays a buffer that derives from one of
+the given modes.
+
+The behaviour is also controlled by entries for
+@code{inhibit-same-window}, @code{reusable-frames} and
+@code{inhibit-switch-frame} as is done in the function
+@code{display-buffer-reuse-window}.
+
+@end defun
+
 @defun display-buffer-pop-up-frame buffer alist
 This function creates a new frame, and displays the buffer in that
 frame's window.  It actually performs the frame creation by calling
diff --git a/lisp/window.el b/lisp/window.el
index 620f4ed..4586994 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -6721,6 +6721,74 @@ display-buffer-reuse-window
 	(unless (cdr (assq 'inhibit-switch-frame alist))
 	  (window--maybe-raise-frame (window-frame window)))))))
 
+(defun display-buffer-reuse-mode-window (buffer alist)
+  "Return a window based on the mode of the buffer it displays.
+Display BUFFER in the returned window. Return nil if no usable
+window is found.
+
+If ALIST contains a `mode' entry, its value is a major mode (a
+symbol) or a list of modes.  A window is a candidate if it
+displays a buffer that derives from one of the given modes. When
+ALIST contains no `mode' entry, the current major mode of BUFFER
+is used.
+
+The behaviour is also controlled by entries for
+`inhibit-same-window', `reusable-frames' and
+`inhibit-switch-frame' as is done in the function
+`display-buffer-reuse-window'."
+  (let* ((alist-entry (assq 'reusable-frames alist))
+         (alist-mode-entry (assq 'mode alist))
+	 (frames (cond (alist-entry (cdr alist-entry))
+		       ((if (eq pop-up-frames 'graphic-only)
+			    (display-graphic-p)
+			  pop-up-frames)
+			0)
+		       (display-buffer-reuse-frames 0)
+		       (t (last-nonminibuffer-frame))))
+         (inhibit-same-window-p (cdr (assq 'inhibit-same-window alist)))
+	 (windows (window-list-1 nil 'nomini frames))
+         (buffer-mode (with-current-buffer buffer major-mode))
+         (allowed-modes (if alist-mode-entry
+                            (cdr alist-mode-entry)
+                          buffer-mode))
+         (curwin (selected-window))
+         (curframe (selected-frame)))
+    (unless (listp allowed-modes)
+      (setq allowed-modes (list allowed-modes)))
+    (let (same-mode-same-frame
+          same-mode-other-frame
+          derived-mode-same-frame
+          derived-mode-other-frame)
+      (dolist (window windows)
+        (let ((window-mode (with-current-buffer
+                               (window-buffer window)
+                             major-mode))
+              mode? frame?)
+          (setq mode?
+                (cond ((memq window-mode allowed-modes)
+                       'same)
+                      ((let ((major-mode window-mode))
+                         (derived-mode-p allowed-modes))
+                       'derived)))
+          (when (and mode?
+                     (not (and inhibit-same-window-p
+                               (eq window curwin))))
+            (if (eq curframe (window-frame window))
+                (if (eq mode? 'same)
+                    (push window same-mode-same-frame)
+                  (push window derived-mode-same-frame))
+              (if (eq mode? 'same)
+                  (push window same-mode-other-frame)
+                (push window derived-mode-other-frame))))))
+      (let ((window (first (nconc same-mode-same-frame
+                                  same-mode-other-frame
+                                  derived-mode-same-frame
+                                  derived-mode-other-frame))))
+        (when (window-live-p window)
+          (prog1 (window--display-buffer buffer window 'reuse alist)
+            (unless (cdr (assq 'inhibit-switch-frame alist))
+              (window--maybe-raise-frame (window-frame window)))))))))
+
 (defun display-buffer--special-action (buffer)
   "Return special display action for BUFFER, if any.
 If `special-display-p' returns non-nil for BUFFER, return an
-- 
2.4.5


[-- Attachment #3: Type: text/plain, Size: 14 bytes --]


-- 
Nicolas.

  reply	other threads:[~2016-03-01 15:49 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-08 15:54 bug#21649: 25.0.50; [PATCH] Allow M-x man to reuse an existing window Nicolas Richard
2015-10-09 14:37 ` Kaushal Modi
     [not found]   ` <86r3l09t3u.fsf@members.fsf.org>
2015-10-12 15:06     ` Kaushal Modi
2015-10-13 22:10       ` Nicolas Richard
2015-10-13 22:19         ` Kaushal Modi
2015-10-14  8:49           ` martin rudalics
     [not found]             ` <86wpufc8n8.fsf@members.fsf.org>
2015-10-22 15:34               ` martin rudalics
2015-10-22 19:21                 ` Nicolas Richard
2015-10-23  8:01                   ` martin rudalics
2016-03-01 15:49                     ` Nicolas Richard [this message]
2016-03-01 17:04                       ` martin rudalics
2016-03-10  9:55                         ` Nicolas Richard
2016-03-10 10:32                           ` martin rudalics
2016-03-10 13:49                             ` Nicolas Richard
2015-10-27 11:30 ` Nicolas Richard
2015-10-28  9:55   ` martin rudalics

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=861t7unqq4.fsf@members.fsf.org \
    --to=youngfrog@members.fsf.org \
    --cc=21649@debbugs.gnu.org \
    --cc=rudalics@gmx.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).