init-git.el 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. ;;; init-git.el --- .Emacs Configuration -*- lexical-binding: t -*-
  2. ;;; Commentary:
  3. ;;
  4. ;;; Code:
  5. (setq vc-follows-symlinks t
  6. find-file-visit-truename t
  7. vc-handled-backends nil)
  8. (if (display-graphic-p)
  9. (use-package git-gutter-fringe
  10. :ensure t
  11. :config
  12. (global-git-gutter-mode t)
  13. (setq-default fringes-outside-margins nil)
  14. (setq-default left-fringe-width 10)
  15. (set-face-foreground 'git-gutter-fr:modified "purple")
  16. (set-face-foreground 'git-gutter-fr:added "green")
  17. (set-face-foreground 'git-gutter-fr:deleted "red")
  18. (defun my-reshape-git-gutter (gutter)
  19. "Re-shape gutter for `ivy-read'."
  20. (let* ((linenum-start (aref gutter 3))
  21. (linenum-end (aref gutter 4))
  22. (target-line "")
  23. (target-linenum 1)
  24. (tmp-line "")
  25. (max-line-length 0))
  26. (save-excursion
  27. (while (<= linenum-start linenum-end)
  28. (with-no-warnings
  29. (goto-line linenum-start))
  30. (setq tmp-line (replace-regexp-in-string "^[ \t]*" ""
  31. (buffer-substring (line-beginning-position)
  32. (line-end-position))))
  33. (when (> (length tmp-line) max-line-length)
  34. (setq target-linenum linenum-start)
  35. (setq target-line tmp-line)
  36. (setq max-line-length (length tmp-line)))
  37. (setq linenum-start (1+ linenum-start))))
  38. ;; build (key . linenum-start)
  39. (cons (format "%s %d: %s"
  40. (if (eq 'deleted (aref gutter 1)) "-" "+")
  41. target-linenum target-line)
  42. target-linenum)))
  43. (defun my-goto-git-gutter ()
  44. (interactive)
  45. (eval-when-compile (require 'git-gutter-fringe nil t))
  46. (when (and (require 'git-gutter-fringe nil t)
  47. (fboundp 'ivy-read))
  48. (if git-gutter-fr:diffinfos
  49. (ivy-read "git-gutters-fr:"
  50. (mapcar 'my-reshape-git-gutter git-gutter-fr:diffinfos)
  51. :action (lambda (e)
  52. ;; ivy9+ keep `(car e)'
  53. ;; ivy8- strip the `(car e)'
  54. ;; we handle both data structure
  55. (unless (numberp e) (setq e (cdr e)))
  56. (with-no-warnings
  57. (goto-line e))))
  58. (message "NO git-gutters-fringe!"))
  59. ))))
  60. (use-package git-modes
  61. :ensure t
  62. :mode
  63. ("/\\.?git/?config$" . gitconfig-mode)
  64. ("/\\.gitmodules$" . gitconfig-mode)
  65. ("/\\.gitignore$" . gitignore-mode)
  66. ("/\\.git/info/exclude$" . gitignore-mode)
  67. ("/git/ignore$" . gitignore-mode)
  68. ("/.dockerignore\\'" . gitignore-mode)
  69. ("/\\.gitattributes\\'" . gitattributes-mode)
  70. ("/info/attributes\\'" . gitattributes-mode)
  71. ("/git/attributes\\'" . gitattributes-mode))
  72. (use-package git-timemachine
  73. :ensure t
  74. :commands git-timemachine
  75. :bind (:map git-timemachine-mode
  76. ("c" . git-timemachine-show-current-revision)
  77. ("b" . git-timemachine-switch-branch)))
  78. ;;; smerge-mode video explain https://emacsgifs.github.io/public/videos/758861381898637313.mp4
  79. (use-package smerge-mode
  80. :ensure t
  81. :config
  82. (defun enable-smerge-maybe ()
  83. (when (and buffer-file-name (vc-backend buffer-file-name))
  84. (save-excursion
  85. (goto-char (point-min))
  86. (when (re-search-forward "^<<<<<<< " nil t)
  87. (smerge-mode +1)))))
  88. (eval-when-compile (require 'smerge-mode nil t))
  89. (when (and (require 'smerge-mode nil t)
  90. (fboundp 'enable-smerge-maybe))
  91. (add-hook 'buffer-list-update-hook #'enable-smerge-maybe)))
  92. (provide 'init-git)
  93. ;; Local Variables:
  94. ;; byte-compile-warnings: (not free-vars)
  95. ;; End:
  96. ;;; init-git.el ends here