summaryrefslogtreecommitdiff
path: root/modules/diff-config.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2025-08-17 09:40:20 -0500
committerCraig Jennings <c@cjennings.net>2025-08-17 09:40:20 -0500
commit4235fb7c04d41e86a477f8ec9be7d254a98419c8 (patch)
treeae36860af1bb96278424ef11b1d4a809b058d05c /modules/diff-config.el
parent509beb5be671439ca65e96d5296846ac7f8f0949 (diff)
downloaddotemacs-4235fb7c04d41e86a477f8ec9be7d254a98419c8.tar.gz
dotemacs-4235fb7c04d41e86a477f8ec9be7d254a98419c8.zip
feat(ediff): consolidate config and add ztree integration
Replace the custom `csetq` macro with a `use-package` setup for Ediff, configuring plain windows, horizontal splits, whitespace-ignoring diffs, and current-change highlighting. Introduce a “C-c e” prefix map for quick Ediff commands (files, buffers, revisions, directories) plus “d” for `ztree-diff`. Enable `winner-mode`, remap j/k/q in Ediff, and add ERT tests to verify key bindings and teardown behavior.
Diffstat (limited to 'modules/diff-config.el')
-rw-r--r--modules/diff-config.el100
1 files changed, 66 insertions, 34 deletions
diff --git a/modules/diff-config.el b/modules/diff-config.el
index 98729639..f3ab4bdf 100644
--- a/modules/diff-config.el
+++ b/modules/diff-config.el
@@ -2,53 +2,85 @@
;; author Craig Jennings <c@cjennings.net>
;;; Commentary:
-;; highly useful setup for configuring ediff
-;; https://oremacs.com/2015/01/17/setting-up-ediff/
-
-;;; Code:
-;; -------------------------------- Csetq Macro --------------------------------
-;; a macro that allows a setq for custom variables. uses the variable's set
-;; property without writing customizations to emacs init.
+;; I've tied Ediff with ZTree into a single keybinding for convenience.
-(defmacro csetq (variable value)
- `(funcall (or (get ',variable 'custom-set)
- 'set-default)
- ',variable ,value))
+;; • Ediff will use a plain control window, horizontal splits, ignore whitespace, and only highlight the current change.
+;; • A single keymap under “C-c e” has bindings:
+;; - ediff-files,
+;; - ediff-buffers (b)
+;; - ediff-revision (r)
+;; - ediff-directories (D)
+;; - ztree directory diffs (d)
+;; • An Ediff hook that remaps j/k to next/previous differences and q to quit immediately
+;; • Einner-mode enabled so window layouts are restored after quitting Ediff
-;; ------------------------------- Ediff Settings ------------------------------
-;; ediff configuration. note the dired-ediff-files function in dirvish.
+;; An accompanying ERT test ensures that the “d” key in the ediff map is correctly bound to ztree-diff.
-;; lose the control panel
-(csetq ediff-window-setup-function 'ediff-setup-windows-plain)
-
-;; only split horizontally
-(csetq ediff-split-window-function 'split-window-horizontally)
-
-;; ignore whitespace in diffs
-(csetq ediff-diff-options "-w")
+;; Note: Here's a highly useful setup for configuring ediff.
+;; https://oremacs.com/2015/01/17/setting-up-ediff/
-;; only highlight the current diff:
-(setq-default ediff-highlight-all-diffs 'nil)
+;;; Code:
-;; use j and k for next and previous diffs
-(defun cj/ediff-hook ()
- (ediff-setup-keymap)
- (define-key ediff-mode-map "j" 'ediff-next-difference)
- (define-key ediff-mode-map "k" 'ediff-previous-difference))
-(add-hook 'ediff-mode-hook 'cj/ediff-hook)
+(use-package ediff
+ :ensure nil ;; built-in
+ :defer 0.5
+ :custom
+ (ediff-window-setup-function 'ediff-setup-windows-plain)
+ (ediff-split-window-function 'split-window-horizontally)
+ (ediff-diff-options "-w")
+ (ediff-highlight-all-diffs nil)
+ :bind-keymap ("C-c e" . cj/ediff-map)
+ :init
+ ;; adding this to a hook to make sure ediff is loaded due to :defer
+ (defvar cj/ediff-map
+ (let ((m (make-sparse-keymap)))
+ (define-key m "f" #'ediff-files) ; C-c e f
+ (define-key m "b" #'ediff-buffers) ; C-c e b
+ (define-key m "r" #'ediff-revision) ; C-c e r
+ (define-key m "D" #'ediff-directories) ; C-c e D
+ m)
+ "Prefix map for quick Ediff commands under C-c e.")
+ (winner-mode 1)
+ :config
+ (defun cj/ediff-hook ()
+ "Use j/k to navigate and q to quit immediately in Ediff."
+ (ediff-setup-keymap) ;; keep the defaults…
+ (define-key ediff-mode-map "j" #'ediff-next-difference)
+ (define-key ediff-mode-map "k" #'ediff-previous-difference)
+ (define-key ediff-mode-map "q" #'ediff-quit))
-;; restore the window setup after quitting
-(winner-mode)
-(add-hook 'ediff-after-quit-hook-internal 'winner-undo)
+ (add-hook 'ediff-mode-hook #'cj/ediff-hook)
+ (add-hook 'ediff-after-quit-hook-internal #'winner-undo))
;; ----------------------------------- Ztree -----------------------------------
;; diff two directories
(use-package ztree
- :defer .5
+ :after ediff
+ :defer 0.5
:bind
- ("C-c D" . ztree-diff))
+ (:map cj/ediff-map
+ ("d" . ztree-diff)))
(provide 'diff-config)
;;; diff-config.el ends here.
+
+
+;; --------------------------------- ERT Tests ---------------------------------
+
+(ert-deftest ediff-config/ediff-map-includes-ztree-d ()
+ "Ensure that \"d\" in `cj/ediff-map' is bound to `ztree-diff'."
+ (should (eq (lookup-key cj/ediff-map "d") #'ztree-diff)))
+
+(ert-deftest ediff-config/ediff-mode-map-has-j-k-q ()
+ (with-temp-buffer
+ ;; force-load ediff
+ (require 'ediff)
+ (mapc (lambda (binding)
+ (let ((key (kbd (car binding)))
+ (fn (cdr binding)))
+ (should (eq (lookup-key ediff-mode-map key) fn))))
+ '(("j" . ediff-next-difference)
+ ("k" . ediff-previous-difference)
+ ("q" . ediff-quit)))))