(require 'cl) ;; for `copy-list'
(let* ((frame-list (frame-list))
(current-frame (selected-frame))
(result
(delq nil
(mapcar
(lambda (frame)
(with-selected-frame frame
(when (one-window-p)
(with-current-buffer (car (buffer-list frame))
(if (and buffer-file-name (file-exists-p buffer-file-name))
(list frame buffer-file-name))))))
frame-list)))
(destructable-result (copy-list result)))
(mapc
(lambda (x)
(setq destructable-result (delq x destructable-result))
(mapc
(lambda (y)
(when (equal (cdr x) (cdr y))
(if (eq (car x) current-frame)
(when (frame-live-p (car y))
(delete-frame (car y))
(setq destructable-result (delq y destructable-result)))
(when (frame-live-p (car x))
(delete-frame (car x))))))
destructable-result))
result))
SHOW YOUR WORK: One of the concerns @lawlist had while creating the above-mentioned solution was whether altering destructable-result
during an ongoing mapc
loop that uses the previous value for SEQUENCE
(i.e., prior to its altercation) would throw an error. The following example demonstrates that this is a non-issue.
(let ((my-list '(0 1 2 3 4 5 6 7 8 9)))
(mapc
(lambda (x)
(when my-list
(setq my-list nil))
(message "x: %s | my-list: %s" x my-list))
my-list))