2018-06-21 21:14:00 +02:00
|
|
|
;;; ui/vc-gutter/config.el -*- lexical-binding: t; -*-
|
|
|
|
|
|
|
|
(defvar +vc-gutter-in-margin nil
|
|
|
|
"If non-nil, use the margin for diffs instead of the fringe.")
|
|
|
|
|
|
|
|
(defvar +vc-gutter-in-remote-files nil
|
|
|
|
"If non-nil, enable the vc gutter in remote files (e.g. open through TRAMP).")
|
|
|
|
|
|
|
|
(defvar +vc-gutter-diff-unsaved-buffer nil
|
|
|
|
"If non-nil, `diff-hl-flydiff-mode' will be activated. This allows on-the-fly
|
|
|
|
diffing, even for unsaved buffers.")
|
|
|
|
|
|
|
|
(defvar +vc-gutter-default-style t
|
2020-02-23 15:41:49 -05:00
|
|
|
"If non-nil, enable the default look of the vc gutter.
|
|
|
|
This means subtle thin bitmaps on the left, an arrow bitmap for flycheck, and
|
|
|
|
flycheck indicators moved to the right fringe.")
|
2018-06-21 21:14:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
;;
|
2018-09-07 19:36:16 -04:00
|
|
|
;; Packages
|
2018-06-21 21:14:00 +02:00
|
|
|
|
2019-07-23 12:44:03 +02:00
|
|
|
(use-package! git-gutter
|
2019-07-22 19:11:12 +02:00
|
|
|
:commands git-gutter:revert-hunk git-gutter:stage-hunk
|
2018-06-21 21:14:00 +02:00
|
|
|
:init
|
2019-07-26 19:57:13 +02:00
|
|
|
(add-hook! 'find-file-hook
|
2019-07-18 15:27:20 +02:00
|
|
|
(defun +vc-gutter-init-maybe-h ()
|
|
|
|
"Enable `git-gutter-mode' in the current buffer.
|
2019-05-06 02:14:14 -04:00
|
|
|
|
|
|
|
If the buffer doesn't represent an existing file, `git-gutter-mode's activation
|
2019-06-14 11:08:59 +02:00
|
|
|
is deferred until the file is saved. Respects `git-gutter:disabled-modes'."
|
2020-02-25 12:49:52 -05:00
|
|
|
(let ((file-name (buffer-file-name (buffer-base-buffer))))
|
|
|
|
(when (or +vc-gutter-in-remote-files
|
|
|
|
(not (file-remote-p (or file-name default-directory))))
|
|
|
|
(if (null file-name)
|
|
|
|
(add-hook 'after-save-hook #'+vc-gutter-init-maybe-h nil 'local)
|
|
|
|
(when (and (vc-backend file-name)
|
|
|
|
(progn
|
|
|
|
(require 'git-gutter)
|
|
|
|
(not (memq major-mode git-gutter:disabled-modes))))
|
|
|
|
(if (and (display-graphic-p)
|
|
|
|
(require 'git-gutter-fringe nil t))
|
|
|
|
(progn
|
|
|
|
(setq-local git-gutter:init-function #'git-gutter-fr:init)
|
|
|
|
(setq-local git-gutter:view-diff-function #'git-gutter-fr:view-diff-infos)
|
|
|
|
(setq-local git-gutter:clear-function #'git-gutter-fr:clear)
|
|
|
|
(setq-local git-gutter:window-width -1))
|
|
|
|
(setq-local git-gutter:init-function 'nil)
|
|
|
|
(setq-local git-gutter:view-diff-function #'git-gutter:view-diff-infos)
|
|
|
|
(setq-local git-gutter:clear-function #'git-gutter:clear-diff-infos)
|
|
|
|
(setq-local git-gutter:window-width 1))
|
|
|
|
(git-gutter-mode +1)
|
|
|
|
(remove-hook 'after-save-hook #'+vc-gutter-init-maybe-h 'local)))))))
|
2019-07-18 15:27:20 +02:00
|
|
|
|
2019-07-21 15:24:07 +02:00
|
|
|
;; Disable in Org mode, as per
|
|
|
|
;; <https://github.com/syl20bnr/spacemacs/issues/10555> and
|
|
|
|
;; <https://github.com/syohex/emacs-git-gutter/issues/24>. Apparently, the
|
|
|
|
;; mode-enabling function for global minor modes gets called for new buffers
|
|
|
|
;; while they are still in `fundamental-mode', before a major mode has been
|
|
|
|
;; assigned. I don't know why this is the case, but adding `fundamental-mode'
|
|
|
|
;; here fixes the issue.
|
2019-07-23 20:43:35 +02:00
|
|
|
(setq git-gutter:disabled-modes '(fundamental-mode image-mode pdf-view-mode))
|
2018-06-21 21:14:00 +02:00
|
|
|
:config
|
2020-03-01 01:36:16 -05:00
|
|
|
;; Only enable the backends that are available, so it doesn't have to check
|
|
|
|
;; when opening each buffer.
|
|
|
|
(setq git-gutter:handled-backends '(git))
|
|
|
|
(dolist (backend '(hg svn bzr))
|
|
|
|
(when (executable-find (symbol-name backend))
|
|
|
|
(add-to-list 'git-gutter:handled-backends backend)))
|
|
|
|
|
2019-05-21 17:23:18 -04:00
|
|
|
(set-popup-rule! "^\\*git-gutter" :select nil :size '+popup-shrink-to-fit)
|
2018-06-21 21:14:00 +02:00
|
|
|
|
|
|
|
;; Update git-gutter on focus (in case I was using git externally)
|
|
|
|
(add-hook 'focus-in-hook #'git-gutter:update-all-windows)
|
|
|
|
|
2019-07-26 19:57:13 +02:00
|
|
|
(add-hook! '(doom-escape-hook doom-switch-window-hook) :append
|
2019-07-18 15:27:20 +02:00
|
|
|
(defun +vc-gutter-update-h (&rest _)
|
|
|
|
"Refresh git-gutter on ESC. Return nil to prevent shadowing other
|
2018-06-21 21:14:00 +02:00
|
|
|
`doom-escape-hook' hooks."
|
2019-07-23 18:18:43 +02:00
|
|
|
(when (and git-gutter-mode
|
|
|
|
(not (memq this-command '(git-gutter:stage-hunk
|
Fix infinite redrawing/freezing with {centaur,awesome}-tabs
Caused by over-zealous doom-switch-window-hook.
For my own sanity (and if you're curious), I'll break it down here:
1. Doom has a `doom-switch-window-hook` hook. It triggers when window
focus is changed.
2. We use `buffer-list-update-hook` to trigger
`doom-switch-window-hook`. (That may sound weird, but this hook is
reliably executed when window focus is changed -- there are
safeguards to prevent this from triggering too often)
3. `buffer-list-update-hook` triggers whenever a buffer is created, but
`doom-switch-window-hook` only triggers if the created buffer is in
a new window.
4. The use of `with-temp-buffer` in `centaur-tabs-line-format` counts as
"buffer creation" in a "new window".
5. `+vc-gutter-update-h` is in `doom-switch-window-hook`. This refreshes
git-gutter, which initiates a redraw of Emacs.
6. When Emacs redraws, it recalculates its mode and header lines. which
triggers `doom-switch-window-hook` once, which triggers
`+vc-gutter-update-h`, which redraws the screen, then Emacs recalculates
the header line, running `centaur-tabs-line-format`...
Infinite loop ensues
Hopefully fixes:
- hlissner/doom-emacs#2436
- ema2159/centaur-tabs#18
- ema2159/centaur-tabs#88
2020-02-27 21:47:32 -05:00
|
|
|
git-gutter:revert-hunk)))
|
|
|
|
(not inhibit-redisplay))
|
2019-07-18 15:27:20 +02:00
|
|
|
(ignore (git-gutter)))))
|
2018-07-12 18:47:36 +02:00
|
|
|
;; update git-gutter when using magit commands
|
2019-07-18 15:27:20 +02:00
|
|
|
(advice-add #'magit-stage-file :after #'+vc-gutter-update-h)
|
2019-09-27 15:15:30 -04:00
|
|
|
(advice-add #'magit-unstage-file :after #'+vc-gutter-update-h)
|
|
|
|
|
|
|
|
(defadvice! +vc-gutter--fix-linearity-of-hunks-a (diffinfos is-reverse)
|
|
|
|
"Fixes `git-gutter:next-hunk' and `git-gutter:previous-hunk' sometimes
|
|
|
|
jumping to random hunks."
|
|
|
|
:override #'git-gutter:search-near-diff-index
|
|
|
|
(cl-position-if (let ((lineno (line-number-at-pos)))
|
|
|
|
(lambda (line)
|
|
|
|
(funcall (if is-reverse #'> #'<) lineno line)))
|
|
|
|
diffinfos
|
|
|
|
:key #'git-gutter-hunk-start-line
|
|
|
|
:from-end is-reverse)))
|
2018-06-21 21:14:00 +02:00
|
|
|
|
2018-10-03 19:01:06 -04:00
|
|
|
|
|
|
|
;; subtle diff indicators in the fringe
|
2020-02-27 14:52:53 -05:00
|
|
|
(after! git-gutter-fringe
|
|
|
|
(when +vc-gutter-default-style
|
|
|
|
;; standardize default fringe width
|
|
|
|
(if (fboundp 'fringe-mode) (fringe-mode '4))
|
2020-02-23 15:41:49 -05:00
|
|
|
|
2018-06-21 21:14:00 +02:00
|
|
|
;; places the git gutter outside the margins.
|
|
|
|
(setq-default fringes-outside-margins t)
|
|
|
|
;; thin fringe bitmaps
|
|
|
|
(define-fringe-bitmap 'git-gutter-fr:added [224]
|
|
|
|
nil nil '(center repeated))
|
|
|
|
(define-fringe-bitmap 'git-gutter-fr:modified [224]
|
|
|
|
nil nil '(center repeated))
|
|
|
|
(define-fringe-bitmap 'git-gutter-fr:deleted [128 192 224 240]
|
2020-02-27 14:52:53 -05:00
|
|
|
nil nil 'bottom)))
|
|
|
|
|
|
|
|
(after! flycheck
|
|
|
|
(when +vc-gutter-default-style
|
2018-06-21 21:14:00 +02:00
|
|
|
;; let diff have left fringe, flycheck can have right fringe
|
2020-02-25 12:45:30 -05:00
|
|
|
(setq flycheck-indication-mode 'right-fringe)
|
|
|
|
;; A non-descript, left-pointing arrow
|
|
|
|
(define-fringe-bitmap 'flycheck-fringe-bitmap-double-arrow
|
|
|
|
[16 48 112 240 112 48 16] nil nil 'center)))
|