diff options
| author | Daniel Colascione | 2025-03-21 19:46:08 -0400 |
|---|---|---|
| committer | Daniel Colascione | 2025-03-21 20:56:12 -0400 |
| commit | e5ee1d2a74c6a0989c863c3c6c06eba31efaecb3 (patch) | |
| tree | cebe7391a81e10fa0776484dfb8c7553b52abf13 | |
| parent | b21636580bed822bd9fb8bb84014311fa9b4c071 (diff) | |
| download | emacs-e5ee1d2a74c6a0989c863c3c6c06eba31efaecb3.tar.gz emacs-e5ee1d2a74c6a0989c863c3c6c06eba31efaecb3.zip | |
Adapt ediff to nonstandard layouts
Make ediff cope with having some of its windows (especially the control
window) not shown by a custom ediff-window-setup-function.
Modernize relevant adjacent code. After this change, one can write a
custom ediff-window-setup-function that doesn't show the control window.
* doc/misc/ediff.texi (Notes on Heavy-duty Customization): Refine
language to explain that the window setup function doesn't have to show
all windows.
* lisp/vc/ediff-util.el (ediff-select-control-window-on-setup):
New variable.
(ediff-setup, ediff-recenter, ediff-recenter-one-window)
(ediff-recenter-ancestor, ediff-toggle-read-only)
(ediff-operate-on-windows, ediff-jump-to-difference-at-point)
(ediff-default-suspend-function)
(ediff-clone-buffer-for-region-comparison)
(ediff-clone-buffer-for-window-comparison): Modernize control flow;
select only windows that exist.
* lisp/vc/ediff-wind.el (ediff-with-live-window): New convenience macro.
(ediff-window-setup-function): Explain relaxed contract.
| -rw-r--r-- | doc/misc/ediff.texi | 6 | ||||
| -rw-r--r-- | etc/NEWS | 8 | ||||
| -rw-r--r-- | lisp/vc/ediff-util.el | 229 | ||||
| -rw-r--r-- | lisp/vc/ediff-wind.el | 24 |
4 files changed, 125 insertions, 142 deletions
diff --git a/doc/misc/ediff.texi b/doc/misc/ediff.texi index 26a0ee433d0..73f751f3a4b 100644 --- a/doc/misc/ediff.texi +++ b/doc/misc/ediff.texi | |||
| @@ -2399,10 +2399,12 @@ The window displaying buffer A@. If buffer A is not visible, this variable | |||
| 2399 | is @code{nil} or it may be a dead window. | 2399 | is @code{nil} or it may be a dead window. |
| 2400 | 2400 | ||
| 2401 | @item ediff-window-B | 2401 | @item ediff-window-B |
| 2402 | The window displaying buffer B. | 2402 | The window displaying buffer B. If buffer B is not visible, this variable |
| 2403 | is @code{nil} or it may be a dead window. | ||
| 2403 | 2404 | ||
| 2404 | @item ediff-window-C | 2405 | @item ediff-window-C |
| 2405 | The window displaying buffer C, if any. | 2406 | The window displaying buffer C, if any. If buffer C is not visible, |
| 2407 | this variable is @code{nil} or it may be a dead window. | ||
| 2406 | 2408 | ||
| 2407 | @item ediff-control-frame | 2409 | @item ediff-control-frame |
| 2408 | A dedicated frame displaying the control buffer, if it exists. It is | 2410 | A dedicated frame displaying the control buffer, if it exists. It is |
| @@ -1202,6 +1202,14 @@ changes when supplied with a universal prefix argument via 'C-u': | |||
| 1202 | - 'C-u c a' copies all changes from buffer C to buffer A. | 1202 | - 'C-u c a' copies all changes from buffer C to buffer A. |
| 1203 | - 'C-u c b' copies all changes from buffer C to buffer B. | 1203 | - 'C-u c b' copies all changes from buffer C to buffer B. |
| 1204 | 1204 | ||
| 1205 | +++ | ||
| 1206 | *** Ediff now supports more flexible custom window layouts | ||
| 1207 | Custom implementations of 'ediff-window-setup-function' no | ||
| 1208 | longer need to display *all* ediff windows. Any of the A, B, C, | ||
| 1209 | and control windows can be left undisplayed and the corresponding | ||
| 1210 | variable set to nil. This change enables custom layouts without | ||
| 1211 | a control panel window. | ||
| 1212 | |||
| 1205 | ** Dired | 1213 | ** Dired |
| 1206 | 1214 | ||
| 1207 | +++ | 1215 | +++ |
diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el index e07f2c0b2f6..6446e0a945b 100644 --- a/lisp/vc/ediff-util.el +++ b/lisp/vc/ediff-util.el | |||
| @@ -36,6 +36,15 @@ | |||
| 36 | (require 'ediff-diff) | 36 | (require 'ediff-diff) |
| 37 | (require 'ediff-merg) | 37 | (require 'ediff-merg) |
| 38 | 38 | ||
| 39 | (eval-when-compile | ||
| 40 | (require 'cl-lib)) | ||
| 41 | |||
| 42 | (ediff-defvar-local ediff-select-control-window-on-setup t | ||
| 43 | "Select the control window after window setup. | ||
| 44 | `t' for compatibility. Custom `ediff-window-setup-function' | ||
| 45 | implementations may want to set it to `nil' to fully control | ||
| 46 | window setup.") | ||
| 47 | |||
| 39 | 48 | ||
| 40 | ;;; Functions | 49 | ;;; Functions |
| 41 | 50 | ||
| @@ -472,20 +481,20 @@ to invocation.") | |||
| 472 | (ediff-get-value-according-to-buffer-type | 481 | (ediff-get-value-according-to-buffer-type |
| 473 | 'C ediff-narrow-bounds)))) | 482 | 'C ediff-narrow-bounds)))) |
| 474 | ;; position point in buf A | 483 | ;; position point in buf A |
| 475 | (save-excursion | 484 | (when (window-live-p ediff-window-A) |
| 476 | (select-window ediff-window-A) | 485 | (with-selected-window ediff-window-A |
| 477 | (goto-char shift-A)) | 486 | (goto-char shift-A))) |
| 478 | ;; position point in buf B | 487 | ;; position point in buf B |
| 479 | (save-excursion | 488 | (when (window-live-p ediff-window-B) |
| 480 | (select-window ediff-window-B) | 489 | (with-selected-window ediff-window-B |
| 481 | (goto-char shift-B)) | 490 | (goto-char shift-B))) |
| 482 | (if ediff-3way-job | 491 | (if (and ediff-3way-job (window-live-p ediff-window-C)) |
| 483 | (save-excursion | 492 | (with-selected-window ediff-window-C |
| 484 | (select-window ediff-window-C) | 493 | (goto-char shift-C)))) |
| 485 | (goto-char shift-C))) | 494 | |
| 486 | ) | 495 | (when (and ediff-select-control-window-on-setup |
| 487 | 496 | (window-live-p ediff-control-window)) | |
| 488 | (select-window ediff-control-window) | 497 | (select-window ediff-control-window)) |
| 489 | (ediff-visible-region) | 498 | (ediff-visible-region) |
| 490 | 499 | ||
| 491 | (mapc #'funcall startup-hooks) | 500 | (mapc #'funcall startup-hooks) |
| @@ -776,16 +785,19 @@ buffers." | |||
| 776 | (or (not ediff-3way-job) | 785 | (or (not ediff-3way-job) |
| 777 | (ediff-buffer-live-p ediff-buffer-C))) | 786 | (ediff-buffer-live-p ediff-buffer-C))) |
| 778 | (progn | 787 | (progn |
| 779 | (or no-rehighlight | 788 | (or no-rehighlight |
| 780 | (ediff-select-difference ediff-current-difference)) | 789 | (ediff-select-difference ediff-current-difference)) |
| 781 | 790 | ||
| 782 | (ediff-recenter-one-window 'A) | 791 | (save-current-buffer |
| 783 | (ediff-recenter-one-window 'B) | 792 | (ediff-recenter-one-window 'A)) |
| 784 | (if ediff-3way-job | 793 | (save-current-buffer |
| 785 | (ediff-recenter-one-window 'C)) | 794 | (ediff-recenter-one-window 'B)) |
| 795 | (if ediff-3way-job | ||
| 796 | (save-current-buffer | ||
| 797 | (ediff-recenter-one-window 'C))) | ||
| 786 | 798 | ||
| 787 | (ediff-with-current-buffer control-buf | 799 | (ediff-with-current-buffer control-buf |
| 788 | (ediff-recenter-ancestor) ; check if ancestor is alive | 800 | (ediff-recenter-ancestor) ; check if ancestor is alive |
| 789 | 801 | ||
| 790 | (if (and (ediff-multiframe-setup-p) | 802 | (if (and (ediff-multiframe-setup-p) |
| 791 | (not ediff-use-long-help-message) | 803 | (not ediff-use-long-help-message) |
| @@ -801,13 +813,11 @@ buffers." | |||
| 801 | (ediff-with-current-buffer control-buf (ediff-refresh-mode-lines)) | 813 | (ediff-with-current-buffer control-buf (ediff-refresh-mode-lines)) |
| 802 | )) | 814 | )) |
| 803 | 815 | ||
| 804 | ;; this function returns to the window it was called from | 816 | ;; this function does not change current window |
| 805 | ;; (which was the control window) | ||
| 806 | (defun ediff-recenter-one-window (buf-type) | 817 | (defun ediff-recenter-one-window (buf-type) |
| 807 | (if (ediff-valid-difference-p) | 818 | (if (ediff-valid-difference-p) |
| 808 | ;; context must be saved before switching to windows A/B/C | 819 | ;; context must be saved before switching to windows A/B/C |
| 809 | (let* ((ctl-wind (selected-window)) | 820 | (let* ((shift (ediff-overlay-start |
| 810 | (shift (ediff-overlay-start | ||
| 811 | (ediff-get-value-according-to-buffer-type | 821 | (ediff-get-value-according-to-buffer-type |
| 812 | buf-type ediff-narrow-bounds))) | 822 | buf-type ediff-narrow-bounds))) |
| 813 | (job-name ediff-job-name) | 823 | (job-name ediff-job-name) |
| @@ -817,20 +827,16 @@ buffers." | |||
| 817 | (window (if (window-live-p (symbol-value window-name)) | 827 | (window (if (window-live-p (symbol-value window-name)) |
| 818 | (symbol-value window-name)))) | 828 | (symbol-value window-name)))) |
| 819 | 829 | ||
| 820 | (if (and window ediff-windows-job) | 830 | (when (and window ediff-windows-job) |
| 821 | (set-window-start window shift)) | 831 | (set-window-start window shift)) |
| 822 | (if window | 832 | (when window |
| 823 | (progn | 833 | (with-selected-window window |
| 824 | (select-window window) | 834 | (deactivate-mark) |
| 825 | (deactivate-mark) | 835 | (ediff-position-region |
| 826 | (ediff-position-region | ||
| 827 | (ediff-get-diff-posn buf-type 'beg nil control-buf) | 836 | (ediff-get-diff-posn buf-type 'beg nil control-buf) |
| 828 | (ediff-get-diff-posn buf-type 'end nil control-buf) | 837 | (ediff-get-diff-posn buf-type 'end nil control-buf) |
| 829 | (ediff-get-diff-posn buf-type 'beg nil control-buf) | 838 | (ediff-get-diff-posn buf-type 'beg nil control-buf) |
| 830 | job-name | 839 | job-name)))))) |
| 831 | ))) | ||
| 832 | (select-window ctl-wind) | ||
| 833 | ))) | ||
| 834 | 840 | ||
| 835 | (defun ediff-recenter-ancestor () | 841 | (defun ediff-recenter-ancestor () |
| 836 | ;; do half-hearted job by recentering the ancestor buffer, if it is alive and | 842 | ;; do half-hearted job by recentering the ancestor buffer, if it is alive and |
| @@ -838,21 +844,17 @@ buffers." | |||
| 838 | (if (and (ediff-buffer-live-p ediff-ancestor-buffer) | 844 | (if (and (ediff-buffer-live-p ediff-ancestor-buffer) |
| 839 | (ediff-valid-difference-p)) | 845 | (ediff-valid-difference-p)) |
| 840 | (let ((window (ediff-get-visible-buffer-window ediff-ancestor-buffer)) | 846 | (let ((window (ediff-get-visible-buffer-window ediff-ancestor-buffer)) |
| 841 | (ctl-wind (selected-window)) | ||
| 842 | (job-name ediff-job-name) | 847 | (job-name ediff-job-name) |
| 843 | (ctl-buf ediff-control-buffer)) | 848 | (ctl-buf ediff-control-buffer)) |
| 844 | (ediff-with-current-buffer ediff-ancestor-buffer | 849 | (ediff-with-current-buffer ediff-ancestor-buffer |
| 845 | (goto-char (ediff-get-diff-posn 'Ancestor 'beg nil ctl-buf)) | 850 | (goto-char (ediff-get-diff-posn 'Ancestor 'beg nil ctl-buf)) |
| 846 | (if window | 851 | (when (window-live-p window) |
| 847 | (progn | 852 | (with-selected-window window |
| 848 | (select-window window) | 853 | (ediff-position-region |
| 849 | (ediff-position-region | ||
| 850 | (ediff-get-diff-posn 'Ancestor 'beg nil ctl-buf) | 854 | (ediff-get-diff-posn 'Ancestor 'beg nil ctl-buf) |
| 851 | (ediff-get-diff-posn 'Ancestor 'end nil ctl-buf) | 855 | (ediff-get-diff-posn 'Ancestor 'end nil ctl-buf) |
| 852 | (ediff-get-diff-posn 'Ancestor 'beg nil ctl-buf) | 856 | (ediff-get-diff-posn 'Ancestor 'beg nil ctl-buf) |
| 853 | job-name)))) | 857 | job-name))))))) |
| 854 | (select-window ctl-wind) | ||
| 855 | ))) | ||
| 856 | 858 | ||
| 857 | 859 | ||
| 858 | ;; This will have to be refined for 3way jobs | 860 | ;; This will have to be refined for 3way jobs |
| @@ -1064,10 +1066,9 @@ of the current buffer." | |||
| 1064 | (sit-for 3)))) ; let the user see the warning | 1066 | (sit-for 3)))) ; let the user see the warning |
| 1065 | (if (and toggle-ro-cmd | 1067 | (if (and toggle-ro-cmd |
| 1066 | (string-match "read-only-mode" (symbol-name toggle-ro-cmd))) | 1068 | (string-match "read-only-mode" (symbol-name toggle-ro-cmd))) |
| 1067 | (save-excursion | 1069 | (save-window-excursion |
| 1068 | (save-window-excursion | 1070 | (ediff-with-live-window (ediff-get-visible-buffer-window buf) |
| 1069 | (select-window (ediff-get-visible-buffer-window buf)) | 1071 | (command-execute toggle-ro-cmd))) |
| 1070 | (command-execute toggle-ro-cmd))) | ||
| 1071 | (user-error "Don't know how to toggle read-only in buffer %S" buf)) | 1072 | (user-error "Don't know how to toggle read-only in buffer %S" buf)) |
| 1072 | 1073 | ||
| 1073 | ;; Check if we made the current buffer updatable, but its file is RO. | 1074 | ;; Check if we made the current buffer updatable, but its file is RO. |
| @@ -1413,8 +1414,8 @@ Used in ediff-windows/regions only." | |||
| 1413 | (defun ediff-operate-on-windows (operation arg) | 1414 | (defun ediff-operate-on-windows (operation arg) |
| 1414 | 1415 | ||
| 1415 | ;; make sure windows aren't dead | 1416 | ;; make sure windows aren't dead |
| 1416 | (if (not (and (window-live-p ediff-window-A) (window-live-p ediff-window-B))) | 1417 | (unless (and (window-live-p ediff-window-A) (window-live-p ediff-window-B)) |
| 1417 | (ediff-recenter 'no-rehighlight)) | 1418 | (ediff-recenter 'no-rehighlight)) |
| 1418 | (if (not (and (ediff-buffer-live-p ediff-buffer-A) | 1419 | (if (not (and (ediff-buffer-live-p ediff-buffer-A) |
| 1419 | (ediff-buffer-live-p ediff-buffer-B) | 1420 | (ediff-buffer-live-p ediff-buffer-B) |
| 1420 | (or (not ediff-3way-job) (ediff-buffer-live-p ediff-buffer-C)) | 1421 | (or (not ediff-3way-job) (ediff-buffer-live-p ediff-buffer-C)) |
| @@ -1424,8 +1425,7 @@ Used in ediff-windows/regions only." | |||
| 1424 | )) | 1425 | )) |
| 1425 | (error ediff-KILLED-VITAL-BUFFER)) | 1426 | (error ediff-KILLED-VITAL-BUFFER)) |
| 1426 | 1427 | ||
| 1427 | (let* ((wind (selected-window)) | 1428 | (let* ((wind-A ediff-window-A) |
| 1428 | (wind-A ediff-window-A) | ||
| 1429 | (wind-B ediff-window-B) | 1429 | (wind-B ediff-window-B) |
| 1430 | (wind-C ediff-window-C) | 1430 | (wind-C ediff-window-C) |
| 1431 | (wind-Anc ediff-window-Ancestor) | 1431 | (wind-Anc ediff-window-Ancestor) |
| @@ -1438,26 +1438,16 @@ Used in ediff-windows/regions only." | |||
| 1438 | (coefAnc (if with-Ancestor | 1438 | (coefAnc (if with-Ancestor |
| 1439 | (ediff-get-region-size-coefficient 'Ancestor operation)))) | 1439 | (ediff-get-region-size-coefficient 'Ancestor operation)))) |
| 1440 | 1440 | ||
| 1441 | (select-window wind-A) | 1441 | (ediff-with-live-window wind-A |
| 1442 | (condition-case nil | 1442 | (ignore-errors (funcall operation (round (* coefA arg))))) |
| 1443 | (funcall operation (round (* coefA arg))) | 1443 | (ediff-with-live-window wind-B |
| 1444 | (error)) | 1444 | (ignore-errors (funcall operation (round (* coefB arg))))) |
| 1445 | (select-window wind-B) | 1445 | (when three-way |
| 1446 | (condition-case nil | 1446 | (ediff-with-live-window wind-C |
| 1447 | (funcall operation (round (* coefB arg))) | 1447 | (ignore-errors (funcall operation (round (* coefC arg)))))) |
| 1448 | (error)) | ||
| 1449 | (if three-way | ||
| 1450 | (progn | ||
| 1451 | (select-window wind-C) | ||
| 1452 | (condition-case nil | ||
| 1453 | (funcall operation (round (* coefC arg))) | ||
| 1454 | (error)))) | ||
| 1455 | (when with-Ancestor | 1448 | (when with-Ancestor |
| 1456 | (select-window wind-Anc) | 1449 | (ediff-with-live-window wind-Anc |
| 1457 | (condition-case nil | 1450 | (ignore-errors (funcall operation (round (* coefAnc arg)))))))) |
| 1458 | (funcall operation (round (* coefAnc arg))) | ||
| 1459 | (error))) | ||
| 1460 | (select-window wind))) | ||
| 1461 | 1451 | ||
| 1462 | (defun ediff-scroll-vertically (&optional arg) | 1452 | (defun ediff-scroll-vertically (&optional arg) |
| 1463 | "Vertically scroll buffers A, B (and C if appropriate). | 1453 | "Vertically scroll buffers A, B (and C if appropriate). |
| @@ -1817,44 +1807,29 @@ current point position in the specified buffer." | |||
| 1817 | (beg (if past-last-diff | 1807 | (beg (if past-last-diff |
| 1818 | (ediff-with-current-buffer buffer (point-max)) | 1808 | (ediff-with-current-buffer buffer (point-max)) |
| 1819 | (ediff-get-diff-posn buf-type 'beg (1- diff-no)))) | 1809 | (ediff-get-diff-posn buf-type 'beg (1- diff-no)))) |
| 1820 | ctl-wind wind-A wind-B wind-C | 1810 | wind-A wind-B wind-C |
| 1821 | shift) | 1811 | shift) |
| 1822 | (if past-last-diff | 1812 | (if past-last-diff |
| 1823 | (ediff-jump-to-difference -1) | 1813 | (ediff-jump-to-difference -1) |
| 1824 | (ediff-jump-to-difference diff-no)) | 1814 | (ediff-jump-to-difference diff-no)) |
| 1825 | (setq ctl-wind (selected-window) | 1815 | (setq wind-A ediff-window-A |
| 1826 | wind-A ediff-window-A | ||
| 1827 | wind-B ediff-window-B | 1816 | wind-B ediff-window-B |
| 1828 | wind-C ediff-window-C) | 1817 | wind-C ediff-window-C) |
| 1829 | (if arg | 1818 | (if arg |
| 1830 | (progn | 1819 | (save-selected-window |
| 1831 | (ediff-with-current-buffer buffer | 1820 | (setq shift (- beg pt)) |
| 1832 | (setq shift (- beg pt))) | 1821 | (ediff-with-live-window wind-A |
| 1833 | (select-window wind-A) | 1822 | (when past-last-diff (goto-char (point-max))) |
| 1834 | (if past-last-diff (goto-char (point-max))) | 1823 | (ignore-errors (backward-char shift)) |
| 1835 | (condition-case nil | 1824 | (recenter)) |
| 1836 | (backward-char shift) ; noerror, if beginning of buffer | 1825 | (ediff-with-live-window wind-B |
| 1837 | (error)) | 1826 | (when past-last-diff (goto-char (point-max))) |
| 1838 | (recenter) | 1827 | (ignore-errors (backward-char shift)) |
| 1839 | (select-window wind-B) | 1828 | (recenter)) |
| 1840 | (if past-last-diff (goto-char (point-max))) | 1829 | (ediff-with-live-window wind-C |
| 1841 | (condition-case nil | 1830 | (when past-last-diff (goto-char (point-max))) |
| 1842 | (backward-char shift) ; noerror, if beginning of buffer | 1831 | (ignore-errors (backward-char shift)) |
| 1843 | (error)) | 1832 | (recenter)))))) |
| 1844 | (recenter) | ||
| 1845 | (if (window-live-p wind-C) | ||
| 1846 | (progn | ||
| 1847 | (select-window wind-C) | ||
| 1848 | (if past-last-diff (goto-char (point-max))) | ||
| 1849 | (condition-case nil | ||
| 1850 | (backward-char shift) ; noerror, if beginning of buffer | ||
| 1851 | (error)) | ||
| 1852 | (recenter) | ||
| 1853 | )) | ||
| 1854 | (select-window ctl-wind) | ||
| 1855 | )) | ||
| 1856 | )) | ||
| 1857 | |||
| 1858 | 1833 | ||
| 1859 | ;; find region most related to the current point position (or POS, if given) | 1834 | ;; find region most related to the current point position (or POS, if given) |
| 1860 | ;; returns diff number as seen by the user (i.e., 1+ the internal | 1835 | ;; returns diff number as seen by the user (i.e., 1+ the internal |
| @@ -2725,10 +2700,7 @@ only if this merge job is part of a group, i.e., was invoked from within | |||
| 2725 | (let* ((buf-A ediff-buffer-A) | 2700 | (let* ((buf-A ediff-buffer-A) |
| 2726 | (buf-B ediff-buffer-B) | 2701 | (buf-B ediff-buffer-B) |
| 2727 | (buf-C ediff-buffer-C) | 2702 | (buf-C ediff-buffer-C) |
| 2728 | (buf-A-wind (ediff-get-visible-buffer-window buf-A)) | 2703 | (buf-patch (if (boundp 'ediff-patchbufer) ediff-patchbufer nil)) |
| 2729 | (buf-B-wind (ediff-get-visible-buffer-window buf-B)) | ||
| 2730 | (buf-C-wind (ediff-get-visible-buffer-window buf-C)) | ||
| 2731 | (buf-patch (if (boundp 'ediff-patchbufer) ediff-patchbufer nil)) | ||
| 2732 | (buf-patch-diag (if (boundp 'ediff-patch-diagnostics) | 2704 | (buf-patch-diag (if (boundp 'ediff-patch-diagnostics) |
| 2733 | ediff-patch-diagnostics nil)) | 2705 | ediff-patch-diagnostics nil)) |
| 2734 | (buf-err ediff-error-buffer) | 2706 | (buf-err ediff-error-buffer) |
| @@ -2746,35 +2718,18 @@ only if this merge job is part of a group, i.e., was invoked from within | |||
| 2746 | (if buf-fine-diff (bury-buffer buf-fine-diff)) | 2718 | (if buf-fine-diff (bury-buffer buf-fine-diff)) |
| 2747 | (if buf-patch (bury-buffer buf-patch)) | 2719 | (if buf-patch (bury-buffer buf-patch)) |
| 2748 | (if buf-patch-diag (bury-buffer buf-patch-diag)) | 2720 | (if buf-patch-diag (bury-buffer buf-patch-diag)) |
| 2749 | (if (window-live-p buf-A-wind) | 2721 | (cl-loop |
| 2750 | (progn | 2722 | with buffers = (list buf-A buf-B buf-C) |
| 2751 | (select-window buf-A-wind) | 2723 | with windows = (mapcar #'ediff-get-visible-buffer-window buffers) |
| 2752 | (delete-other-windows) | 2724 | for buffer in buffers |
| 2753 | (bury-buffer)) | 2725 | for window in windows |
| 2754 | (if (ediff-buffer-live-p buf-A) | 2726 | do (cond ((window-live-p window) |
| 2755 | (progn | 2727 | (select-window window) |
| 2756 | (set-buffer buf-A) | 2728 | (delete-other-windows) |
| 2757 | (bury-buffer)))) | 2729 | (bury-buffer)) |
| 2758 | (if (window-live-p buf-B-wind) | 2730 | (buffer |
| 2759 | (progn | 2731 | (set-buffer buffer) |
| 2760 | (select-window buf-B-wind) | 2732 | (bury-buffer)))))) |
| 2761 | (delete-other-windows) | ||
| 2762 | (bury-buffer)) | ||
| 2763 | (if (ediff-buffer-live-p buf-B) | ||
| 2764 | (progn | ||
| 2765 | (set-buffer buf-B) | ||
| 2766 | (bury-buffer)))) | ||
| 2767 | (if (window-live-p buf-C-wind) | ||
| 2768 | (progn | ||
| 2769 | (select-window buf-C-wind) | ||
| 2770 | (delete-other-windows) | ||
| 2771 | (bury-buffer)) | ||
| 2772 | (if (ediff-buffer-live-p buf-C) | ||
| 2773 | (progn | ||
| 2774 | (set-buffer buf-C) | ||
| 2775 | (bury-buffer)))) | ||
| 2776 | )) | ||
| 2777 | |||
| 2778 | 2733 | ||
| 2779 | (defun ediff-suspend () | 2734 | (defun ediff-suspend () |
| 2780 | "Suspend Ediff. | 2735 | "Suspend Ediff. |
| @@ -3274,8 +3229,9 @@ Without an argument, it saves customized diff argument, if available | |||
| 3274 | (setq ediff-temp-indirect-buffer t)) | 3229 | (setq ediff-temp-indirect-buffer t)) |
| 3275 | (pop-to-buffer cloned-buff) | 3230 | (pop-to-buffer cloned-buff) |
| 3276 | (setq wind (ediff-get-visible-buffer-window cloned-buff)) | 3231 | (setq wind (ediff-get-visible-buffer-window cloned-buff)) |
| 3277 | (select-window wind) | 3232 | (when (window-live-p wind) |
| 3278 | (delete-other-windows) | 3233 | (select-window wind) |
| 3234 | (delete-other-windows)) | ||
| 3279 | (or (mark) (push-mark)) | 3235 | (or (mark) (push-mark)) |
| 3280 | (setq mark-active 'ediff-util) | 3236 | (setq mark-active 'ediff-util) |
| 3281 | (setq-local transient-mark-mode t) | 3237 | (setq-local transient-mark-mode t) |
| @@ -3310,7 +3266,8 @@ Without an argument, it saves customized diff argument, if available | |||
| 3310 | (let ((cloned-buff (ediff-make-cloned-buffer buff region-name))) | 3266 | (let ((cloned-buff (ediff-make-cloned-buffer buff region-name))) |
| 3311 | (ediff-with-current-buffer cloned-buff | 3267 | (ediff-with-current-buffer cloned-buff |
| 3312 | (setq ediff-temp-indirect-buffer t)) | 3268 | (setq ediff-temp-indirect-buffer t)) |
| 3313 | (set-window-buffer wind cloned-buff) | 3269 | (when (window-live-p wind) |
| 3270 | (set-window-buffer wind cloned-buff)) | ||
| 3314 | cloned-buff)) | 3271 | cloned-buff)) |
| 3315 | 3272 | ||
| 3316 | (defun ediff-buffer-type (buffer) | 3273 | (defun ediff-buffer-type (buffer) |
diff --git a/lisp/vc/ediff-wind.el b/lisp/vc/ediff-wind.el index 4ac21cb4136..aefa17de2c6 100644 --- a/lisp/vc/ediff-wind.el +++ b/lisp/vc/ediff-wind.el | |||
| @@ -53,16 +53,21 @@ frame. | |||
| 53 | 53 | ||
| 54 | If you don't like any of the two provided functions, write your own one. | 54 | If you don't like any of the two provided functions, write your own one. |
| 55 | The basic guidelines: | 55 | The basic guidelines: |
| 56 | 1. It should leave the control buffer current and the control window | 56 | 1. It should leave the control buffer current and, if showing, |
| 57 | selected. | 57 | the control window selected if showing these windows. |
| 58 | 2. It should set `ediff-window-A', `ediff-window-B', `ediff-window-C', | 58 | 2. It should set `ediff-window-A', `ediff-window-B', `ediff-window-C', |
| 59 | and `ediff-control-window' to contain window objects that display | 59 | and `ediff-control-window' to contain window objects that display |
| 60 | the corresponding buffers. | 60 | the corresponding buffers or `nil' if the corresponding window |
| 61 | is not shown. | ||
| 61 | 3. It should accept the following arguments: | 62 | 3. It should accept the following arguments: |
| 62 | buffer-A, buffer-B, buffer-C, control-buffer | 63 | buffer-A, buffer-B, buffer-C, control-buffer |
| 63 | Buffer C may not be used in jobs that compare only two buffers. | 64 | Buffer C may not be used in jobs that compare only two buffers. |
| 64 | If you plan to do something fancy, take a close look at how the two | 65 | If you plan to do something fancy, take a close look at how the two |
| 65 | provided functions are written." | 66 | provided functions are written. |
| 67 | |||
| 68 | Set `ediff-select-control-window-on-setup' to nil to prevent the window | ||
| 69 | `ediff-control-window' being selected by ediff after this | ||
| 70 | function returns. " | ||
| 66 | :type '(choice (const :tag "Choose Automatically" ediff-setup-windows-default) | 71 | :type '(choice (const :tag "Choose Automatically" ediff-setup-windows-default) |
| 67 | (const :tag "Multi Frame" ediff-setup-windows-multiframe) | 72 | (const :tag "Multi Frame" ediff-setup-windows-multiframe) |
| 68 | (const :tag "Single Frame" ediff-setup-windows-plain) | 73 | (const :tag "Single Frame" ediff-setup-windows-plain) |
| @@ -247,6 +252,17 @@ keyboard input to go into icons." | |||
| 247 | 252 | ||
| 248 | ;;; Functions | 253 | ;;; Functions |
| 249 | 254 | ||
| 255 | (defmacro ediff-with-live-window (window &rest body) | ||
| 256 | "Like `with-selected-window' but only if WINDOW is live. | ||
| 257 | If WINDOW is not live (or not a window) do nothing and don't evaluate | ||
| 258 | BODY, instead returning nil." | ||
| 259 | (declare (indent 1) (debug (form body))) | ||
| 260 | (let ((w (gensym "window"))) | ||
| 261 | `(let ((,w ,window)) | ||
| 262 | (when (window-live-p ,w) | ||
| 263 | (with-selected-window ,w | ||
| 264 | ,@body))))) | ||
| 265 | |||
| 250 | (defun ediff-get-window-by-clicking (_wind _prev-wind wind-number) | 266 | (defun ediff-get-window-by-clicking (_wind _prev-wind wind-number) |
| 251 | (let (event) | 267 | (let (event) |
| 252 | (message | 268 | (message |