unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#39446: 28.0.50; Use quit-restore-window to close tab
@ 2020-02-05 21:53 Juri Linkov
  2020-02-06  3:32 ` Eli Zaretskii
  0 siblings, 1 reply; 5+ messages in thread
From: Juri Linkov @ 2020-02-05 21:53 UTC (permalink / raw)
  To: 39446

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

Version: 28.0.50
Tags: patch

The same way as quit-window deletes the frame
when quitting the last window on the frame with e.g.

  C-x 5 d RET q

this patch implements the same behavior for tabs:

  C-x t d RET q

closes the tab.

This is for master since it will take time to tweak.
For example, it works fine everywhere except Gnus
that doesn't call quit-window when exiting a summary buffer
typing `q' (gnus-summary-exit) in a summary buffer
that was automatically displayed in a new tab,
so needed to customize Gnus by

  (add-hook 'gnus-summary-exit-hook 'quit-window)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: close-tab-quit-restore-window.patch --]
[-- Type: text/x-diff, Size: 4870 bytes --]

diff --git a/lisp/window.el b/lisp/window.el
index 40c4bf5ad4..bd825c09e1 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -5008,6 +5008,13 @@ quit-restore-window
 		 prev-buffer)))
 	 quad entry)
     (cond
+     ((and (not prev-buffer)
+	   (eq (nth 1 quit-restore) 'tab)
+	   (eq (nth 3 quit-restore) buffer))
+      (tab-bar-close-tab)
+      ;; If the previously selected window is still alive, select it.
+      (when (window-live-p (nth 2 quit-restore))
+	(select-window (nth 2 quit-restore))))
      ((and (not prev-buffer)
 	   (or (eq (nth 1 quit-restore) 'frame)
 	       (and (eq (nth 1 quit-restore) 'window)
@@ -6367,7 +6374,12 @@ display-buffer-record-window
     ;; WINDOW has been created on a new frame.
     (set-window-parameter
      window 'quit-restore
-     (list 'frame 'frame (selected-window) buffer)))))
+     (list 'frame 'frame (selected-window) buffer)))
+   ((eq type 'tab)
+    ;; WINDOW has been created on a new tab.
+    (set-window-parameter
+     window 'quit-restore
+     (list 'tab 'tab (selected-window) buffer)))))
 
 (defcustom display-buffer-function nil
   "If non-nil, function to call to handle `display-buffer'.
@@ -7034,7 +7046,7 @@ window--display-buffer
        ;; use that.
        (display-buffer-mark-dedicated
         (set-window-dedicated-p window display-buffer-mark-dedicated))))
-    (when (memq type '(window frame))
+    (when (memq type '(window frame tab))
       (set-window-prev-buffers window nil))
     (let ((quit-restore (window-parameter window 'quit-restore))
 	  (height (cdr (assq 'window-height alist)))
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index ebb0c566ad..d761000993 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -1480,26 +1479,55 @@ display-buffer-in-tab
             (tab-bar-select-tab (1+ index)))
           (when (get-buffer-window buffer frame)
             (select-window (get-buffer-window buffer frame))))
+      (let ((tab-name (alist-get 'tab-name alist)))
+        (when (functionp tab-name)
+          (setq tab-name (funcall tab-name buffer alist)))
+        (if tab-name
+            (let ((tab-index (tab-bar--tab-index-by-name tab-name)))
+              (if tab-index
+                  (progn
+                    (tab-bar-select-tab (1+ tab-index))
+                    (when (get-buffer-window buffer)
+                      (select-window (get-buffer-window buffer))))
+                (display-buffer-in-new-tab buffer alist)))
+          (display-buffer-in-new-tab buffer alist))))))
+
+(defun display-buffer-in-new-tab (buffer alist)
+  "Display BUFFER in a new tab.
+ALIST is an association list of action symbols and values.  See
+Info node `(elisp) Buffer Display Action Alists' for details of
+such alists.
+
+Like `display-buffer-in-tab', but always creates a new tab unconditionally,
+without checking if a suitable tab already exists.
+
+If ALIST contains a `tab-name' entry, it creates a new tab with that name
+and displays BUFFER in a new tab.  The `tab-name' entry can be a function,
+then it is called with two arguments: BUFFER and ALIST, and should return
+the tab name.  When a `tab-name' entry is omitted, create a new tab without
+an explicit name.
+
+This is an action function for buffer display, see Info
+node `(elisp) Buffer Display Action Functions'.  It should be
+called only by `display-buffer' or a function directly or
+indirectly called by the latter."
+  (let ((tab-bar-new-tab-choice t))
+    (tab-bar-new-tab)
+    (let ((tab-name (alist-get 'tab-name alist)))
       (when (functionp tab-name)
         (setq tab-name (funcall tab-name buffer alist)))
-      (if tab-name
-          (let ((tab-index (tab-bar--tab-index-by-name tab-name)))
-            (if tab-index
-                (tab-bar-select-tab (1+ tab-index))
-              (let ((tab-bar-new-tab-choice t))
-                (tab-bar-new-tab)
-                (tab-bar-rename-tab tab-name))))
-        (let ((tab-bar-new-tab-choice t))
-          (tab-bar-new-tab))))))
+      (when tab-name
+        (tab-bar-rename-tab tab-name)))
+    (window--display-buffer buffer (selected-window) 'tab alist)))
 
 (defun switch-to-buffer-other-tab (buffer-or-name &optional norecord)
   "Switch to buffer BUFFER-OR-NAME in another tab.
 Like \\[switch-to-buffer-other-frame] (which see), but creates a new tab."
   (interactive
    (list (read-buffer-to-switch "Switch to buffer in other tab: ")))
-  (display-buffer buffer-or-name '((display-buffer-in-tab
-                                    display-buffer-same-window)
-                                   (inhibit-same-window . nil))
+  (display-buffer buffer-or-name '((display-buffer-in-tab)
+                                   (inhibit-same-window . nil)
+                                   (reusable-frames . t))
                   norecord))
 
 (defun find-file-other-tab (filename &optional wildcards)

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* bug#39446: 28.0.50; Use quit-restore-window to close tab
  2020-02-05 21:53 bug#39446: 28.0.50; Use quit-restore-window to close tab Juri Linkov
@ 2020-02-06  3:32 ` Eli Zaretskii
  2020-02-07  0:17   ` Juri Linkov
  0 siblings, 1 reply; 5+ messages in thread
From: Eli Zaretskii @ 2020-02-06  3:32 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39446

> From: Juri Linkov <juri@linkov.net>
> Date: Wed, 05 Feb 2020 23:53:13 +0200
> 
> The same way as quit-window deletes the frame
> when quitting the last window on the frame with e.g.
> 
>   C-x 5 d RET q

This doesn't delete the frame here.  Is the key sequence above
correct?  If so, can you show a detailed use case where such
deletion-on-quit happens?

Thanks.





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#39446: 28.0.50; Use quit-restore-window to close tab
  2020-02-06  3:32 ` Eli Zaretskii
@ 2020-02-07  0:17   ` Juri Linkov
  2020-02-07  8:07     ` Eli Zaretskii
  0 siblings, 1 reply; 5+ messages in thread
From: Juri Linkov @ 2020-02-07  0:17 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 39446

>> The same way as quit-window deletes the frame
>> when quitting the last window on the frame with e.g.
>>
>>   C-x 5 d RET q
>
> This doesn't delete the frame here.  Is the key sequence above
> correct?  If so, can you show a detailed use case where such
> deletion-on-quit happens?

Indeed.  I thought that it deletes the frame, but it only
minimizes/buries/hides the frame.

The frame is deleted only when quit-window is called
with a prefix arg, e.g.

  C-x 5 d RET C-u q

Since there is no such thing as tab minimizing,
it should be fine to just close the tab.





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#39446: 28.0.50; Use quit-restore-window to close tab
  2020-02-07  0:17   ` Juri Linkov
@ 2020-02-07  8:07     ` Eli Zaretskii
  2020-02-09  0:35       ` Juri Linkov
  0 siblings, 1 reply; 5+ messages in thread
From: Eli Zaretskii @ 2020-02-07  8:07 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39446

> From: Juri Linkov <juri@linkov.net>
> Cc: 39446@debbugs.gnu.org
> Date: Fri, 07 Feb 2020 02:17:45 +0200
> 
> The frame is deleted only when quit-window is called
> with a prefix arg, e.g.
> 
>   C-x 5 d RET C-u q
> 
> Since there is no such thing as tab minimizing,
> it should be fine to just close the tab.

But I think 'q' here is not the important part, because in most major
modes it just inserts 'q'.  You are saying that quit-window, when
called with KILL argument non-nil, will close the tab if this is the
last window in that tab's window-configuration, is that right?





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#39446: 28.0.50; Use quit-restore-window to close tab
  2020-02-07  8:07     ` Eli Zaretskii
@ 2020-02-09  0:35       ` Juri Linkov
  0 siblings, 0 replies; 5+ messages in thread
From: Juri Linkov @ 2020-02-09  0:35 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 39446

>> The frame is deleted only when quit-window is called
>> with a prefix arg, e.g.
>>
>>   C-x 5 d RET C-u q
>>
>> Since there is no such thing as tab minimizing,
>> it should be fine to just close the tab.
>
> But I think 'q' here is not the important part, because in most major
> modes it just inserts 'q'.  You are saying that quit-window, when
> called with KILL argument non-nil, will close the tab if this is the
> last window in that tab's window-configuration, is that right?

Right, this is what I meant.





^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-02-09  0:35 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-02-05 21:53 bug#39446: 28.0.50; Use quit-restore-window to close tab Juri Linkov
2020-02-06  3:32 ` Eli Zaretskii
2020-02-07  0:17   ` Juri Linkov
2020-02-07  8:07     ` Eli Zaretskii
2020-02-09  0:35       ` Juri Linkov

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).