aboutsummaryrefslogtreecommitdiffstats
path: root/modules/init-git.el
blob: c191f1da709ca802a598a4aa26b64980bba8dd28 (plain)
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
;;; init-git.el --- .Emacs Configuration -*- lexical-binding: t -*-
;;; Commentary:
;;

;;; Code:
(setq vc-follows-symlinks t
      find-file-visit-truename t
      vc-handled-backends nil)

(if (display-graphic-p)
    (use-package git-gutter-fringe
      :ensure t
      :config
      (global-git-gutter-mode t)
      (setq-default fringes-outside-margins nil)
      (setq-default left-fringe-width 10)
      (set-face-foreground 'git-gutter-fr:modified "purple")
      (set-face-foreground 'git-gutter-fr:added "green")
      (set-face-foreground 'git-gutter-fr:deleted "red")

      (defun my-reshape-git-gutter (gutter)
        "Re-shape gutter for `ivy-read'."
        (let* ((linenum-start (aref gutter 3))
               (linenum-end (aref gutter 4))
               (target-line "")
               (target-linenum 1)
               (tmp-line "")
               (max-line-length 0))
          (save-excursion
            (while (<= linenum-start linenum-end)
              (with-no-warnings
                (goto-line linenum-start))
              (setq tmp-line (replace-regexp-in-string "^[ \t]*" ""
                                                       (buffer-substring (line-beginning-position)
                                                                         (line-end-position))))
              (when (> (length tmp-line) max-line-length)
                (setq target-linenum linenum-start)
                (setq target-line tmp-line)
                (setq max-line-length (length tmp-line)))

              (setq linenum-start (1+ linenum-start))))
          ;; build (key . linenum-start)
          (cons (format "%s %d: %s"
                        (if (eq 'deleted (aref gutter 1)) "-" "+")
                        target-linenum target-line)
                target-linenum)))

      (defun my-goto-git-gutter ()
        (interactive)
        (eval-when-compile (require 'git-gutter-fringe nil t))
        (when (and (require 'git-gutter-fringe nil t)
                   (fboundp 'ivy-read))

          (if git-gutter-fr:diffinfos
              (ivy-read "git-gutters-fr:"
                        (mapcar 'my-reshape-git-gutter git-gutter-fr:diffinfos)
                        :action (lambda (e)
                                  ;; ivy9+ keep `(car e)'
                                  ;; ivy8- strip the `(car e)'
                                  ;; we handle both data structure
                                  (unless (numberp e) (setq e (cdr e)))
                                  (with-no-warnings
                                    (goto-line e))))
            (message "NO git-gutters-fringe!"))
          ))))

(use-package git-modes
  :ensure t
  :config
  (setq auto-mode-alist
        (append auto-mode-alist
                '(("/\\.?git/?config$" . gitconfig-mode)
                  ("/\\.gitmodules$" . gitconfig-mode)
                  ("/\\.gitignore$" . gitignore-mode)
                  ("/\\.git/info/exclude$" . gitignore-mode)
                  ("/git/ignore$" . gitignore-mode)
                  ("/.dockerignore\\'" . gitignore-mode)
                  ("/\\.gitattributes\\'" . gitattributes-mode)
                  ("/info/attributes\\'" . gitattributes-mode)
                  ("/git/attributes\\'" . gitattributes-mode)))))

(use-package git-timemachine
  :ensure t
  :commands git-timemachine
  :bind (:map git-timemachine-mode
              ("c" . git-timemachine-show-current-revision)
              ("b" . git-timemachine-switch-branch)))

;;; smerge-mode video explain https://emacsgifs.github.io/public/videos/758861381898637313.mp4
(use-package smerge-mode
  :ensure t
  :config
  (defun enable-smerge-maybe ()
    (when (and buffer-file-name (vc-backend buffer-file-name))
      (save-excursion
        (goto-char (point-min))
        (when (re-search-forward "^<<<<<<< " nil t)
          (smerge-mode +1)))))

  (eval-when-compile (require 'smerge-mode nil t))
  (when (and (require 'smerge-mode nil t)
             (fboundp 'enable-smerge-maybe))
    (add-hook 'buffer-list-update-hook #'enable-smerge-maybe)))

(provide 'init-git)

;; Local Variables:
;; byte-compile-warnings: (not free-vars)
;; End:
;;; init-git.el ends here