1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-03 10:31:37 -08:00

The key prefix 'C-x t t' displays next command buffer in a new tab (bug#41691)

* lisp/tab-bar.el (other-tab-prefix): New command.
(tab-prefix-map): Bind key 'C-x t t' to other-tab-prefix.

* lisp/windmove.el (windmove-display-in-direction):
Use display-buffer-override-next-command.

* lisp/window.el (display-buffer-override-next-command):
New function refactored from windmove-display-in-direction.
This commit is contained in:
Juri Linkov 2020-06-07 02:42:24 +03:00
parent 7ac79872ae
commit 788cd6d8b9
4 changed files with 97 additions and 54 deletions

View file

@ -109,6 +109,10 @@ setting the variable 'auto-save-visited-mode' buffer-locally to nil.
* Changes in Specialized Modes and Packages in Emacs 28.1 * Changes in Specialized Modes and Packages in Emacs 28.1
** Tab Bars
*** The key prefix 'C-x t t' displays next command buffer in a new tab.
** New bindings in occur-mode, 'next-error-no-select' bound to 'n' and ** New bindings in occur-mode, 'next-error-no-select' bound to 'n' and
'previous-error-no-select' bound to 'p'. 'previous-error-no-select' bound to 'p'.

View file

@ -1575,6 +1575,25 @@ Like \\[find-file-other-frame] (which see), but creates a new tab."
value) value)
(switch-to-buffer-other-tab value)))) (switch-to-buffer-other-tab value))))
(defun other-tab-prefix ()
"Display the buffer of the next command in a new tab.
The next buffer is the buffer displayed by the next command invoked
immediately after this command (ignoring reading from the minibuffer).
Creates a new tab before displaying the buffer, or switches to the tab
that already contains that buffer.
When `switch-to-buffer-obey-display-actions' is non-nil,
`switch-to-buffer' commands are also supported."
(interactive)
(display-buffer-override-next-command
(lambda (buffer alist)
(cons (progn
(display-buffer-in-tab
buffer (append alist '((inhibit-same-window . nil)
(reusable-frames . t))))
(selected-window))
'tab)))
(message "Display next command buffer in a new tab..."))
(define-key tab-prefix-map "2" 'tab-new) (define-key tab-prefix-map "2" 'tab-new)
(define-key tab-prefix-map "1" 'tab-close-other) (define-key tab-prefix-map "1" 'tab-close-other)
(define-key tab-prefix-map "0" 'tab-close) (define-key tab-prefix-map "0" 'tab-close)
@ -1585,6 +1604,7 @@ Like \\[find-file-other-frame] (which see), but creates a new tab."
(define-key tab-prefix-map "b" 'switch-to-buffer-other-tab) (define-key tab-prefix-map "b" 'switch-to-buffer-other-tab)
(define-key tab-prefix-map "f" 'find-file-other-tab) (define-key tab-prefix-map "f" 'find-file-other-tab)
(define-key tab-prefix-map "\C-f" 'find-file-other-tab) (define-key tab-prefix-map "\C-f" 'find-file-other-tab)
(define-key tab-prefix-map "t" 'other-tab-prefix)
(provide 'tab-bar) (provide 'tab-bar)

View file

@ -461,60 +461,38 @@ select the window with a displayed buffer, and the meaning of
the prefix argument is reversed. the prefix argument is reversed.
When `switch-to-buffer-obey-display-actions' is non-nil, When `switch-to-buffer-obey-display-actions' is non-nil,
`switch-to-buffer' commands are also supported." `switch-to-buffer' commands are also supported."
(let* ((no-select (xor (consp arg) windmove-display-no-select)) (let ((no-select (xor (consp arg) windmove-display-no-select)))
(old-window (or (minibuffer-selected-window) (selected-window))) (display-buffer-override-next-command
(new-window) (lambda (_buffer alist)
(minibuffer-depth (minibuffer-depth)) (let* ((type 'reuse)
(action (lambda (buffer alist) (window (cond
(unless (> (minibuffer-depth) minibuffer-depth) ((eq dir 'new-tab)
(let* ((type 'reuse) (let ((tab-bar-new-tab-choice t))
(window (cond (tab-bar-new-tab))
((eq dir 'new-tab) (setq type 'tab)
(let ((tab-bar-new-tab-choice t)) (selected-window))
(tab-bar-new-tab)) ((eq dir 'new-frame)
(setq type 'tab) (let* ((params (cdr (assq 'pop-up-frame-parameters alist)))
(selected-window)) (pop-up-frame-alist (append params pop-up-frame-alist))
((eq dir 'new-frame) (frame (make-frame-on-current-monitor
(let* ((params (cdr (assq 'pop-up-frame-parameters alist))) pop-up-frame-alist)))
(pop-up-frame-alist (append params pop-up-frame-alist)) (unless (cdr (assq 'inhibit-switch-frame alist))
(frame (make-frame-on-current-monitor (window--maybe-raise-frame frame))
pop-up-frame-alist))) (setq type 'frame)
(unless (cdr (assq 'inhibit-switch-frame alist)) (frame-selected-window frame)))
(window--maybe-raise-frame frame)) ((eq dir 'same-window)
(setq type 'frame) (selected-window))
(frame-selected-window frame))) (t (window-in-direction
((eq dir 'same-window) dir nil nil
(selected-window)) (and arg (prefix-numeric-value arg))
(t (window-in-direction windmove-wrap-around)))))
dir nil nil (unless window
(and arg (prefix-numeric-value arg)) (setq window (split-window nil nil dir) type 'window))
windmove-wrap-around))))) (cons window type)))
(unless window (lambda (old-window new-window)
(setq window (split-window nil nil dir) type 'window)) (when (window-live-p (if no-select old-window new-window))
(setq new-window (window--display-buffer buffer window (select-window (if no-select old-window new-window))))))
type alist)))))) (message "[display-%s]" dir))
(command this-command)
(clearfun (make-symbol "clear-display-buffer-overriding-action"))
(exitfun
(lambda ()
(setq display-buffer-overriding-action
(delq action display-buffer-overriding-action))
(when (window-live-p (if no-select old-window new-window))
(select-window (if no-select old-window new-window)))
(remove-hook 'post-command-hook clearfun))))
(fset clearfun
(lambda ()
(unless (or
;; Remove the hook immediately
;; after exiting the minibuffer.
(> (minibuffer-depth) minibuffer-depth)
;; But don't remove immediately after
;; adding the hook by the same command below.
(eq this-command command))
(funcall exitfun))))
(add-hook 'post-command-hook clearfun)
(push action display-buffer-overriding-action)
(message "[display-%s]" dir)))
;;;###autoload ;;;###autoload
(defun windmove-display-left (&optional arg) (defun windmove-display-left (&optional arg)

View file

@ -8578,6 +8578,47 @@ documentation for additional customization information."
(interactive (interactive
(list (read-buffer-to-switch "Switch to buffer in other frame: "))) (list (read-buffer-to-switch "Switch to buffer in other frame: ")))
(pop-to-buffer buffer-or-name display-buffer--other-frame-action norecord)) (pop-to-buffer buffer-or-name display-buffer--other-frame-action norecord))
(defun display-buffer-override-next-command (pre-function &optional post-function)
"Set `display-buffer-overriding-action' for the next command.
`pre-function' is called to prepare the window where the buffer should be
displayed. This function takes two arguments `buffer' and `alist', and
should return a cons with the displayed window and its type. See the
meaning of these values in `window--display-buffer'.
Optional `post-function' is called after the buffer is displayed in the
window; the function takes two arguments: an old and new window."
(let* ((old-window (or (minibuffer-selected-window) (selected-window)))
(new-window nil)
(minibuffer-depth (minibuffer-depth))
(action (lambda (buffer alist)
(unless (> (minibuffer-depth) minibuffer-depth)
(let* ((ret (funcall pre-function buffer alist))
(window (car ret))
(type (cdr ret)))
(setq new-window (window--display-buffer buffer window
type alist))))))
(command this-command)
(clearfun (make-symbol "clear-display-buffer-overriding-action"))
(exitfun
(lambda ()
(setq display-buffer-overriding-action
(delq action display-buffer-overriding-action))
(remove-hook 'post-command-hook clearfun)
(when (functionp post-function)
(funcall post-function old-window new-window)))))
(fset clearfun
(lambda ()
(unless (or
;; Remove the hook immediately
;; after exiting the minibuffer.
(> (minibuffer-depth) minibuffer-depth)
;; But don't remove immediately after
;; adding the hook by the same command below.
(eq this-command command))
(funcall exitfun))))
(add-hook 'post-command-hook clearfun)
(push action display-buffer-overriding-action)))
(defun set-window-text-height (window height) (defun set-window-text-height (window height)
"Set the height in lines of the text display area of WINDOW to HEIGHT. "Set the height in lines of the text display area of WINDOW to HEIGHT.