aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2020-06-07 02:42:24 +0300
committerJuri Linkov2020-06-07 02:42:24 +0300
commit788cd6d8b98c0e7750e478ae84e580f29576b5ff (patch)
tree46c566e2e9e89003d4ba2555c3c8e6c56151cdcf
parent7ac79872aed63110c0d26c1e62e1838d6101c9bd (diff)
downloademacs-788cd6d8b98c0e7750e478ae84e580f29576b5ff.tar.gz
emacs-788cd6d8b98c0e7750e478ae84e580f29576b5ff.zip
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.
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/tab-bar.el20
-rw-r--r--lisp/windmove.el86
-rw-r--r--lisp/window.el41
4 files changed, 97 insertions, 54 deletions
diff --git a/etc/NEWS b/etc/NEWS
index edad5b37d6c..6e94d4a91ba 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -109,6 +109,10 @@ setting the variable 'auto-save-visited-mode' buffer-locally to nil.
109 109
110* Changes in Specialized Modes and Packages in Emacs 28.1 110* Changes in Specialized Modes and Packages in Emacs 28.1
111 111
112** Tab Bars
113
114*** The key prefix 'C-x t t' displays next command buffer in a new tab.
115
112** New bindings in occur-mode, 'next-error-no-select' bound to 'n' and 116** New bindings in occur-mode, 'next-error-no-select' bound to 'n' and
113'previous-error-no-select' bound to 'p'. 117'previous-error-no-select' bound to 'p'.
114 118
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 76e7f8c33a2..eb3ad72db43 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -1575,6 +1575,25 @@ Like \\[find-file-other-frame] (which see), but creates a new tab."
1575 value) 1575 value)
1576 (switch-to-buffer-other-tab value)))) 1576 (switch-to-buffer-other-tab value))))
1577 1577
1578(defun other-tab-prefix ()
1579 "Display the buffer of the next command in a new tab.
1580The next buffer is the buffer displayed by the next command invoked
1581immediately after this command (ignoring reading from the minibuffer).
1582Creates a new tab before displaying the buffer, or switches to the tab
1583that already contains that buffer.
1584When `switch-to-buffer-obey-display-actions' is non-nil,
1585`switch-to-buffer' commands are also supported."
1586 (interactive)
1587 (display-buffer-override-next-command
1588 (lambda (buffer alist)
1589 (cons (progn
1590 (display-buffer-in-tab
1591 buffer (append alist '((inhibit-same-window . nil)
1592 (reusable-frames . t))))
1593 (selected-window))
1594 'tab)))
1595 (message "Display next command buffer in a new tab..."))
1596
1578(define-key tab-prefix-map "2" 'tab-new) 1597(define-key tab-prefix-map "2" 'tab-new)
1579(define-key tab-prefix-map "1" 'tab-close-other) 1598(define-key tab-prefix-map "1" 'tab-close-other)
1580(define-key tab-prefix-map "0" 'tab-close) 1599(define-key tab-prefix-map "0" 'tab-close)
@@ -1585,6 +1604,7 @@ Like \\[find-file-other-frame] (which see), but creates a new tab."
1585(define-key tab-prefix-map "b" 'switch-to-buffer-other-tab) 1604(define-key tab-prefix-map "b" 'switch-to-buffer-other-tab)
1586(define-key tab-prefix-map "f" 'find-file-other-tab) 1605(define-key tab-prefix-map "f" 'find-file-other-tab)
1587(define-key tab-prefix-map "\C-f" 'find-file-other-tab) 1606(define-key tab-prefix-map "\C-f" 'find-file-other-tab)
1607(define-key tab-prefix-map "t" 'other-tab-prefix)
1588 1608
1589 1609
1590(provide 'tab-bar) 1610(provide 'tab-bar)
diff --git a/lisp/windmove.el b/lisp/windmove.el
index f96383197bd..341c739d924 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -461,60 +461,38 @@ select the window with a displayed buffer, and the meaning of
461the prefix argument is reversed. 461the prefix argument is reversed.
462When `switch-to-buffer-obey-display-actions' is non-nil, 462When `switch-to-buffer-obey-display-actions' is non-nil,
463`switch-to-buffer' commands are also supported." 463`switch-to-buffer' commands are also supported."
464 (let* ((no-select (xor (consp arg) windmove-display-no-select)) 464 (let ((no-select (xor (consp arg) windmove-display-no-select)))
465 (old-window (or (minibuffer-selected-window) (selected-window))) 465 (display-buffer-override-next-command
466 (new-window) 466 (lambda (_buffer alist)
467 (minibuffer-depth (minibuffer-depth)) 467 (let* ((type 'reuse)
468 (action (lambda (buffer alist) 468 (window (cond
469 (unless (> (minibuffer-depth) minibuffer-depth) 469 ((eq dir 'new-tab)
470 (let* ((type 'reuse) 470 (let ((tab-bar-new-tab-choice t))
471 (window (cond 471 (tab-bar-new-tab))
472 ((eq dir 'new-tab) 472 (setq type 'tab)
473 (let ((tab-bar-new-tab-choice t)) 473 (selected-window))
474 (tab-bar-new-tab)) 474 ((eq dir 'new-frame)
475 (setq type 'tab) 475 (let* ((params (cdr (assq 'pop-up-frame-parameters alist)))
476 (selected-window)) 476 (pop-up-frame-alist (append params pop-up-frame-alist))
477 ((eq dir 'new-frame) 477 (frame (make-frame-on-current-monitor
478 (let* ((params (cdr (assq 'pop-up-frame-parameters alist))) 478 pop-up-frame-alist)))
479 (pop-up-frame-alist (append params pop-up-frame-alist)) 479 (unless (cdr (assq 'inhibit-switch-frame alist))
480 (frame (make-frame-on-current-monitor 480 (window--maybe-raise-frame frame))
481 pop-up-frame-alist))) 481 (setq type 'frame)
482 (unless (cdr (assq 'inhibit-switch-frame alist)) 482 (frame-selected-window frame)))
483 (window--maybe-raise-frame frame)) 483 ((eq dir 'same-window)
484 (setq type 'frame) 484 (selected-window))
485 (frame-selected-window frame))) 485 (t (window-in-direction
486 ((eq dir 'same-window) 486 dir nil nil
487 (selected-window)) 487 (and arg (prefix-numeric-value arg))
488 (t (window-in-direction 488 windmove-wrap-around)))))
489 dir nil nil 489 (unless window
490 (and arg (prefix-numeric-value arg)) 490 (setq window (split-window nil nil dir) type 'window))
491 windmove-wrap-around))))) 491 (cons window type)))
492 (unless window 492 (lambda (old-window new-window)
493 (setq window (split-window nil nil dir) type 'window)) 493 (when (window-live-p (if no-select old-window new-window))
494 (setq new-window (window--display-buffer buffer window 494 (select-window (if no-select old-window new-window))))))
495 type alist)))))) 495 (message "[display-%s]" dir))
496 (command this-command)
497 (clearfun (make-symbol "clear-display-buffer-overriding-action"))
498 (exitfun
499 (lambda ()
500 (setq display-buffer-overriding-action
501 (delq action display-buffer-overriding-action))
502 (when (window-live-p (if no-select old-window new-window))
503 (select-window (if no-select old-window new-window)))
504 (remove-hook 'post-command-hook clearfun))))
505 (fset clearfun
506 (lambda ()
507 (unless (or
508 ;; Remove the hook immediately
509 ;; after exiting the minibuffer.
510 (> (minibuffer-depth) minibuffer-depth)
511 ;; But don't remove immediately after
512 ;; adding the hook by the same command below.
513 (eq this-command command))
514 (funcall exitfun))))
515 (add-hook 'post-command-hook clearfun)
516 (push action display-buffer-overriding-action)
517 (message "[display-%s]" dir)))
518 496
519;;;###autoload 497;;;###autoload
520(defun windmove-display-left (&optional arg) 498(defun windmove-display-left (&optional arg)
diff --git a/lisp/window.el b/lisp/window.el
index d658cb81f65..998568e7b82 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -8578,6 +8578,47 @@ documentation for additional customization information."
8578 (interactive 8578 (interactive
8579 (list (read-buffer-to-switch "Switch to buffer in other frame: "))) 8579 (list (read-buffer-to-switch "Switch to buffer in other frame: ")))
8580 (pop-to-buffer buffer-or-name display-buffer--other-frame-action norecord)) 8580 (pop-to-buffer buffer-or-name display-buffer--other-frame-action norecord))
8581
8582(defun display-buffer-override-next-command (pre-function &optional post-function)
8583 "Set `display-buffer-overriding-action' for the next command.
8584`pre-function' is called to prepare the window where the buffer should be
8585displayed. This function takes two arguments `buffer' and `alist', and
8586should return a cons with the displayed window and its type. See the
8587meaning of these values in `window--display-buffer'.
8588Optional `post-function' is called after the buffer is displayed in the
8589window; the function takes two arguments: an old and new window."
8590 (let* ((old-window (or (minibuffer-selected-window) (selected-window)))
8591 (new-window nil)
8592 (minibuffer-depth (minibuffer-depth))
8593 (action (lambda (buffer alist)
8594 (unless (> (minibuffer-depth) minibuffer-depth)
8595 (let* ((ret (funcall pre-function buffer alist))
8596 (window (car ret))
8597 (type (cdr ret)))
8598 (setq new-window (window--display-buffer buffer window
8599 type alist))))))
8600 (command this-command)
8601 (clearfun (make-symbol "clear-display-buffer-overriding-action"))
8602 (exitfun
8603 (lambda ()
8604 (setq display-buffer-overriding-action
8605 (delq action display-buffer-overriding-action))
8606 (remove-hook 'post-command-hook clearfun)
8607 (when (functionp post-function)
8608 (funcall post-function old-window new-window)))))
8609 (fset clearfun
8610 (lambda ()
8611 (unless (or
8612 ;; Remove the hook immediately
8613 ;; after exiting the minibuffer.
8614 (> (minibuffer-depth) minibuffer-depth)
8615 ;; But don't remove immediately after
8616 ;; adding the hook by the same command below.
8617 (eq this-command command))
8618 (funcall exitfun))))
8619 (add-hook 'post-command-hook clearfun)
8620 (push action display-buffer-overriding-action)))
8621
8581 8622
8582(defun set-window-text-height (window height) 8623(defun set-window-text-height (window height)
8583 "Set the height in lines of the text display area of WINDOW to HEIGHT. 8624 "Set the height in lines of the text display area of WINDOW to HEIGHT.