aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorTassilo Horn2020-06-11 17:02:02 +0200
committerTassilo Horn2020-06-11 23:22:30 +0200
commitea43151b5b625ee39ff5c22b722b1b4169719123 (patch)
treeeb696f1e278f238e944f5b7db15f665b7c24f2ab /lisp
parentd8a6d2e4810a4072cabbf76170dc4bf708f27d10 (diff)
downloademacs-bug-reference-setup.tar.gz
emacs-bug-reference-setup.zip
bug-reference-setupbug-reference-setup
Diffstat (limited to 'lisp')
-rw-r--r--lisp/progmodes/bug-reference.el122
-rw-r--r--lisp/vc/vc.el7
2 files changed, 125 insertions, 4 deletions
diff --git a/lisp/progmodes/bug-reference.el b/lisp/progmodes/bug-reference.el
index 02af263ec34..e8cffd639f0 100644
--- a/lisp/progmodes/bug-reference.el
+++ b/lisp/progmodes/bug-reference.el
@@ -60,6 +60,7 @@ If you set it to a symbol in the file Local Variables section,
60you need to add a `bug-reference-url-format' property to it: 60you need to add a `bug-reference-url-format' property to it:
61\(put \\='my-bug-reference-url-format \\='bug-reference-url-format t) 61\(put \\='my-bug-reference-url-format \\='bug-reference-url-format t)
62so that it is considered safe, see `enable-local-variables'.") 62so that it is considered safe, see `enable-local-variables'.")
63(make-variable-buffer-local 'bug-reference-url-format)
63 64
64;;;###autoload 65;;;###autoload
65(put 'bug-reference-url-format 'safe-local-variable 66(put 'bug-reference-url-format 'safe-local-variable
@@ -75,6 +76,7 @@ The second subexpression should match the bug reference (usually a number)."
75 :type 'regexp 76 :type 'regexp
76 :version "24.3" ; previously defconst 77 :version "24.3" ; previously defconst
77 :group 'bug-reference) 78 :group 'bug-reference)
79(make-variable-buffer-local 'bug-reference-bug-regexp)
78 80
79;;;###autoload 81;;;###autoload
80(put 'bug-reference-bug-regexp 'safe-local-variable 'stringp) 82(put 'bug-reference-bug-regexp 'safe-local-variable 'stringp)
@@ -139,6 +141,122 @@ The second subexpression should match the bug reference (usually a number)."
139 (when url 141 (when url
140 (browse-url url)))))) 142 (browse-url url))))))
141 143
144(defcustom bug-reference-setup-functions nil
145 "A list of function for setting up bug-reference mode.
146A setup function should return non-nil if it set
147`bug-reference-bug-regexp' and `bug-reference-url-format'
148appropiately for the current buffer. The functions are called in
149sequence stopping as soon as one signalled a successful setup.
150
151Also see `bug-reference-default-setup-functions'.
152
153The `bug-reference-setup-functions' take preference over
154`bug-reference-default-setup-functions', i.e., they are
155called before the latter."
156 :type '(list function)
157 :version "28.1"
158 :group 'bug-reference)
159
160(defun bug-reference-try-setup-from-vc ()
161 "Try setting up `bug-reference-bug-regexp' and
162`bug-reference-url-format' from the version control system of the
163current file."
164 (when (buffer-file-name)
165 (let* ((backend (vc-responsible-backend (buffer-file-name) t))
166 (url (pcase backend
167 ('Git (string-trim
168 (shell-command-to-string
169 "git ls-remote --get-url"))))))
170 (cl-flet ((maybe-set (url-rx bug-rx bug-url-fmt)
171 (when (string-match url-rx url)
172 (setq bug-reference-bug-regexp bug-rx)
173 (setq bug-reference-url-format
174 (if (functionp bug-url-fmt)
175 (funcall bug-url-fmt)
176 bug-url-fmt)))))
177 (when (and url
178 ;; If there's a space in the url, it's propably an
179 ;; error message.
180 (not (string-match-p "[[:space:]]" url)))
181 (or
182 ;; GNU projects on savannah. FIXME: Only a fraction of
183 ;; them uses debbugs.
184 (maybe-set "git\\.\\(sv\\|savannah\\)\\.gnu\\.org:"
185 "\\([Bb]ug ?#?\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)"
186 "https://debbugs.gnu.org/%s")
187 ;; GitHub projects. Here #17 may refer to either an issue
188 ;; or a pull request but visiting the issue/17 web page
189 ;; will automatically redirect to the pull/17 page if 17 is
190 ;; a PR. TODO: Support user/project#17 references linking
191 ;; to possibly different than the current project.
192 (maybe-set "[/@]github.com[/:]\\([.A-Za-z0-9_/-]+\\)\\.git"
193 "\\(#\\)\\([0-9]+\\)"
194 (lambda ()
195 (concat "https://github.com/"
196 (match-string 1 url)
197 "/issues/%s")))
198 ;; GitLab projects.
199 (maybe-set "[/@]gitlab.com[/:]\\([.A-Za-z0-9_/-]+\\)\\.git"
200 "\\(#\\|!\\)\\([0-9]+\\)"
201 (lambda ()
202 (let ((user-project (match-string 1 url)))
203 (lambda ()
204 (concat "https://gitlab.com/"
205 user-project
206 "/-/"
207 (if (string= (match-string 1) "#")
208 "issues/"
209 "merge_requests/")
210 (match-string 2))))))))))))
211
212(defun bug-reference-try-setup-from-gnus ()
213 (when (and (memq major-mode '(gnus-summary-mode gnus-article-mode))
214 (boundp 'gnus-newsgroup-name)
215 gnus-newsgroup-name)
216 (let ((debbugs-regexp
217 ;; TODO: Obviously there are more, so add them.
218 (regexp-opt '("emacs" "auctex" "reftex"
219 "-devel@gnu.org" "ding@gnus.org"))))
220 (when (or (string-match-p debbugs-regexp gnus-newsgroup-name)
221 (and
222 gnus-article-buffer
223 (with-current-buffer gnus-article-buffer
224 (let ((headers (mail-header-extract)))
225 (when headers
226 (or (string-match-p
227 debbugs-regexp
228 (or (mail-header 'from headers) ""))
229 (string-match-p
230 debbugs-regexp
231 (or (mail-header 'to headers) ""))
232 (string-match-p
233 debbugs-regexp
234 (or (mail-header 'cc headers) ""))))))))
235 (setq bug-reference-bug-regexp
236 "\\([Bb]ug ?#?\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)")
237 (setq bug-reference-url-format
238 "https://debbugs.gnu.org/%s")))))
239
240;;;###autoload
241(defvar bug-reference-default-setup-functions
242 (list #'bug-reference-try-setup-from-vc
243 #'bug-reference-try-setup-from-gnus)
244 "Like `bug-reference-setup-functions' for packages to hook in.")
245
246(defun bug-reference--init ()
247 "Initialize `bug-reference-mode'."
248 (progn
249 (or
250 (with-demoted-errors
251 "Error while running bug-reference-setup-functions: %S"
252 (run-hook-with-args-until-success
253 'bug-reference-setup-functions))
254 (with-demoted-errors
255 "Error while running bug-reference-default-setup-functions: %S"
256 (run-hook-with-args-until-success
257 'bug-reference-default-setup-functions)))
258 (jit-lock-register #'bug-reference-fontify)))
259
142;;;###autoload 260;;;###autoload
143(define-minor-mode bug-reference-mode 261(define-minor-mode bug-reference-mode
144 "Toggle hyperlinking bug references in the buffer (Bug Reference mode)." 262 "Toggle hyperlinking bug references in the buffer (Bug Reference mode)."
@@ -146,7 +264,7 @@ The second subexpression should match the bug reference (usually a number)."
146 "" 264 ""
147 nil 265 nil
148 (if bug-reference-mode 266 (if bug-reference-mode
149 (jit-lock-register #'bug-reference-fontify) 267 (bug-reference--init)
150 (jit-lock-unregister #'bug-reference-fontify) 268 (jit-lock-unregister #'bug-reference-fontify)
151 (save-restriction 269 (save-restriction
152 (widen) 270 (widen)
@@ -159,7 +277,7 @@ The second subexpression should match the bug reference (usually a number)."
159 "" 277 ""
160 nil 278 nil
161 (if bug-reference-prog-mode 279 (if bug-reference-prog-mode
162 (jit-lock-register #'bug-reference-fontify) 280 (bug-reference--init)
163 (jit-lock-unregister #'bug-reference-fontify) 281 (jit-lock-unregister #'bug-reference-fontify)
164 (save-restriction 282 (save-restriction
165 (widen) 283 (widen)
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index c640ba0420e..af7339f34b3 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -957,7 +957,7 @@ use."
957 (throw 'found bk)))) 957 (throw 'found bk))))
958 958
959;;;###autoload 959;;;###autoload
960(defun vc-responsible-backend (file) 960(defun vc-responsible-backend (file &optional no-error)
961 "Return the name of a backend system that is responsible for FILE. 961 "Return the name of a backend system that is responsible for FILE.
962 962
963If FILE is already registered, return the 963If FILE is already registered, return the
@@ -967,7 +967,10 @@ responsible for FILE is returned.
967 967
968Note that if FILE is a symbolic link, it will not be resolved -- 968Note that if FILE is a symbolic link, it will not be resolved --
969the responsible backend system for the symbolic link itself will 969the responsible backend system for the symbolic link itself will
970be reported." 970be reported.
971
972If NO-ERROR is nil, signal an error that no VC backend is
973responsible for the given file."
971 (or (and (not (file-directory-p file)) (vc-backend file)) 974 (or (and (not (file-directory-p file)) (vc-backend file))
972 (catch 'found 975 (catch 'found
973 ;; First try: find a responsible backend. If this is for registration, 976 ;; First try: find a responsible backend. If this is for registration,