diff options
| author | Robert Cochran | 2019-10-07 13:41:47 -0700 |
|---|---|---|
| committer | Juri Linkov | 2019-10-16 00:04:40 +0300 |
| commit | bf112e23ef7b2939ff40c0c1f94adce4ffa79187 (patch) | |
| tree | 468c169934d5e5fe76ca9cec727314e654b9336f | |
| parent | 56a7c60872272eef2dbd4fd071d0af0441f374d8 (diff) | |
| download | emacs-bf112e23ef7b2939ff40c0c1f94adce4ffa79187.tar.gz emacs-bf112e23ef7b2939ff40c0c1f94adce4ffa79187.zip | |
Allow tabs to have consistent given names
* lisp/tab-bar.el (tab-bar--tab): Pull automatic name information from
current tab
(tab-bar--current-tab): Pull automatic name information from current
tab, or from new optional template argument
(tab-bar-select-tab): Pass the target tab as a template when setting
it as current tab
(tab-bar-rename-tab, tab-bar-rename-tab-by-name): New functions
* doc/emacs/frames.texi (Tab Bars): Document new tab rename functionality.
| -rw-r--r-- | doc/emacs/frames.texi | 4 | ||||
| -rw-r--r-- | lisp/tab-bar.el | 93 |
2 files changed, 77 insertions, 20 deletions
diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi index f93c5b168b1..452c167c726 100644 --- a/doc/emacs/frames.texi +++ b/doc/emacs/frames.texi | |||
| @@ -1282,6 +1282,10 @@ runs @code{find-file-other-tab}. @xref{Visiting}. | |||
| 1282 | @item C-x 6 d @var{directory} @key{RET} | 1282 | @item C-x 6 d @var{directory} @key{RET} |
| 1283 | Select a Dired buffer for directory @var{directory} in another tab. | 1283 | Select a Dired buffer for directory @var{directory} in another tab. |
| 1284 | This runs @code{dired-other-tab}. @xref{Dired}. | 1284 | This runs @code{dired-other-tab}. @xref{Dired}. |
| 1285 | @item C-x 6 r @var{tabname} @key{RET} | ||
| 1286 | Renames the current tab to @var{tabname}. You can control the | ||
| 1287 | programmatic name given to a tab by default by customizing the | ||
| 1288 | variable @code{tab-bar-tab-name-function}. | ||
| 1285 | @end table | 1289 | @end table |
| 1286 | 1290 | ||
| 1287 | @vindex tab-bar-new-tab-choice | 1291 | @vindex tab-bar-new-tab-choice |
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index f9d4de4ebf2..32d7f6c784b 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el | |||
| @@ -359,9 +359,13 @@ Return its existing value or a new value." | |||
| 359 | (let* ((separator (or tab-bar-separator (if window-system " " "|"))) | 359 | (let* ((separator (or tab-bar-separator (if window-system " " "|"))) |
| 360 | (i 0) | 360 | (i 0) |
| 361 | (tabs (funcall tab-bar-tabs-function)) | 361 | (tabs (funcall tab-bar-tabs-function)) |
| 362 | (current-tab-name (assq 'name (assq 'current-tab tabs)))) | 362 | (current-tab-name (assq 'name (assq 'current-tab tabs))) |
| 363 | (when current-tab-name | 363 | (current-tab-explicit-name (assq 'explicit-name (assq 'current-tab tabs)))) |
| 364 | (setf (cdr current-tab-name) (funcall tab-bar-tab-name-function))) | 364 | (when (and current-tab-name |
| 365 | current-tab-explicit-name | ||
| 366 | (not (cdr current-tab-explicit-name))) | ||
| 367 | (setf (cdr current-tab-name) | ||
| 368 | (funcall tab-bar-tab-name-function))) | ||
| 365 | (append | 369 | (append |
| 366 | '(keymap (mouse-1 . tab-bar-handle-mouse)) | 370 | '(keymap (mouse-1 . tab-bar-handle-mouse)) |
| 367 | (mapcan | 371 | (mapcan |
| @@ -413,16 +417,29 @@ Return its existing value or a new value." | |||
| 413 | 417 | ||
| 414 | 418 | ||
| 415 | (defun tab-bar--tab () | 419 | (defun tab-bar--tab () |
| 416 | `(tab | 420 | (let* ((tab (assq 'current-tab (frame-parameter nil 'tabs))) |
| 417 | (name . ,(funcall tab-bar-tab-name-function)) | 421 | (tab-explicit-name (cdr (assq 'explicit-name tab)))) |
| 418 | (time . ,(time-convert nil 'integer)) | 422 | `(tab |
| 419 | (wc . ,(current-window-configuration)) | 423 | (name . ,(if tab-explicit-name |
| 420 | (ws . ,(window-state-get | 424 | (cdr (assq 'name tab)) |
| 421 | (frame-root-window (selected-frame)) 'writable)))) | 425 | (funcall tab-bar-tab-name-function))) |
| 422 | 426 | (explicit-name . ,tab-explicit-name) | |
| 423 | (defun tab-bar--current-tab () | 427 | (time . ,(time-convert nil 'integer)) |
| 424 | `(current-tab | 428 | (wc . ,(current-window-configuration)) |
| 425 | (name . ,(funcall tab-bar-tab-name-function)))) | 429 | (ws . ,(window-state-get |
| 430 | (frame-root-window (selected-frame)) 'writable))))) | ||
| 431 | |||
| 432 | (defun tab-bar--current-tab (&optional tab) | ||
| 433 | ;; `tab` here is an argument meaning 'use tab as template'. This is | ||
| 434 | ;; necessary when switching tabs, otherwise the destination tab | ||
| 435 | ;; inherit the current tab's `explicit-name` parameter. | ||
| 436 | (let* ((tab (or tab (assq 'current-tab (frame-parameter nil 'tabs)))) | ||
| 437 | (tab-explicit-name (cdr (assq 'explicit-name tab)))) | ||
| 438 | `(current-tab | ||
| 439 | (name . ,(if tab-explicit-name | ||
| 440 | (cdr (assq 'name tab)) | ||
| 441 | (funcall tab-bar-tab-name-function))) | ||
| 442 | (explicit-name . ,tab-explicit-name)))) | ||
| 426 | 443 | ||
| 427 | (defun tab-bar--current-tab-index (&optional tabs) | 444 | (defun tab-bar--current-tab-index (&optional tabs) |
| 428 | ;; FIXME: could be replaced with 1-liner using seq-position | 445 | ;; FIXME: could be replaced with 1-liner using seq-position |
| @@ -491,7 +508,7 @@ to the numeric argument. ARG counts from 1." | |||
| 491 | 508 | ||
| 492 | (when from-index | 509 | (when from-index |
| 493 | (setf (nth from-index tabs) from-tab)) | 510 | (setf (nth from-index tabs) from-tab)) |
| 494 | (setf (nth to-index tabs) (tab-bar--current-tab))) | 511 | (setf (nth to-index tabs) (tab-bar--current-tab (nth to-index tabs)))) |
| 495 | 512 | ||
| 496 | (when tab-bar-mode | 513 | (when tab-bar-mode |
| 497 | (force-mode-line-update))))) | 514 | (force-mode-line-update))))) |
| @@ -649,16 +666,51 @@ TO-INDEX counts from 1." | |||
| 649 | (force-mode-line-update) | 666 | (force-mode-line-update) |
| 650 | (message "Deleted all other tabs"))))) | 667 | (message "Deleted all other tabs"))))) |
| 651 | 668 | ||
| 669 | (defun tab-bar-rename-tab (name &optional arg) | ||
| 670 | "Rename the tab specified by its absolute position ARG. | ||
| 671 | If no ARG is specified, then rename the current tab. | ||
| 672 | ARG counts from 1. | ||
| 673 | If NAME is the empty string, then use the automatic name | ||
| 674 | function `tab-bar-tab-name-function'." | ||
| 675 | (interactive "sNew name for tab (leave blank for automatic naming): \nP") | ||
| 676 | (let* ((tabs (tab-bar-tabs)) | ||
| 677 | (tab-index (if arg | ||
| 678 | (1- (max 0 (min arg (length tabs)))) | ||
| 679 | (tab-bar--current-tab-index tabs))) | ||
| 680 | (tab-to-rename (nth tab-index tabs)) | ||
| 681 | (tab-explicit-name (> (length name) 0)) | ||
| 682 | (tab-new-name (if tab-explicit-name | ||
| 683 | name | ||
| 684 | (funcall tab-bar-tab-name-function)))) | ||
| 685 | (setf (cdr (assq 'name tab-to-rename)) tab-new-name | ||
| 686 | (cdr (assq 'explicit-name tab-to-rename)) tab-explicit-name | ||
| 687 | (frame-parameter nil 'tabs) tabs) | ||
| 688 | (if (tab-bar-mode) | ||
| 689 | (force-mode-line-update) | ||
| 690 | (message "Renamed tab to '%s'" tab-new-name)))) | ||
| 691 | |||
| 692 | (defun tab-bar-rename-tab-by-name (tab-name new-name) | ||
| 693 | "Rename the tab named TAB-NAME. | ||
| 694 | If NEW-NAME is the empty string, then use the automatic name | ||
| 695 | function `tab-bar-tab-name-function'." | ||
| 696 | (interactive (list (completing-read "Rename tab by name: " | ||
| 697 | (mapcar (lambda (tab) | ||
| 698 | (cdr (assq 'name tab))) | ||
| 699 | (tab-bar-tabs))) | ||
| 700 | (read-from-minibuffer "New name for tab (leave blank for automatic naming): "))) | ||
| 701 | (tab-bar-rename-tab new-name (tab-bar--tab-index-by-name tab-name))) | ||
| 702 | |||
| 652 | 703 | ||
| 653 | ;;; Short aliases | 704 | ;;; Short aliases |
| 654 | 705 | ||
| 655 | (defalias 'tab-new 'tab-bar-new-tab) | 706 | (defalias 'tab-new 'tab-bar-new-tab) |
| 656 | (defalias 'tab-close 'tab-bar-close-tab) | 707 | (defalias 'tab-close 'tab-bar-close-tab) |
| 657 | (defalias 'tab-close-other 'tab-bar-close-other-tabs) | 708 | (defalias 'tab-close-other 'tab-bar-close-other-tabs) |
| 658 | (defalias 'tab-select 'tab-bar-select-tab) | 709 | (defalias 'tab-select 'tab-bar-select-tab) |
| 659 | (defalias 'tab-next 'tab-bar-switch-to-next-tab) | 710 | (defalias 'tab-next 'tab-bar-switch-to-next-tab) |
| 660 | (defalias 'tab-previous 'tab-bar-switch-to-prev-tab) | 711 | (defalias 'tab-previous 'tab-bar-switch-to-prev-tab) |
| 661 | (defalias 'tab-list 'tab-bar-list) | 712 | (defalias 'tab-rename 'tab-bar-rename-tab) |
| 713 | (defalias 'tab-list 'tab-bar-list) | ||
| 662 | 714 | ||
| 663 | 715 | ||
| 664 | ;;; Non-graphical access to frame-local tabs (named window configurations) | 716 | ;;; Non-graphical access to frame-local tabs (named window configurations) |
| @@ -915,6 +967,7 @@ Like \\[find-file-other-frame] (which see), but creates a new tab." | |||
| 915 | (define-key ctl-x-6-map "b" 'switch-to-buffer-other-tab) | 967 | (define-key ctl-x-6-map "b" 'switch-to-buffer-other-tab) |
| 916 | (define-key ctl-x-6-map "f" 'find-file-other-tab) | 968 | (define-key ctl-x-6-map "f" 'find-file-other-tab) |
| 917 | (define-key ctl-x-6-map "\C-f" 'find-file-other-tab) | 969 | (define-key ctl-x-6-map "\C-f" 'find-file-other-tab) |
| 970 | (define-key ctl-x-6-map "r" 'tab-rename) | ||
| 918 | 971 | ||
| 919 | 972 | ||
| 920 | (provide 'tab-bar) | 973 | (provide 'tab-bar) |