Klimi's new dotfiles with stow.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

258 řádky
10 KiB

před 5 roky
  1. ;;; magit-autorevert.el --- revert buffers when files in repository change -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2010-2019 The Magit Project Contributors
  3. ;;
  4. ;; You should have received a copy of the AUTHORS.md file which
  5. ;; lists all contributors. If not, see http://magit.vc/authors.
  6. ;; Author: Jonas Bernoulli <jonas@bernoul.li>
  7. ;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
  8. ;; Magit is free software; you can redistribute it and/or modify it
  9. ;; under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation; either version 3, or (at your option)
  11. ;; any later version.
  12. ;;
  13. ;; Magit is distributed in the hope that it will be useful, but WITHOUT
  14. ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  15. ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  16. ;; License for more details.
  17. ;;
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with Magit. If not, see http://www.gnu.org/licenses.
  20. ;;; Code:
  21. (require 'cl-lib)
  22. (require 'dash)
  23. (require 'magit-git)
  24. (require 'autorevert)
  25. ;;; Options
  26. (defgroup magit-auto-revert nil
  27. "Revert buffers when files in repository change."
  28. :link '(custom-group-link auto-revert)
  29. :link '(info-link "(magit)Automatic Reverting of File-Visiting Buffers")
  30. :group 'auto-revert
  31. :group 'magit-essentials
  32. :group 'magit-modes)
  33. (defcustom auto-revert-buffer-list-filter nil
  34. "Filter that determines which buffers `auto-revert-buffers' reverts.
  35. This option is provided by Magit, which also advises
  36. `auto-revert-buffers' to respect it. Magit users who do not turn
  37. on the local mode `auto-revert-mode' themselves, are best served
  38. by setting the value to `magit-auto-revert-repository-buffer-p'.
  39. However the default is nil, so as not to disturb users who do use
  40. the local mode directly. If you experience delays when running
  41. Magit commands, then you should consider using one of the
  42. predicates provided by Magit - especially if you also use Tramp.
  43. Users who do turn on `auto-revert-mode' in buffers in which Magit
  44. doesn't do that for them, should likely not use any filter.
  45. Users who turn on `global-auto-revert-mode', do not have to worry
  46. about this option, because it is disregarded if the global mode
  47. is enabled."
  48. :package-version '(magit . "2.4.2")
  49. :group 'auto-revert
  50. :group 'magit-auto-revert
  51. :group 'magit-related
  52. :type '(radio (const :tag "No filter" nil)
  53. (function-item magit-auto-revert-buffer-p)
  54. (function-item magit-auto-revert-repository-buffer-p)
  55. function))
  56. (defcustom magit-auto-revert-tracked-only t
  57. "Whether `magit-auto-revert-mode' only reverts tracked files."
  58. :package-version '(magit . "2.4.0")
  59. :group 'magit-auto-revert
  60. :type 'boolean
  61. :set (lambda (var val)
  62. (set var val)
  63. (when (and (bound-and-true-p magit-auto-revert-mode)
  64. (featurep 'magit-autorevert))
  65. (magit-auto-revert-mode -1)
  66. (magit-auto-revert-mode))))
  67. (defcustom magit-auto-revert-immediately t
  68. "Whether Magit reverts buffers immediately.
  69. If this is non-nil and either `global-auto-revert-mode' or
  70. `magit-auto-revert-mode' is enabled, then Magit immediately
  71. reverts buffers by explicitly calling `auto-revert-buffers'
  72. after running Git for side-effects.
  73. If `auto-revert-use-notify' is non-nil (and file notifications
  74. are actually supported), then `magit-auto-revert-immediately'
  75. does not have to be non-nil, because the reverts happen
  76. immediately anyway.
  77. If `magit-auto-revert-immediately' and `auto-revert-use-notify'
  78. are both nil, then reverts happen after `auto-revert-interval'
  79. seconds of user inactivity. That is not desirable."
  80. :package-version '(magit . "2.4.0")
  81. :group 'magit-auto-revert
  82. :type 'boolean)
  83. ;;; Mode
  84. (defun magit-turn-on-auto-revert-mode-if-desired (&optional file)
  85. (if file
  86. (--when-let (find-buffer-visiting file)
  87. (with-current-buffer it
  88. (magit-turn-on-auto-revert-mode-if-desired)))
  89. (when (and buffer-file-name
  90. (file-readable-p buffer-file-name)
  91. (magit-toplevel)
  92. (or (not magit-auto-revert-tracked-only)
  93. (magit-file-tracked-p buffer-file-name))
  94. (not auto-revert-mode) ; see #3014
  95. (not global-auto-revert-mode)) ; see #3460
  96. (auto-revert-mode 1))))
  97. ;;;###autoload
  98. (define-globalized-minor-mode magit-auto-revert-mode auto-revert-mode
  99. magit-turn-on-auto-revert-mode-if-desired
  100. :package-version '(magit . "2.4.0")
  101. :link '(info-link "(magit)Automatic Reverting of File-Visiting Buffers")
  102. :group 'magit-auto-revert
  103. :group 'magit-essentials
  104. ;; - When `global-auto-revert-mode' is enabled, then this mode is
  105. ;; redundant.
  106. ;; - In all other cases enable the mode because if buffers are not
  107. ;; automatically reverted that would make many very common tasks
  108. ;; much more cumbersome.
  109. :init-value (not (or global-auto-revert-mode
  110. noninteractive)))
  111. ;; - Unfortunately `:init-value t' only sets the value of the mode
  112. ;; variable but does not cause the mode function to be called.
  113. ;; - I don't think it works like this on purpose, but since one usually
  114. ;; should not enable global modes by default, it is understandable.
  115. ;; - If the user has set the variable `magit-auto-revert-mode' to nil
  116. ;; after loading magit (instead of doing so before loading magit or
  117. ;; by using the function), then we should still respect that setting.
  118. ;; - If the user sets one of these variables after loading magit and
  119. ;; after `after-init-hook' has run, then that won't have an effect
  120. ;; and there is nothing we can do about it.
  121. (defun magit-auto-revert-mode--init-kludge ()
  122. "This is an internal kludge to be used on `after-init-hook'.
  123. Do not use this function elsewhere, and don't remove it from
  124. the `after-init-hook'. For more information see the comments
  125. and code surrounding the definition of this function."
  126. (if magit-auto-revert-mode
  127. (let ((start (current-time)))
  128. (magit-message "Turning on magit-auto-revert-mode...")
  129. (magit-auto-revert-mode 1)
  130. (magit-message
  131. "Turning on magit-auto-revert-mode...done%s"
  132. (let ((elapsed (float-time (time-subtract nil start))))
  133. (if (> elapsed 0.2)
  134. (format " (%.3fs, %s buffers checked)" elapsed
  135. (length (buffer-list)))
  136. ""))))
  137. (magit-auto-revert-mode -1)))
  138. (if after-init-time
  139. ;; Since `after-init-hook' has already been
  140. ;; run, turn the mode on or off right now.
  141. (magit-auto-revert-mode--init-kludge)
  142. ;; By the time the init file has been fully loaded the
  143. ;; values of the relevant variables might have changed.
  144. (add-hook 'after-init-hook #'magit-auto-revert-mode--init-kludge t))
  145. (put 'magit-auto-revert-mode 'function-documentation
  146. "Toggle Magit Auto Revert mode.
  147. If called interactively, enable Magit Auto Revert mode if ARG is
  148. positive, and disable it if ARG is zero or negative. If called
  149. from Lisp, also enable the mode if ARG is omitted or nil, and
  150. toggle it if ARG is `toggle'; disable the mode otherwise.
  151. Magit Auto Revert mode is a global minor mode that reverts
  152. buffers associated with a file that is located inside a Git
  153. repository when the file changes on disk. Use `auto-revert-mode'
  154. to revert a particular buffer. Or use `global-auto-revert-mode'
  155. to revert all file-visiting buffers, not just those that visit
  156. a file located inside a Git repository.
  157. This global mode works by turning on the buffer-local mode
  158. `auto-revert-mode' at the time a buffer is first created. The
  159. local mode is turned on if the visited file is being tracked in
  160. a Git repository at the time when the buffer is created.
  161. If `magit-auto-revert-tracked-only' is non-nil (the default),
  162. then only tracked files are reverted. But if you stage a
  163. previously untracked file using `magit-stage', then this mode
  164. notices that.
  165. Unlike `global-auto-revert-mode', this mode never reverts any
  166. buffers that are not visiting files.
  167. The behavior of this mode can be customized using the options
  168. in the `autorevert' and `magit-autorevert' groups.
  169. This function calls the hook `magit-auto-revert-mode-hook'.")
  170. (defun magit-auto-revert-buffers ()
  171. (when (and magit-auto-revert-immediately
  172. (or global-auto-revert-mode
  173. (and magit-auto-revert-mode auto-revert-buffer-list)))
  174. (let ((auto-revert-buffer-list-filter
  175. (or auto-revert-buffer-list-filter
  176. #'magit-auto-revert-repository-buffer-p)))
  177. (auto-revert-buffers))))
  178. (defvar magit-auto-revert-toplevel nil)
  179. (defvar magit-auto-revert-counter 1
  180. "Incremented each time `auto-revert-buffers' is called.")
  181. (defun magit-auto-revert-buffer-p (buffer)
  182. "Return non-nil if BUFFER visits a file inside the current repository.
  183. The current repository is the one containing `default-directory'.
  184. If there is no current repository, then return t for any BUFFER."
  185. (magit-auto-revert-repository-buffer-p buffer t))
  186. (defun magit-auto-revert-repository-buffer-p (buffer &optional fallback)
  187. "Return non-nil if BUFFER visits a file inside the current repository.
  188. The current repository is the one containing `default-directory'.
  189. If there is no current repository, then return FALLBACK (which
  190. defaults to nil) for any BUFFER."
  191. ;; Call `magit-toplevel' just once per cycle.
  192. (unless (and magit-auto-revert-toplevel
  193. (= (cdr magit-auto-revert-toplevel)
  194. magit-auto-revert-counter))
  195. (setq magit-auto-revert-toplevel
  196. (cons (or (magit-toplevel) 'no-repo)
  197. magit-auto-revert-counter)))
  198. (let ((top (car magit-auto-revert-toplevel)))
  199. (if (eq top 'no-repo)
  200. fallback
  201. (let ((dir (buffer-local-value 'default-directory buffer)))
  202. (and (equal (file-remote-p dir)
  203. (file-remote-p top))
  204. ;; ^ `tramp-handle-file-in-directory-p' lacks this optimization.
  205. (file-in-directory-p dir top))))))
  206. (defun auto-revert-buffers--buffer-list-filter (fn)
  207. (cl-incf magit-auto-revert-counter)
  208. (if (or global-auto-revert-mode
  209. (not auto-revert-buffer-list)
  210. (not auto-revert-buffer-list-filter))
  211. (funcall fn)
  212. (let ((auto-revert-buffer-list
  213. (-filter auto-revert-buffer-list-filter
  214. auto-revert-buffer-list)))
  215. (funcall fn))
  216. (unless auto-revert-timer
  217. (auto-revert-set-timer))))
  218. (advice-add 'auto-revert-buffers :around
  219. 'auto-revert-buffers--buffer-list-filter)
  220. ;;; _
  221. (provide 'magit-autorevert)
  222. ;;; magit-autorevert.el ends here