Last updated on November 15, 2020

Emacs Snippets

👋 Hello! Most of these notes are "knowledge in the making", so parts of them could be incomplete 🙈, inaccurate 🙉 or even potentially wrong 🙊.

Selectively remove HTML links when publishing org files

I split my notes between private and public, and quite often my public notes have links to my private ones. I do not want these links to be published, otherwise when they're clicked they'll throw a Not Found error.

To achieve this, I added a org-export-filter-link-functions:

(defun remove-private-links-filter (text backend info)
  "Removes any HTML link pointing to my private directory."
  (if (and
       (eq backend 'html)
       (string-match "file:///.*/Notes/Private/" text))
      (replace-regexp-in-string "<[^>]*>" "" text)
    text))

(add-to-list 'org-export-filter-link-functions 'remove-private-links-filter)

Show custom git log information on the mode line

When I start to work on a new code base I generally would like to know if I'm looking at an "old" file (from the perspective of the repository lifetime), or a "new" file. To achieve this, I first played with vc-git-mode-line-string, but it seems that it's only useful if you want to display whether a file is up-to-date or not.

To do what I wanted, the following functions and hooks should allows me to display whatever information I want from git log output:

(use-package vc-git
  :defines mode-line-git-information
  :config
  (defun vc-git-buffer-last-commit-relative-date (file)
    "Return FILE last commit's relative date (e.g. 2 days ago)."
    (string-trim
     (with-output-to-string
       (with-current-buffer standard-output
         (vc-git-command t nil file "log" "-1" "--pretty=format:%ar")))
     "\"" "\""))

  (defun mode-line-setup-git-information ()
    "Setup local variable MODE-LINE-GIT-INFORMATION for use by the mode-line."
    (let ((file (buffer-file-name (current-buffer))))
      (when (not (eq 'unregistered (vc-git-state file)))
        (make-local-variable 'mode-line-git-information)
        (setq mode-line-git-information
              (format "Last commit ~%s"
                      (vc-git-buffer-last-commit-relative-date (buffer-file-name (current-buffer))))))))
  :hook
  (find-file . mode-line-setup-git-information)
  (after-revert . mode-line-setup-git-information))

(setq-default mode-line-format
          '(
            ;; ...
            mode-line-git-information))

A small disclaimer: Emacs' help explicitly says to avoid using make-local-variable to make a hook variable buffer-local, but I still don't have enough expertise to understand if it's referring to this case or another one, so for now I've left it like this :).