diff options
| author | Juri Linkov | 2020-06-07 02:42:24 +0300 |
|---|---|---|
| committer | Juri Linkov | 2020-06-07 02:42:24 +0300 |
| commit | 788cd6d8b98c0e7750e478ae84e580f29576b5ff (patch) | |
| tree | 46c566e2e9e89003d4ba2555c3c8e6c56151cdcf | |
| parent | 7ac79872aed63110c0d26c1e62e1838d6101c9bd (diff) | |
| download | emacs-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/NEWS | 4 | ||||
| -rw-r--r-- | lisp/tab-bar.el | 20 | ||||
| -rw-r--r-- | lisp/windmove.el | 86 | ||||
| -rw-r--r-- | lisp/window.el | 41 |
4 files changed, 97 insertions, 54 deletions
| @@ -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. | ||
| 1580 | The next buffer is the buffer displayed by the next command invoked | ||
| 1581 | immediately after this command (ignoring reading from the minibuffer). | ||
| 1582 | Creates a new tab before displaying the buffer, or switches to the tab | ||
| 1583 | that already contains that buffer. | ||
| 1584 | When `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 | |||
| 461 | the prefix argument is reversed. | 461 | the prefix argument is reversed. |
| 462 | When `switch-to-buffer-obey-display-actions' is non-nil, | 462 | When `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 | ||
| 8585 | displayed. This function takes two arguments `buffer' and `alist', and | ||
| 8586 | should return a cons with the displayed window and its type. See the | ||
| 8587 | meaning of these values in `window--display-buffer'. | ||
| 8588 | Optional `post-function' is called after the buffer is displayed in the | ||
| 8589 | window; 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. |