Package: emacs;
Reported by: Juri Linkov <juri <at> linkov.net>
Date: Wed, 5 Feb 2020 22:42:01 UTC
Severity: normal
Tags: fixed, patch
Fixed in version 28.0.50
Done: Juri Linkov <juri <at> linkov.net>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Juri Linkov <juri <at> linkov.net> To: 39446 <at> debbugs.gnu.org Subject: bug#39446: 28.0.50; Use quit-restore-window to close tab Date: Wed, 05 Feb 2020 23:53:13 +0200
[Message part 1 (text/plain, inline)]
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)
[close-tab-quit-restore-window.patch (text/x-diff, inline)]
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)
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.