diff options
| author | Juri Linkov | 2019-10-30 00:31:11 +0200 |
|---|---|---|
| committer | Juri Linkov | 2019-10-30 00:31:11 +0200 |
| commit | d7f62ce0cd58f6275bbf88925f3abbbd1db212a8 (patch) | |
| tree | 4750df4d47ea051bdc4e5a99a4bc74d53fc4f19f | |
| parent | d3517de4b472ede7abaf3a552c5064be979e6eff (diff) | |
| download | emacs-d7f62ce0cd58f6275bbf88925f3abbbd1db212a8.tar.gz emacs-d7f62ce0cd58f6275bbf88925f3abbbd1db212a8.zip | |
* lisp/tab-bar.el: Store point position and frame buffer-lists in tab.
* lisp/tab-bar.el (tab-bar--tab): Store additionally point-marker,
frame parameters buffer-list and buried-buffer-list, both for wc and ws.
Use seq-filter.
(tab-bar-select-tab): Restore point-marker after restoring
window-configuration. Also restore frame parameters buffer-list
and buried-buffer-list both for window-configuration and window-state.
(tab-bar-history-limit, tab-bar-history--minibuffer-depth): New variables.
(tab-bar-history-current): Rename from tab-bar-history--pre-change.
(tab-bar-history--pre-change): Set tab-bar-history-current.
(tab-bar--history-change): Use seq-take for tab-bar-history-limit.
(tab-bar-history-back, tab-bar-history-forward): Restore point-marker.
(tab-bar-list-noselect): Use seq-remove.
* lisp/emacs-lisp/seq.el (seq-take, seq-filter): Add autoload cookie.
| -rw-r--r-- | lisp/emacs-lisp/seq.el | 2 | ||||
| -rw-r--r-- | lisp/tab-bar.el | 130 |
2 files changed, 95 insertions, 37 deletions
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 9a5872c094b..810b4792b2b 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el | |||
| @@ -223,6 +223,7 @@ If N is a negative integer or zero, SEQUENCE is returned." | |||
| 223 | (let ((length (seq-length sequence))) | 223 | (let ((length (seq-length sequence))) |
| 224 | (seq-subseq sequence (min n length) length)))) | 224 | (seq-subseq sequence (min n length) length)))) |
| 225 | 225 | ||
| 226 | ;;;###autoload | ||
| 226 | (cl-defgeneric seq-take (sequence n) | 227 | (cl-defgeneric seq-take (sequence n) |
| 227 | "Take the first N elements of SEQUENCE and return the result. | 228 | "Take the first N elements of SEQUENCE and return the result. |
| 228 | The result is a sequence of the same type as SEQUENCE. | 229 | The result is a sequence of the same type as SEQUENCE. |
| @@ -306,6 +307,7 @@ list." | |||
| 306 | (`list (seq--into-list sequence)) | 307 | (`list (seq--into-list sequence)) |
| 307 | (_ (error "Not a sequence type name: %S" type)))) | 308 | (_ (error "Not a sequence type name: %S" type)))) |
| 308 | 309 | ||
| 310 | ;;;###autoload | ||
| 309 | (cl-defgeneric seq-filter (pred sequence) | 311 | (cl-defgeneric seq-filter (pred sequence) |
| 310 | "Return a list of all the elements for which (PRED element) is non-nil in SEQUENCE." | 312 | "Return a list of all the elements for which (PRED element) is non-nil in SEQUENCE." |
| 311 | (let ((exclude (make-symbol "exclude"))) | 313 | (let ((exclude (make-symbol "exclude"))) |
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index c4763337a25..c9829e94ff4 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el | |||
| @@ -438,7 +438,9 @@ Return its existing value or a new value." | |||
| 438 | 438 | ||
| 439 | (defun tab-bar--tab () | 439 | (defun tab-bar--tab () |
| 440 | (let* ((tab (assq 'current-tab (frame-parameter nil 'tabs))) | 440 | (let* ((tab (assq 'current-tab (frame-parameter nil 'tabs))) |
| 441 | (tab-explicit-name (cdr (assq 'explicit-name tab)))) | 441 | (tab-explicit-name (cdr (assq 'explicit-name tab))) |
| 442 | (bl (seq-filter #'buffer-live-p (frame-parameter nil 'buffer-list))) | ||
| 443 | (bbl (seq-filter #'buffer-live-p (frame-parameter nil 'buried-buffer-list)))) | ||
| 442 | `(tab | 444 | `(tab |
| 443 | (name . ,(if tab-explicit-name | 445 | (name . ,(if tab-explicit-name |
| 444 | (cdr (assq 'name tab)) | 446 | (cdr (assq 'name tab)) |
| @@ -446,10 +448,15 @@ Return its existing value or a new value." | |||
| 446 | (explicit-name . ,tab-explicit-name) | 448 | (explicit-name . ,tab-explicit-name) |
| 447 | (time . ,(time-convert nil 'integer)) | 449 | (time . ,(time-convert nil 'integer)) |
| 448 | (wc . ,(current-window-configuration)) | 450 | (wc . ,(current-window-configuration)) |
| 451 | (wc-point . ,(point-marker)) | ||
| 452 | (wc-bl . ,bl) | ||
| 453 | (wc-bbl . ,bbl) | ||
| 454 | (wc-history-back . ,(gethash (selected-frame) tab-bar-history-back)) | ||
| 455 | (wc-history-forward . ,(gethash (selected-frame) tab-bar-history-forward)) | ||
| 449 | (ws . ,(window-state-get | 456 | (ws . ,(window-state-get |
| 450 | (frame-root-window (selected-frame)) 'writable)) | 457 | (frame-root-window (selected-frame)) 'writable)) |
| 451 | (history-back . ,(gethash (selected-frame) tab-bar-history-back)) | 458 | (ws-bl . ,(mapcar #'buffer-name bl)) |
| 452 | (history-forward . ,(gethash (selected-frame) tab-bar-history-forward))))) | 459 | (ws-bbl . ,(mapcar #'buffer-name bbl))))) |
| 453 | 460 | ||
| 454 | (defun tab-bar--current-tab (&optional tab) | 461 | (defun tab-bar--current-tab (&optional tab) |
| 455 | ;; `tab` here is an argument meaning 'use tab as template'. This is | 462 | ;; `tab` here is an argument meaning 'use tab as template'. This is |
| @@ -505,9 +512,7 @@ to the numeric argument. ARG counts from 1." | |||
| 505 | (let* ((from-tab (tab-bar--tab)) | 512 | (let* ((from-tab (tab-bar--tab)) |
| 506 | (to-tab (nth to-index tabs)) | 513 | (to-tab (nth to-index tabs)) |
| 507 | (wc (cdr (assq 'wc to-tab))) | 514 | (wc (cdr (assq 'wc to-tab))) |
| 508 | (ws (cdr (assq 'ws to-tab))) | 515 | (ws (cdr (assq 'ws to-tab)))) |
| 509 | (history-back (cdr (assq 'history-back to-tab))) | ||
| 510 | (history-forward (cdr (assq 'history-forward to-tab)))) | ||
| 511 | 516 | ||
| 512 | ;; During the same session, use window-configuration to switch | 517 | ;; During the same session, use window-configuration to switch |
| 513 | ;; tabs, because window-configurations are more reliable | 518 | ;; tabs, because window-configurations are more reliable |
| @@ -515,18 +520,54 @@ to the numeric argument. ARG counts from 1." | |||
| 515 | ;; But after restoring tabs from a previously saved session, | 520 | ;; But after restoring tabs from a previously saved session, |
| 516 | ;; its value of window-configuration is unreadable, | 521 | ;; its value of window-configuration is unreadable, |
| 517 | ;; so restore its saved window-state. | 522 | ;; so restore its saved window-state. |
| 518 | (if (window-configuration-p wc) | 523 | (cond |
| 524 | ((window-configuration-p wc) | ||
| 525 | (let ((wc-point (cdr (assq 'wc-point to-tab))) | ||
| 526 | (wc-bl (seq-filter #'buffer-live-p (cdr (assq 'wc-bl to-tab)))) | ||
| 527 | (wc-bbl (seq-filter #'buffer-live-p (cdr (assq 'wc-bbl to-tab)))) | ||
| 528 | (wc-history-back (cdr (assq 'wc-history-back to-tab))) | ||
| 529 | (wc-history-forward (cdr (assq 'wc-history-forward to-tab)))) | ||
| 530 | |||
| 519 | (set-window-configuration wc) | 531 | (set-window-configuration wc) |
| 520 | (if ws (window-state-put ws (frame-root-window (selected-frame)) | 532 | |
| 521 | 'safe))) | 533 | ;; set-window-configuration does not restore the value of |
| 534 | ;; point in the current buffer, so restore it separately. | ||
| 535 | (when (and (markerp wc-point) | ||
| 536 | (marker-buffer wc-point) | ||
| 537 | ;; FIXME: After dired-revert, marker relocates to 1. | ||
| 538 | ;; window-configuration restores point to global point | ||
| 539 | ;; in this dired buffer, not to its window point, | ||
| 540 | ;; but this is slightly better than 1. | ||
| 541 | (not (eq 1 (marker-position wc-point)))) | ||
| 542 | (goto-char wc-point)) | ||
| 543 | |||
| 544 | (when wc-bl (modify-frame-parameters | ||
| 545 | nil (list (cons 'buffer-list wc-bl)))) | ||
| 546 | (when wc-bbl (modify-frame-parameters | ||
| 547 | nil (list (cons 'buried-buffer-list wc-bbl)))) | ||
| 548 | |||
| 549 | (puthash (selected-frame) | ||
| 550 | (and (window-configuration-p (cdr (assq 'wc (car wc-history-back)))) | ||
| 551 | wc-history-back) | ||
| 552 | tab-bar-history-back) | ||
| 553 | (puthash (selected-frame) | ||
| 554 | (and (window-configuration-p (cdr (assq 'wc (car wc-history-forward)))) | ||
| 555 | wc-history-forward) | ||
| 556 | tab-bar-history-forward))) | ||
| 557 | |||
| 558 | (ws | ||
| 559 | (window-state-put ws (frame-root-window (selected-frame)) 'safe) | ||
| 560 | |||
| 561 | (let ((ws-bl (seq-filter #'buffer-live-p | ||
| 562 | (mapcar #'get-buffer (cdr (assq 'ws-bl to-tab))))) | ||
| 563 | (ws-bbl (seq-filter #'buffer-live-p | ||
| 564 | (mapcar #'get-buffer (cdr (assq 'ws-bbl to-tab)))))) | ||
| 565 | (when ws-bl (modify-frame-parameters | ||
| 566 | nil (list (cons 'buffer-list ws-bl)))) | ||
| 567 | (when ws-bbl (modify-frame-parameters | ||
| 568 | nil (list (cons 'buried-buffer-list ws-bbl))))))) | ||
| 522 | 569 | ||
| 523 | (setq tab-bar-history-omit t) | 570 | (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 | 571 | ||
| 531 | (when from-index | 572 | (when from-index |
| 532 | (setf (nth from-index tabs) from-tab)) | 573 | (setf (nth from-index tabs) from-tab)) |
| @@ -861,6 +902,9 @@ function `tab-bar-tab-name-function'." | |||
| 861 | 902 | ||
| 862 | ;;; Tab history mode | 903 | ;;; Tab history mode |
| 863 | 904 | ||
| 905 | (defvar tab-bar-history-limit 3 | ||
| 906 | "The number of history elements to keep.") | ||
| 907 | |||
| 864 | (defvar tab-bar-history-omit nil | 908 | (defvar tab-bar-history-omit nil |
| 865 | "When non-nil, omit window-configuration changes from the current command.") | 909 | "When non-nil, omit window-configuration changes from the current command.") |
| 866 | 910 | ||
| @@ -870,52 +914,65 @@ function `tab-bar-tab-name-function'." | |||
| 870 | (defvar tab-bar-history-forward (make-hash-table) | 914 | (defvar tab-bar-history-forward (make-hash-table) |
| 871 | "History of forward changes in every tab per frame.") | 915 | "History of forward changes in every tab per frame.") |
| 872 | 916 | ||
| 873 | (defvar tab-bar-history--pre-change nil | 917 | (defvar tab-bar-history-current nil |
| 874 | "Window configuration and minibuffer depth before the current command.") | 918 | "Window configuration before the current command.") |
| 919 | |||
| 920 | (defvar tab-bar-history--minibuffer-depth 0 | ||
| 921 | "Minibuffer depth before the current command.") | ||
| 875 | 922 | ||
| 876 | (defun tab-bar-history--pre-change () | 923 | (defun tab-bar-history--pre-change () |
| 877 | (setq tab-bar-history--pre-change | 924 | (setq tab-bar-history--minibuffer-depth (minibuffer-depth) |
| 878 | (list (current-window-configuration) | 925 | tab-bar-history-current |
| 879 | (minibuffer-depth)))) | 926 | `((wc . ,(current-window-configuration)) |
| 927 | (wc-point . ,(point-marker))))) | ||
| 880 | 928 | ||
| 881 | (defun tab-bar--history-change () | 929 | (defun tab-bar--history-change () |
| 882 | (when (and (not tab-bar-history-omit) | 930 | (when (and (not tab-bar-history-omit) |
| 883 | tab-bar-history--pre-change | 931 | tab-bar-history-current |
| 884 | ;; Entering the minibuffer | 932 | ;; Entering the minibuffer |
| 885 | (zerop (nth 1 tab-bar-history--pre-change)) | 933 | (zerop tab-bar-history--minibuffer-depth) |
| 886 | ;; Exiting the minibuffer | 934 | ;; Exiting the minibuffer |
| 887 | (zerop (minibuffer-depth))) | 935 | (zerop (minibuffer-depth))) |
| 888 | (puthash (selected-frame) | 936 | (puthash (selected-frame) |
| 889 | (cons (nth 0 tab-bar-history--pre-change) | 937 | (seq-take (cons tab-bar-history-current |
| 890 | (gethash (selected-frame) tab-bar-history-back)) | 938 | (gethash (selected-frame) tab-bar-history-back)) |
| 891 | tab-bar-history-back)) | 939 | tab-bar-history-limit) |
| 940 | tab-bar-history-back)) | ||
| 892 | (when tab-bar-history-omit | 941 | (when tab-bar-history-omit |
| 893 | (setq tab-bar-history-omit nil))) | 942 | (setq tab-bar-history-omit nil))) |
| 894 | 943 | ||
| 895 | (defun tab-bar-history-back () | 944 | (defun tab-bar-history-back () |
| 896 | (interactive) | 945 | (interactive) |
| 897 | (setq tab-bar-history-omit t) | 946 | (setq tab-bar-history-omit t) |
| 898 | (let ((wc (pop (gethash (selected-frame) tab-bar-history-back)))) | 947 | (let* ((history (pop (gethash (selected-frame) tab-bar-history-back))) |
| 948 | (wc (cdr (assq 'wc history))) | ||
| 949 | (wc-point (cdr (assq 'wc-point history)))) | ||
| 899 | (if (window-configuration-p wc) | 950 | (if (window-configuration-p wc) |
| 900 | (progn | 951 | (progn |
| 901 | (puthash (selected-frame) | 952 | (puthash (selected-frame) |
| 902 | (cons (current-window-configuration) | 953 | (cons tab-bar-history-current |
| 903 | (gethash (selected-frame) tab-bar-history-forward)) | 954 | (gethash (selected-frame) tab-bar-history-forward)) |
| 904 | tab-bar-history-forward) | 955 | tab-bar-history-forward) |
| 905 | (set-window-configuration wc)) | 956 | (set-window-configuration wc) |
| 957 | (when (and (markerp wc-point) (marker-buffer wc-point)) | ||
| 958 | (goto-char wc-point))) | ||
| 906 | (message "No more tab back history")))) | 959 | (message "No more tab back history")))) |
| 907 | 960 | ||
| 908 | (defun tab-bar-history-forward () | 961 | (defun tab-bar-history-forward () |
| 909 | (interactive) | 962 | (interactive) |
| 910 | (setq tab-bar-history-omit t) | 963 | (setq tab-bar-history-omit t) |
| 911 | (let ((wc (pop (gethash (selected-frame) tab-bar-history-forward)))) | 964 | (let* ((history (pop (gethash (selected-frame) tab-bar-history-forward))) |
| 965 | (wc (cdr (assq 'wc history))) | ||
| 966 | (wc-point (cdr (assq 'wc-point history)))) | ||
| 912 | (if (window-configuration-p wc) | 967 | (if (window-configuration-p wc) |
| 913 | (progn | 968 | (progn |
| 914 | (puthash (selected-frame) | 969 | (puthash (selected-frame) |
| 915 | (cons (current-window-configuration) | 970 | (cons tab-bar-history-current |
| 916 | (gethash (selected-frame) tab-bar-history-back)) | 971 | (gethash (selected-frame) tab-bar-history-back)) |
| 917 | tab-bar-history-back) | 972 | tab-bar-history-back) |
| 918 | (set-window-configuration wc)) | 973 | (set-window-configuration wc) |
| 974 | (when (and (markerp wc-point) (marker-buffer wc-point)) | ||
| 975 | (goto-char wc-point))) | ||
| 919 | (message "No more tab forward history")))) | 976 | (message "No more tab forward history")))) |
| 920 | 977 | ||
| 921 | (define-minor-mode tab-bar-history-mode | 978 | (define-minor-mode tab-bar-history-mode |
| @@ -1000,10 +1057,9 @@ marked for deletion." | |||
| 1000 | The list is displayed in a buffer named `*Tabs*'. | 1057 | The list is displayed in a buffer named `*Tabs*'. |
| 1001 | 1058 | ||
| 1002 | For more information, see the function `tab-bar-list'." | 1059 | For more information, see the function `tab-bar-list'." |
| 1003 | (let* ((tabs (delq nil (mapcar (lambda (tab) ; remove current tab | 1060 | (let* ((tabs (seq-remove (lambda (tab) |
| 1004 | (unless (eq (car tab) 'current-tab) | 1061 | (eq (car tab) 'current-tab)) |
| 1005 | tab)) | 1062 | (funcall tab-bar-tabs-function))) |
| 1006 | (funcall tab-bar-tabs-function)))) | ||
| 1007 | ;; Sort by recency | 1063 | ;; Sort by recency |
| 1008 | (tabs (sort tabs (lambda (a b) (< (cdr (assq 'time b)) | 1064 | (tabs (sort tabs (lambda (a b) (< (cdr (assq 'time b)) |
| 1009 | (cdr (assq 'time a))))))) | 1065 | (cdr (assq 'time a))))))) |