(or emacs irrelevant)

Visiting URLs and issues with counsel-find-file

Many experienced Emacs users are aware of ffap command:

Find FILENAME, guessing a default from text around point. If ffap-url-regexp is not nil, the FILENAME may also be an URL.

It's a great way to open an link, if you plan things in advance. But for me it was usually C-x C-f (annoyed grunt) C-g M-x ffap RET.

Now, thanks to counsel-find-file, it's C-x C-f (anticipated annoyance, followed by a sigh of relief) M-n.

With Ivy completion, M-n calls ivy-next-history-element, which tries to

predict the history element in case you've reached history's edge. The prediction usually simply inserts thing-at-point into the minibuffer. My favorite applications of this are:

  • C-s M-n - swiper thing-at-point, to get the occurrences of the current symbol in the current file.
  • C-c j M-n - counsel-git-grep thing-at-point, to get the mentions within the current project.
  • C-c g M-n - counsel-git thing-at-point to open a file to which the current symbol links.

One thing I've recently added is the \_<...\_> wrapper for when major-mode derives from prog-mode. Since the \_< regex matches the symbol start, and \_> matches the symbol end, there's no chance of getting partial matches. You can call undo or press M-n again in case the symbol bounds aren't useful.

Finally, C-x C-f M-n can be used to open URLs. Recently, I've added functionality to counsel-find-file that allows me to also visit Github issues by simply pointing at the plain issue number, e.g. #123 in either a version-controlled file or in a Magit buffer. The command will query:

$ git remote get-url origin

and fill in all the details. So I no longer bother with bug-reference-url-format and bug-reference-mode - now it's all automatic.

It's also possible to make it work for places other than Github, for instance this code (already included in counsel) makes it work for the Emacs Git repository:

(defun counsel-emacs-url-p ()
  "Return a Debbugs issue URL at point."
  (when (and (looking-at "#[0-9]+")
             (or
              (eq (vc-backend (buffer-file-name)) 'Git)
              (memq major-mode '(magit-commit-mode))))
    (let ((url (match-string-no-properties 0))
          (origin (shell-command-to-string
                   "git remote get-url origin")))
      (when (string-match "git.sv.gnu.org:/srv/git/emacs.git"
                          origin)
        (format "http://debbugs.gnu.org/cgi/bugreport.cgi?bug=%s"
                (substring url 1))))))

(add-to-list 'ivy-ffap-url-functions 'counsel-emacs-url-p)