Update
Starting with Emacs 28, bug-reference
is able to automatically detect and configure itself for Git forges including GitHub and GitLab. Quoth (info "(emacs) Bug Reference")
:
[...]
For its working, bug reference mode needs to know the syntax of bug
references (‘bug-reference-bug-regexp’), and the URL of the tracker
where bug reports can be looked up (‘bug-reference-url-format’). Since
those are typically different from project to project, it makes sense to
specify them in Directory Variables or File Variables.
For example, let’s assume in our project, we usually write references
to bug reports as bug#1234, or Bug-1234 and that this bug’s page on the
issue tracker is <https://project.org/issues/1234>, then these local
variables section would do.
;; Local Variables:
;; bug-reference-bug-regexp: "\\([Bb]ug[#-]\\([0-9]+\\)\\)"
;; bug-reference-url-format: "https://project.org/issues/%s"
;; End:
The string captured by the first regexp group defines the bounds of
the overlay bug-reference creates, i.e., the part which is highlighted
and made clickable.
The string captured by the second regexp group in
‘bug-reference-bug-regexp’ is used to replace the ‘%s’ template in the
‘bug-reference-url-format’.
Note that ‘bug-reference-url-format’ may also be a function in order
to cater for more complex scenarios, e.g., when different parts of the
bug reference have to be used to distinguish between issues and merge
requests resulting in different URLs.
Automatic Setup
===============
If ‘bug-reference-mode’ is activated, ‘bug-reference-mode-hook’ has been
run and still ‘bug-reference-bug-regexp’, and ‘bug-reference-url-format’
aren’t both set, it’ll try to setup suitable values for these two
variables itself by calling the functions in
‘bug-reference-auto-setup-functions’ one after the other until one is
able to set the variables.
Right now, there are three types of setup functions.
1. Setup for version-controlled files configurable by the variables
‘bug-reference-forge-alist’, and
‘bug-reference-setup-from-vc-alist’. The defaults are able to
setup GNU projects where <https://debbugs.gnu.org> is used as issue
tracker and issues are usually referenced as ‘bug#13’ (but many
different notations are considered, too), and several kinds of
modern software forges such as GitLab, Gitea, SourceHut, or GitHub.
If you deploy a self-hosted instance of such a forge, the easiest
way to tell bug-reference about it is through
‘bug-reference-forge-alist’.
[...]
Adding support for third-party packages
=======================================
Adding support for bug-reference’ auto-setup is usually quite
straight-forward: write a setup function of zero arguments which gathers
the required information (e.g., List-Id/To/From/Cc mail header values in
the case of a MUA), and then calls one of the following helper
functions:
• ‘bug-reference-maybe-setup-from-vc’ which does the setup according
to ‘bug-reference-setup-from-vc-alist’,
• ‘bug-reference-maybe-setup-from-mail’ which does the setup
according to ‘bug-reference-setup-from-mail-alist’,
• and ‘bug-reference-maybe-setup-from-irc’ which does the setup
according to ‘bug-reference-setup-from-irc-alist’.
A setup function should return non-nil if it could setup
bug-reference mode which is the case if the last thing the function does
is calling one of the helper functions above.
Finally, the setup function has to be added to
‘bug-reference-auto-setup-functions’.
Note that these auto-setup functions should check as a first step if
they are applicable, e.g., by checking the ‘major-mode’ value.
As Mike Crowe correctly pointed out in the comments, bug-reference
also changed how it interprets (and warns about) regexp grouping constructs in Emacs 28. I have tried to update the rest of the original answer below accordingly.
Summary
is there a way to tell bug-reference-mode
to use different URL formats for them?
If you are using Emacs 24+, there most certainly is.
The key to making bug-reference-mode
more flexible lies in:
customising bug-reference-bug-regexp
to match all your preferred bug reference formats (which should be differentiable); and
setting bug-reference-url-format
to the nullary function to actually differentiate between them by analysing the match data pertaining to the custom bug-reference-bug-regexp
.
After that, you need to find a way for these customisations to apply only to the files in question, e.g. via file or directory variables, or even, say, a custom minor mode.
Documentation
Before I list a sample configuration, see the docstrings of the aforementioned bug-reference
variables:
bug-reference-url-format
bug-reference-url-format is a variable defined in ‘bug-reference.el’.
Its value is nil
Format used to turn a bug number into a URL.
The bug number is supplied as a string, so this should have a single %s.
This can also be a function designator; it is called without arguments
and should return a string.
It can use ‘match-string’ to get parts matched against
‘bug-reference-bug-regexp’, specifically:
1. issue kind (bug, patch, rfe &c)
2. issue number.
There is no default setting for this, it must be set per file.
If you set it to a symbol in the file Local Variables section,
you need to add a ‘bug-reference-url-format’ property to it:
(put 'my-bug-reference-url-format 'bug-reference-url-format t)
so that it is considered safe, see ‘enable-local-variables’.
This variable is safe as a file local variable if its value
satisfies the predicate which is a byte-compiled expression.
Probably introduced at or before Emacs version 28.1.
bug-reference-bug-regexp
bug-reference-bug-regexp is a variable defined in ‘bug-reference.el’.
Its value is
"\\(\\b\\(?:[Bb]ug ?#?\\|[Pp]atch ?#\\|RFE ?#\\|PR [a-z+-]+/\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)\\)"
Regular expression matching bug references.
The first subexpression defines the region of the bug-reference
overlay, i.e., the region being fontified and made clickable in
order to browse the referenced bug in the corresponding project’s
issue tracker.
If ‘bug-reference-url-format’ is set to a format string with
single %s placeholder, the second subexpression must match
the (part of the) bug reference which needs to be injected in
place of the %s in order to form the bug’s ticket URL.
If ‘bug-reference-url-format’ is a function, the interpretation
of the subexpressions larger than 1 is up to the function.
However, it is checked that the bounds of all matching
subexpressions from 2 to 10 are within the bounds of the
subexpression 1 defining the overlay region. Larger
subexpressions may also be used by the function but may lay
outside the bounds of subexpressions 1 and then don’t contribute
to the highlighted and clickable region.
This variable is safe as a file local variable if its value
satisfies the predicate ‘stringp’.
This variable was introduced, or its default value was changed, in
version 28.1 of Emacs.
You can customize this variable.
Example
Assuming issue references are formatted as some variation of Issue #N
or issue#N
, and merge requests as some variation of MR !N
or MR!N
, the following code will create a new sample buffer with an Elisp comment showcasing the two types of bug-reference
button.
(defun my-gitlab-url ()
"Return a GitLab merge request or issue URL.
Intended as a value for `bug-reference-url-format'."
(format "https://gitlab.example.com/group/project/%s/%s"
(if (string-suffix-p "!" (match-string-no-properties 2))
"merge_requests"
"issues")
(match-string-no-properties 3)))
(with-current-buffer-window
(generate-new-buffer-name "tmp") () nil
(emacs-lisp-mode)
(setq-local bug-reference-bug-regexp
(rx (group (group (| (: (in ?I ?i) "ssue" (? ?\s) ?#)
(: "MR" (? ?\s) ?!)))
(group (+ digit)))))
(setq-local bug-reference-url-format #'my-gitlab-url)
(insert ";; MR!101 solves issue #100\n")
(bug-reference-prog-mode))
Note:
bug-reference-bug-regexp
must contain three grouping constructs, one for complete button text, one for the bug type, and one for the bug number.
In my example, I differentiate between issues and merge requests by checking whether the bug type (i.e. the first match group) ends in a trailing exclamation mark. You can adapt this to some other check, such as whether the bug type matches the pattern issue
or similar.
In the sample buffer, I enable bug-reference-prog-mode
instead of bug-reference-mode
. The former is a restricted version of the latter, where the former only creates buttons in comments and strings.