aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2019-10-30 00:31:11 +0200
committerJuri Linkov2019-10-30 00:31:11 +0200
commitd7f62ce0cd58f6275bbf88925f3abbbd1db212a8 (patch)
tree4750df4d47ea051bdc4e5a99a4bc74d53fc4f19f
parentd3517de4b472ede7abaf3a552c5064be979e6eff (diff)
downloademacs-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.el2
-rw-r--r--lisp/tab-bar.el130
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.
228The result is a sequence of the same type as SEQUENCE. 229The 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."
1000The list is displayed in a buffer named `*Tabs*'. 1057The list is displayed in a buffer named `*Tabs*'.
1001 1058
1002For more information, see the function `tab-bar-list'." 1059For 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)))))))