summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lisp/desktop.el7
-rw-r--r--lisp/emacs-lisp/seq.el1
-rw-r--r--lisp/tab-bar.el44
-rw-r--r--lisp/window.el9
4 files changed, 59 insertions, 2 deletions
diff --git a/lisp/desktop.el b/lisp/desktop.el
index 498f769bd32..6f45278218c 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -946,7 +946,9 @@ which means to truncate VAR's value to at most MAX-SIZE elements
")\n"))))
;; ----------------------------------------------------------------------------
-(defun desktop-save-buffer-p (filename bufname mode &rest _dummy)
+(defvar desktop-buffers-not-to-save-function nil)
+
+(defun desktop-save-buffer-p (filename bufname mode &rest rest)
"Return t if buffer should have its state saved in the desktop file.
FILENAME is the visited file name, BUFNAME is the buffer name, and
MODE is the major mode.
@@ -970,6 +972,9 @@ MODE is the major mode.
(and (null filename)
(null dired-skip) ; bug#5755
(with-current-buffer bufname desktop-save-buffer)))
+ (or (null desktop-buffers-not-to-save-function)
+ (funcall desktop-buffers-not-to-save-function
+ filename bufname mode rest))
t)))
;; ----------------------------------------------------------------------------
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 2fd735617ba..7e5e6f3b16f 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -348,6 +348,7 @@ If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called."
(throw 'seq--break nil)))
t))
+;;;###autoload
(cl-defgeneric seq-some (pred sequence)
"Return non-nil if PRED is satisfied for at least one element of SEQUENCE.
If so, return the first non-nil value returned by PRED."
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 5eb332884c5..a36be13e37b 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -1244,7 +1244,8 @@ in the selected frame."
(kill-buffer (current-buffer))
;; Delete the current window configuration of tab list
;; without storing it in the undo list of closed tabs
- (let (tab-bar-closed-tabs)
+ (let ((tab-bar-mode t) ; avoid message about deleted tab
+ tab-bar-closed-tabs)
(tab-bar-close-tab nil (1+ (tab-bar--tab-index to-tab))))))
(defun tab-bar-list-mouse-select (event)
@@ -1284,6 +1285,47 @@ indirectly called by the latter."
(tab-bar-rename-tab name))))
(tab-bar-new-tab))))
+(defun tab-bar-get-buffer-tab (buffer-or-name &optional all-frames)
+ "Return a tab whose window contains BUFFER-OR-NAME, or nil if none.
+BUFFER-OR-NAME may be a buffer or a buffer name and defaults to
+the current buffer.
+
+The optional argument ALL-FRAMES specifies the frames to consider:
+
+- t means consider all tabs on all existing frames.
+
+- `visible' means consider all tabs on all visible frames.
+
+- A frame means consider all tabs on that frame only.
+
+Any other value of ALL-FRAMES means consider all tabs on the
+selected frame and no others."
+ (let ((buffer (if buffer-or-name
+ (get-buffer buffer-or-name)
+ (current-buffer))))
+ (when (bufferp buffer)
+ (let ((frames (cond
+ ((eq all-frames t) (frame-list))
+ ((eq all-frames 'visible) (visible-frame-list))
+ ((framep all-frames) (list all-frames))
+ (t (list (selected-frame))))))
+ (seq-some (lambda (frame)
+ (with-selected-frame frame
+ (seq-some (lambda (tab)
+ (when (if (eq (car tab) 'current-tab)
+ (get-buffer-window buffer frame)
+ (let* ((state (cdr (assq 'ws tab)))
+ (buffers (when state
+ (window-state-buffers state))))
+ (or
+ ;; non-writable window-state
+ (memq buffer buffers)
+ ;; writable window-state
+ (member (buffer-name buffer) buffers))))
+ (append tab `((frame . ,frame)))))
+ (funcall tab-bar-tabs-function))))
+ frames)))))
+
(defun switch-to-buffer-other-tab (buffer-or-name &optional norecord)
"Switch to buffer BUFFER-OR-NAME in another tab.
diff --git a/lisp/window.el b/lisp/window.el
index c750ea71ead..a0280eba9b0 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -6231,6 +6231,15 @@ windows can get as small as `window-safe-min-height' and
(delete-window window))))
(window--check frame))))
+(defun window-state-buffers (state)
+ "Return all buffers saved to the given window state STATE."
+ (let ((buffer (cadr (assq 'buffer state)))
+ (buffers (mapcan (lambda (item)
+ (when (memq (car item) '(leaf vc hc))
+ (window-state-buffers item)))
+ (if (consp (car state)) (list (cdr state)) (cdr state)))))
+ (if buffer (cons buffer buffers) buffers)))
+
(defun window-swap-states (&optional window-1 window-2 size)
"Swap the states of live windows WINDOW-1 and WINDOW-2.
WINDOW-1 must specify a live window and defaults to the selected