forked from redguardtoo/emacs.d
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit-ediff.el
87 lines (75 loc) · 3.61 KB
/
init-ediff.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
;; -*- coding: utf-8; lexical-binding: t; -*-
(defvar my-ediff-panel-name nil)
(defun my-server-save-buffers-kill-terminal-hack (&optional arg)
"Kill buffers to create ediff panel and call `ediff-startup-hook-setup'.
Also remove buffers whose binding files already merged in `buffer-list'."
(mapc 'kill-buffer (buffer-list)))
(advice-add 'server-save-buffers-kill-terminal :after #'my-server-save-buffers-kill-terminal-hack)
(when (my-vc-merge-p)
;; remove `org-mode' from `auto-mode-alist'. So nodes in org file do NOT collapse at all
(setq auto-mode-alist (rassq-delete-all 'org-mode auto-mode-alist))
;; associate simpler major mode with org file instead
(my-add-auto-mode 'outline-mode "\\.org\\(_archive\\)?$")
(defmacro my-ediff-command (cmd &optional no-arg)
`(lambda (&optional arg)
(interactive "P")
(let* ((w (get-buffer-window))
(p (get-buffer-window my-ediff-panel-name)))
;; go to panel window
(when p
(select-window p)
;; execute ediff command, ignore any error
(condition-case e
(if ,no-arg (funcall ,cmd) (funcall ,cmd arg))
(error
(message "%s" (error-message-string e))))
;; back to original window
(select-window w)))))
(my-ensure 'ediff)
;; @see https://stackoverflow.com/a/29757750/245363
(defun ediff-copy-both-to-C (&optional arg)
"Copy code from both A and B to C."
(interactive)
(ediff-copy-diff ediff-current-difference nil 'C nil
(concat
(ediff-get-region-contents ediff-current-difference 'A ediff-control-buffer)
(ediff-get-region-contents ediff-current-difference 'B ediff-control-buffer))))
(my-space-leader-def
"a" (lambda () (interactive) (jump-to-register ?a))
"t" (my-ediff-command 'ediff-toggle-show-clashes-only t)
"n" (my-ediff-command (lambda (arg)
(cond
((< ediff-current-difference (1- ediff-number-of-differences))
(ediff-next-difference arg))
(t
(message "This is last difference!")))))
"p" (my-ediff-command (lambda (arg)
(cond
((> ediff-current-difference 0)
(ediff-previous-difference arg))
(t
(message "This is first difference!")))))
"r" (my-ediff-command 'ediff-restore-diff-in-merge-buffer)
;; press "1-space-R" to revert without confirmation
"R" (my-ediff-command 'ediff-revert-buffers-then-recompute-diffs)
"xa" (lambda () (interactive) (save-buffers-kill-terminal t)) ; similar to vim
;; use 1 3 as hotkey to be consistent with vim
"1" (my-ediff-command 'ediff-copy-A-to-C)
"3" (my-ediff-command 'ediff-copy-B-to-C)
"b" (my-ediff-command 'ediff-copy-both-to-C))
(defun ediff-startup-hook-setup ()
;; hide control panel if it's current buffer
(when (string-match-p "\*Ediff Control Panel.*\*" (buffer-name))
(unless my-ediff-panel-name (setq my-ediff-panel-name (buffer-name)))
;; load color theme for merge
(load-theme 'tao-yang t)
;; show only clashed area
(ediff-toggle-show-clashes-only)
;; move to the first difference
(ediff-next-difference)
;; move to the merged buffer window
(winum-select-window-by-number 3)
;; save the windows layout
(window-configuration-to-register ?a)))
(add-hook 'ediff-startup-hook 'ediff-startup-hook-setup))
(provide 'init-ediff)