2

I’m working on a project which is version controlled using GitLab. GitLab, unlike GitHub, uses two separate URL endpoints for issues and merge requests (AKA Pull Requests):

https://gitlab.example.com/group/project/issues/<issue_number>
https://gitlab.example.com/group/project/merge_requests/<mr_number>

Also, issues are represented as #1 while merge requests are represented as !1.

It is fairly easy to write a regex to match both, but is there a way to tell bug-reference-mode to use different URL formats for them?

4

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

    This variable is safe as a file local variable if its value satisfies the predicate which is a byte-compiled expression.

    Documentation:

    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.

  • bug-reference-bug-regexp

    bug-reference-bug-regexp is a variable defined in bug-reference.el.

    Its value is "\\([Bb]ug ?#?\\|[Pp]atch ?#\\|RFE ?#\\|PR [a-z-+]+/\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)"

    This variable is safe as a file local variable if its value satisfies the predicate stringp.

    Documentation:

    Regular expression matching bug references. The second subexpression should match the bug reference (usually a number).

    You can customize this variable.

    This variable was introduced, or its default value was changed, in version 24.3 of Emacs.

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 1))
              "merge_requests"
            "issues")
          (match-string-no-properties 2)))

(with-current-buffer-window
 (generate-new-buffer-name "tmp") () nil
 (emacs-lisp-mode)
 (setq-local bug-reference-bug-regexp
             (rx (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 two grouping constructs, 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.