zk / Backlink Buffer

A sidebar for showing all files linking to the one currently opened.

Collection of Backlinks

(require 'org-zk-core)

(defun org-zk-backlinks-for-file (file)
  "Files linking to FILE."
  (let ((links)
        (file (expand-file-name file)))
    (org-el-cache-each
     org-zk-cache
     (lambda (key value)
       (dolist (link (plist-get value :links))
         (if (string= file (plist-get link :full-path))
             (push (cons key link) links)))))
    links))

(defun org-zk-backlinks-for-buffer ()
  "Files linking to the current buffer"
  (org-zk-backlinks-for-file (buffer-file-name)))

Buffer Setup / Update

(defcustom org-zk-backlink-buffer-position 'right
  "Position of the backlink buffer")

(defun org-zk-backlink-buffer () (get-buffer-create "*org-zk Backlinks*"))

(defun org-zk-backlink-setup-buffer ()
  (display-buffer-in-side-window
   (org-zk-backlink-buffer)
   `((side . ,org-zk-backlink-buffer-position))))

Display

(defun org-zk-backlink-update-buffer ()
  (interactive)
  (let ((backlinks (org-zk-backlinks-for-buffer))
        (title (or
                (plist-get (org-el-cache-get
                            org-zk-cache
                            (buffer-file-name))
                           :title)
                (buffer-file-name))))
    (with-current-buffer (org-zk-backlink-buffer)
      (read-only-mode -1)
      (erase-buffer)
      (org-mode)
      (visual-line-mode)
      (insert (format "#+TITLE: Backlinks for %s\n\n" title))
      (dolist (backlink backlinks)
        (let ((source (car backlink)))
          (when-let ((entry (org-el-cache-get org-zk-cache source)))
            (insert
             (format
              "* [[file:%s][%s]] \n"
              (car backlink)
              (or (plist-get entry :title) (car backlink))))
            (insert (plist-get (cdr backlink) :context) "\n")
            (insert "\n")
            )))
      (goto-char (point-min))
      (let ((inhibit-message t))
        (org-global-cycle))
      (read-only-mode))))

TODO Group Source Files

Commands

Quitting the Sidebar

(defun org-zk-sidebar-quit ()
  "Close the sidebar."
  (interactive)
  (kill-current-buffer))

NEXT Only kill sidebar buffer

Mode

(defvar org-zk-sidebar-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "q") '("quit" . org-zk-sidebar-quit))
    map)
  "Keymap for `org-zk-sidebar-mode'.")

(define-minor-mode org-zk-sidebar-mode
  "Minor mode for flipping flashcards.

\\{org-zk-sidebar-mode-map}"
  :init-value nil
  :lighter " fc-flip"
  :keymap org-zk-sidebar-mode-map
  :group 'org-fc
  (when org-zk-sidebar-mode
    ;; Make sure only one of the modes is active at a time
    (org-zk-sidebar-rate-mode -1)
    ;; Make sure we're in org mode and there is an active review session
    (unless (and (eq major-mode 'org-mode) org-zk-sidebar--current-session)
      (org-zk-sidebar-mode -1))))

Mode

Idea

Combine with hydra functionality.

Commands / Hooks

(defun org-zk-backlinks ()
  (interactive)
  (when (org-el-cache-member-p org-zk-cache (buffer-file-name))
    (org-zk-backlink-setup-buffer)
    (org-zk-backlink-update-buffer)))

(defun org-zk-backlink-hook (&rest _args)
  (interactive)
  (when (eq major-mode 'org-mode)
    (if-let ((filename (buffer-file-name)))
        (if (org-el-cache-member-p org-zk-cache filename)
            (org-zk-backlink-update-buffer)))))

(advice-add #'select-window :after #'org-zk-backlink-hook)

Footer

(provide 'org-zk-backlinks)

If you have an idea how this page could be improved or a comment send me a mail.