diff options
| author | Juri Linkov | 2019-10-28 01:04:47 +0200 |
|---|---|---|
| committer | Juri Linkov | 2019-10-28 01:04:47 +0200 |
| commit | 7e30076225cebe85f7e60802f471b421a369abd7 (patch) | |
| tree | 00c85a50cec3613c598dac428a0c9e98494783bb | |
| parent | 38ec422a35ab6e6e295b56500bb11493cd39a10e (diff) | |
| download | emacs-7e30076225cebe85f7e60802f471b421a369abd7.tar.gz emacs-7e30076225cebe85f7e60802f471b421a369abd7.zip | |
* lisp/tab-bar.el: Add tab-bar-history-mode with arrow buttons for navigation.
* lisp/tab-bar.el (tab-bar-back-button, tab-bar-forward-button):
New variables.
(tab-bar-make-keymap-1): Show these buttons in tab-bar-history-mode.
(tab-bar--tab): Add history-back and history-forward.
(tab-bar-select-tab): Restore history-back and history-forward.
(tab-bar-history-omit, tab-bar-history-back)
(tab-bar-history-forward, tab-bar-history-pre-change): New variables.
(tab-bar-history-pre-change, tab-bar-history-change)
(tab-bar-history-back, tab-bar-history-forward)
(tab-bar-history-mode): New functions.
| -rw-r--r-- | lisp/tab-bar.el | 112 |
1 files changed, 110 insertions, 2 deletions
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 2b71bf8b2c5..1151df923b7 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el | |||
| @@ -284,6 +284,12 @@ If nil, don't show it at all." | |||
| 284 | :help "Click to close tab") | 284 | :help "Click to close tab") |
| 285 | "Button for closing the clicked tab.") | 285 | "Button for closing the clicked tab.") |
| 286 | 286 | ||
| 287 | (defvar tab-bar-back-button " < " | ||
| 288 | "Button for going back in tab history.") | ||
| 289 | |||
| 290 | (defvar tab-bar-forward-button " > " | ||
| 291 | "Button for going forward in tab history.") | ||
| 292 | |||
| 287 | (defcustom tab-bar-tab-hints nil | 293 | (defcustom tab-bar-tab-hints nil |
| 288 | "Show absolute numbers on tabs in the tab bar before the tab name. | 294 | "Show absolute numbers on tabs in the tab bar before the tab name. |
| 289 | This helps to select the tab by its number using `tab-bar-select-tab'." | 295 | This helps to select the tab by its number using `tab-bar-select-tab'." |
| @@ -373,6 +379,15 @@ Return its existing value or a new value." | |||
| 373 | (tabs (funcall tab-bar-tabs-function))) | 379 | (tabs (funcall tab-bar-tabs-function))) |
| 374 | (append | 380 | (append |
| 375 | '(keymap (mouse-1 . tab-bar-handle-mouse)) | 381 | '(keymap (mouse-1 . tab-bar-handle-mouse)) |
| 382 | (when tab-bar-history-mode | ||
| 383 | `((sep-history-back menu-item ,separator ignore) | ||
| 384 | (history-back | ||
| 385 | menu-item ,tab-bar-back-button tab-bar-history-back | ||
| 386 | :help "Click to go back in tab history") | ||
| 387 | (sep-history-forward menu-item ,separator ignore) | ||
| 388 | (history-forward | ||
| 389 | menu-item ,tab-bar-forward-button tab-bar-history-forward | ||
| 390 | :help "Click to go forward in tab history"))) | ||
| 376 | (mapcan | 391 | (mapcan |
| 377 | (lambda (tab) | 392 | (lambda (tab) |
| 378 | (setq i (1+ i)) | 393 | (setq i (1+ i)) |
| @@ -432,7 +447,9 @@ Return its existing value or a new value." | |||
| 432 | (time . ,(time-convert nil 'integer)) | 447 | (time . ,(time-convert nil 'integer)) |
| 433 | (wc . ,(current-window-configuration)) | 448 | (wc . ,(current-window-configuration)) |
| 434 | (ws . ,(window-state-get | 449 | (ws . ,(window-state-get |
| 435 | (frame-root-window (selected-frame)) 'writable))))) | 450 | (frame-root-window (selected-frame)) 'writable)) |
| 451 | (history-back . ,(gethash (selected-frame) tab-bar-history-back)) | ||
| 452 | (history-forward . ,(gethash (selected-frame) tab-bar-history-forward))))) | ||
| 436 | 453 | ||
| 437 | (defun tab-bar--current-tab (&optional tab) | 454 | (defun tab-bar--current-tab (&optional tab) |
| 438 | ;; `tab` here is an argument meaning 'use tab as template'. This is | 455 | ;; `tab` here is an argument meaning 'use tab as template'. This is |
| @@ -488,7 +505,9 @@ to the numeric argument. ARG counts from 1." | |||
| 488 | (let* ((from-tab (tab-bar--tab)) | 505 | (let* ((from-tab (tab-bar--tab)) |
| 489 | (to-tab (nth to-index tabs)) | 506 | (to-tab (nth to-index tabs)) |
| 490 | (wc (cdr (assq 'wc to-tab))) | 507 | (wc (cdr (assq 'wc to-tab))) |
| 491 | (ws (cdr (assq 'ws to-tab)))) | 508 | (ws (cdr (assq 'ws to-tab))) |
| 509 | (history-back (cdr (assq 'history-back to-tab))) | ||
| 510 | (history-forward (cdr (assq 'history-forward to-tab)))) | ||
| 492 | 511 | ||
| 493 | ;; During the same session, use window-configuration to switch | 512 | ;; During the same session, use window-configuration to switch |
| 494 | ;; tabs, because window-configurations are more reliable | 513 | ;; tabs, because window-configurations are more reliable |
| @@ -501,6 +520,14 @@ to the numeric argument. ARG counts from 1." | |||
| 501 | (if ws (window-state-put ws (frame-root-window (selected-frame)) | 520 | (if ws (window-state-put ws (frame-root-window (selected-frame)) |
| 502 | 'safe))) | 521 | 'safe))) |
| 503 | 522 | ||
| 523 | (setq tab-bar-history-omit t) | ||
| 524 | (puthash (selected-frame) | ||
| 525 | (and (window-configuration-p (car history-back)) history-back) | ||
| 526 | tab-bar-history-back) | ||
| 527 | (puthash (selected-frame) | ||
| 528 | (and (window-configuration-p (car history-forward)) history-forward) | ||
| 529 | tab-bar-history-forward) | ||
| 530 | |||
| 504 | (when from-index | 531 | (when from-index |
| 505 | (setf (nth from-index tabs) from-tab)) | 532 | (setf (nth from-index tabs) from-tab)) |
| 506 | (setf (nth to-index tabs) (tab-bar--current-tab (nth to-index tabs)))) | 533 | (setf (nth to-index tabs) (tab-bar--current-tab (nth to-index tabs)))) |
| @@ -832,6 +859,87 @@ function `tab-bar-tab-name-function'." | |||
| 832 | (tab-bar-rename-tab new-name (1+ (tab-bar--tab-index-by-name tab-name)))) | 859 | (tab-bar-rename-tab new-name (1+ (tab-bar--tab-index-by-name tab-name)))) |
| 833 | 860 | ||
| 834 | 861 | ||
| 862 | ;;; Tab history mode | ||
| 863 | |||
| 864 | (defvar tab-bar-history-omit nil | ||
| 865 | "When non-nil, omit window-configuration changes from the current command.") | ||
| 866 | |||
| 867 | (defvar tab-bar-history-back (make-hash-table) | ||
| 868 | "History of back changes in every tab per frame.") | ||
| 869 | |||
| 870 | (defvar tab-bar-history-forward (make-hash-table) | ||
| 871 | "History of forward changes in every tab per frame.") | ||
| 872 | |||
| 873 | (defvar tab-bar-history-pre-change nil | ||
| 874 | "Window configuration before the current command.") | ||
| 875 | |||
| 876 | (defun tab-bar-history-pre-change () | ||
| 877 | (setq tab-bar-history-pre-change (current-window-configuration))) | ||
| 878 | |||
| 879 | (defun tab-bar-history-change () | ||
| 880 | (when (and (not tab-bar-history-omit) | ||
| 881 | (zerop (minibuffer-depth))) | ||
| 882 | (puthash (selected-frame) | ||
| 883 | (cons tab-bar-history-pre-change | ||
| 884 | (gethash (selected-frame) tab-bar-history-back)) | ||
| 885 | tab-bar-history-back)) | ||
| 886 | (when tab-bar-history-omit | ||
| 887 | (setq tab-bar-history-omit nil))) | ||
| 888 | |||
| 889 | (defun tab-bar-history-back () | ||
| 890 | (interactive) | ||
| 891 | (setq tab-bar-history-omit t) | ||
| 892 | (let ((wc (pop (gethash (selected-frame) tab-bar-history-back)))) | ||
| 893 | (if (window-configuration-p wc) | ||
| 894 | (progn | ||
| 895 | (puthash (selected-frame) | ||
| 896 | (cons (current-window-configuration) | ||
| 897 | (gethash (selected-frame) tab-bar-history-forward)) | ||
| 898 | tab-bar-history-forward) | ||
| 899 | (set-window-configuration wc)) | ||
| 900 | (message "No more tab back history")))) | ||
| 901 | |||
| 902 | (defun tab-bar-history-forward () | ||
| 903 | (interactive) | ||
| 904 | (setq tab-bar-history-omit t) | ||
| 905 | (let ((wc (pop (gethash (selected-frame) tab-bar-history-forward)))) | ||
| 906 | (if (window-configuration-p wc) | ||
| 907 | (progn | ||
| 908 | (puthash (selected-frame) | ||
| 909 | (cons (current-window-configuration) | ||
| 910 | (gethash (selected-frame) tab-bar-history-back)) | ||
| 911 | tab-bar-history-back) | ||
| 912 | (set-window-configuration wc)) | ||
| 913 | (message "No more tab forward history")))) | ||
| 914 | |||
| 915 | (define-minor-mode tab-bar-history-mode | ||
| 916 | "Toggle tab history mode for the tab bar." | ||
| 917 | :global t | ||
| 918 | (if tab-bar-history-mode | ||
| 919 | (progn | ||
| 920 | (when (and tab-bar-mode (not (get-text-property 0 'display tab-bar-back-button))) | ||
| 921 | ;; This file is pre-loaded so only here we can use the right data-directory: | ||
| 922 | (add-text-properties 0 (length tab-bar-back-button) | ||
| 923 | `(display (image :type xpm | ||
| 924 | :file "tabs/left-arrow.xpm" | ||
| 925 | :margin (2 . 0) | ||
| 926 | :ascent center)) | ||
| 927 | tab-bar-back-button)) | ||
| 928 | (when (and tab-bar-mode (not (get-text-property 0 'display tab-bar-forward-button))) | ||
| 929 | ;; This file is pre-loaded so only here we can use the right data-directory: | ||
| 930 | (add-text-properties 0 (length tab-bar-forward-button) | ||
| 931 | `(display (image :type xpm | ||
| 932 | :file "tabs/right-arrow.xpm" | ||
| 933 | :margin (2 . 0) | ||
| 934 | :ascent center)) | ||
| 935 | tab-bar-forward-button)) | ||
| 936 | |||
| 937 | (add-hook 'pre-command-hook 'tab-bar-history-pre-change) | ||
| 938 | (add-hook 'window-configuration-change-hook 'tab-bar-history-change)) | ||
| 939 | (remove-hook 'pre-command-hook 'tab-bar-history-pre-change) | ||
| 940 | (remove-hook 'window-configuration-change-hook 'tab-bar-history-change))) | ||
| 941 | |||
| 942 | |||
| 835 | ;;; Short aliases | 943 | ;;; Short aliases |
| 836 | 944 | ||
| 837 | (defalias 'tab-new 'tab-bar-new-tab) | 945 | (defalias 'tab-new 'tab-bar-new-tab) |