From 9a911b4af50fdfef308aab8e2492392f0986580b Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Tue, 3 Dec 2019 01:40:12 +0200 Subject: [PATCH] New functions window-state-buffers and tab-bar-get-buffer-tab (bug#38354) * lisp/window.el (window-state-buffers): New function. * lisp/tab-bar.el (tab-bar-get-buffer-tab): New function. * lisp/emacs-lisp/seq.el (seq-some): Add autoload cookie. * lisp/desktop.el (desktop-buffers-not-to-save-function): New variable. (desktop-save-buffer-p): Use it. --- lisp/desktop.el | 7 ++++++- lisp/emacs-lisp/seq.el | 1 + lisp/tab-bar.el | 44 +++++++++++++++++++++++++++++++++++++++++- lisp/window.el | 9 +++++++++ 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 -- 2.39.2