Skip to content

Commit f4063d9

Browse files
Yann Hodiquesigma
Yann Hodique
authored andcommitted
extensions as minor modes
This patch changes the strategy for loading magit extensions. Until now, `require'-ing the extension file was sufficient to enable it for every git repository. This is probably not the right behavior, because some extensions might not apply to in every case. For example, there is little sense using both topgit and stgit in the same repo, but one could to use one or the other depending on the case. Extensions such as https://github.com/sigma/magit-gh-pulls will make sense only for repositories hosted in GitHub. In any case, it would probably be desirable for the user to be able to toggle the use of a specific extension. We reach that goal by making extensions minor modes (as was initially quickly discussed when I introduced extensions). For example, toggling `magit-topgit-mode' while in the "status" buffer will make the "Topics" section appear/disappear. Therefore, extensions can now be loaded with code like: (add-hook 'magit-mode-hook 'turn-on-magit-topgit) Additionally, it is possible to introduce git configuration elements to automatically load relevant extensions (configured on a global and/or per repository basis) (add-hook 'magit-mode-hook 'magit-load-config-extensions) This will in effect call "git config --get-all magit.extension" in the repository and load whatever extensions are required there In the following case: $ git config --get-all magit.extension topgit svn the minor modes `magit-topgit-mode' and `magit-svn-mode' will be activated. Signed-off-by: Yann Hodique <[email protected]>
1 parent a1bdd47 commit f4063d9

File tree

3 files changed

+74
-23
lines changed

3 files changed

+74
-23
lines changed

magit-svn.el

+30-9
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ If USE-CACHE is non nil, use the cached information."
170170
nil
171171
"Git SVN extension menu"
172172
'("Git SVN"
173+
:visible magit-svn-mode
173174
["Create branch" magit-svn-create-branch (magit-svn-enabled)]
174175
["Rebase" magit-svn-rebase (magit-svn-enabled)]
175176
["Fetch" magit-svn-remote-update (magit-svn-enabled)]
@@ -179,14 +180,6 @@ If USE-CACHE is non nil, use the cached information."
179180
'("Extensions")
180181
magit-svn-extension-menu)
181182

182-
(add-hook 'magit-after-insert-unpulled-commits-hook
183-
(lambda () (magit-insert-svn-unpulled t)))
184-
185-
(add-hook 'magit-after-insert-unpushed-commits-hook
186-
(lambda () (magit-insert-svn-unpushed t)))
187-
188-
(add-hook 'magit-remote-string-hook 'magit-svn-remote-string)
189-
190183
;; add the group and its keys
191184
(progn
192185
;; (re-)create the group
@@ -201,7 +194,35 @@ If USE-CACHE is non nil, use the cached information."
201194
;; generate and bind the menu popup function
202195
(magit-key-mode-generate 'svn))
203196

204-
(define-key magit-mode-map (kbd "N") 'magit-key-mode-popup-svn)
197+
(defvar magit-svn-mode-map
198+
(let ((map (make-sparse-keymap)))
199+
(define-key map (kbd "N") 'magit-key-mode-popup-svn)
200+
map))
201+
202+
;;;###autoload
203+
(define-minor-mode magit-svn-mode "SVN support for Magit"
204+
:lighter " SVN" :require 'magit-svn :keymap 'magit-svn-mode-map
205+
(or (derived-mode-p 'magit-mode)
206+
(error "This mode only makes sense with magit"))
207+
(let ((unpulled-hook (lambda () (magit-insert-svn-unpulled t)))
208+
(unpushed-hook (lambda () (magit-insert-svn-unpushed t)))
209+
(remote-hook 'magit-svn-remote-string))
210+
(if magit-svn-mode
211+
(progn
212+
(add-hook 'magit-after-insert-unpulled-commits-hook unpulled-hook nil t)
213+
(add-hook 'magit-after-insert-unpushed-commits-hook unpushed-hook nil t)
214+
(add-hook 'magit-remote-string-hook remote-hook nil t))
215+
(progn
216+
(remove-hook 'magit-after-insert-unpulled-commits-hook unpulled-hook t)
217+
(remove-hook 'magit-after-insert-unpushed-commits-hook unpushed-hook t)
218+
(remove-hook 'magit-remote-string-hook remote-hook t)))
219+
(when (called-interactively-p 'any)
220+
(magit-refresh))))
221+
222+
;;;###autoload
223+
(defun turn-on-magit-svn ()
224+
"Unconditionally turn on `magit-svn-mode'."
225+
(magit-svn-mode 1))
205226

206227
(provide 'magit-svn)
207228
;;; magit-svn.el ends here

magit-topgit.el

+36-14
Original file line numberDiff line numberDiff line change
@@ -143,27 +143,49 @@
143143
((topic)
144144
(magit-checkout info)))
145145

146-
(add-hook 'magit-after-insert-stashes-hook 'magit-insert-topics)
147-
148-
(add-hook 'magit-create-branch-command-hook 'magit-topgit-create-branch)
149-
(add-hook 'magit-pull-command-hook 'magit-topgit-pull)
150-
(add-hook 'magit-remote-update-command-hook 'magit-topgit-remote-update)
151-
(add-hook 'magit-push-command-hook 'magit-topgit-push)
152-
153146
(defun magit-topgit-get-top-bases-color (suffix)
154147
(list nil nil))
155148

156149
(defun magit-topgit-get-remote-top-bases-color (suffix)
157150
(when (string-match "^\\(?:[^/]+\\)/top-bases" suffix)
158151
(list nil nil)))
159152

160-
;; hide refs in the top-bases namespace, as they're not meant for the user
161-
(add-to-list 'magit-refs-namespaces
162-
'("top-bases" magit-topgit-get-top-bases-color))
163-
164-
;; same thing for top-bases namespace in any remote
165-
(add-hook 'magit-log-remotes-color-hook
166-
'magit-topgit-get-remote-top-bases-color)
153+
(defconst magit-topgit-ignored-namespace
154+
'("top-bases" magit-topgit-get-top-bases-color))
155+
156+
;;;###autoload
157+
(define-minor-mode magit-topgit-mode "Topgit support for Magit"
158+
:lighter " Topgit" :require 'magit-topgit
159+
(or (derived-mode-p 'magit-mode)
160+
(error "This mode only makes sense with magit"))
161+
(if magit-topgit-mode
162+
(progn
163+
(add-hook 'magit-after-insert-stashes-hook 'magit-insert-topics nil t)
164+
(add-hook 'magit-create-branch-command-hook 'magit-topgit-create-branch nil t)
165+
(add-hook 'magit-pull-command-hook 'magit-topgit-pull nil t)
166+
(add-hook 'magit-remote-update-command-hook 'magit-topgit-remote-update nil t)
167+
(add-hook 'magit-push-command-hook 'magit-topgit-push nil t)
168+
;; hide refs for top-bases namespace in any remote
169+
(add-hook 'magit-log-remotes-color-hook
170+
'magit-topgit-get-remote-top-bases-color)
171+
;; hide refs in the top-bases namespace, as they're not meant for the user
172+
(add-to-list 'magit-refs-namespaces magit-topgit-ignored-namespace))
173+
(progn
174+
(remove-hook 'magit-after-insert-stashes-hook 'magit-insert-topics t)
175+
(remove-hook 'magit-create-branch-command-hook 'magit-topgit-create-branch t)
176+
(remove-hook 'magit-pull-command-hook 'magit-topgit-pull t)
177+
(remove-hook 'magit-remote-update-command-hook 'magit-topgit-remote-update t)
178+
(remove-hook 'magit-push-command-hook 'magit-topgit-push t)
179+
(remove-hook 'magit-log-remotes-color-hook
180+
'magit-topgit-get-remote-top-bases-color)
181+
(delete magit-topgit-ignored-namespace magit-refs-namespaces)))
182+
(when (called-interactively-p 'any)
183+
(magit-refresh)))
184+
185+
;;;###autoload
186+
(defun turn-on-magit-topgit ()
187+
"Unconditionally turn on `magit-topgit-mode'."
188+
(magit-topgit-mode 1))
167189

168190
(provide 'magit-topgit)
169191
;;; magit-topgit.el ends here

magit.el

+8
Original file line numberDiff line numberDiff line change
@@ -5346,6 +5346,14 @@ With a prefix arg, do a submodule update --init"
53465346
(t
53475347
(magit-start-process "Gitk" nil magit-gitk-executable "--all")))))
53485348

5349+
(defun magit-load-config-extensions ()
5350+
"Try to load magit extensions that are defined at git config
5351+
layer. This can be added to `magit-mode-hook' for example"
5352+
(dolist (ext (magit-get-all "magit.extension"))
5353+
(let ((sym (intern (format "magit-%s-mode" ext))))
5354+
(when (fboundp sym)
5355+
(funcall sym 1)))))
5356+
53495357
(provide 'magit)
53505358

53515359
;; rest of magit core

0 commit comments

Comments
 (0)