Skip to content

Instantly share code, notes, and snippets.

@karthink
Last active February 16, 2024 08:37
Show Gist options
  • Save karthink/d2419098c9312e3bf2c63b052464ef5f to your computer and use it in GitHub Desktop.
Save karthink/d2419098c9312e3bf2c63b052464ef5f to your computer and use it in GitHub Desktop.
Configuration for an improved reftex experience in Emacs' Org mode
(use-package org-mode
:hook (org-mode . eldoc-mode)
:config
(font-lock-add-keywords
'org-mode
'(("\\(\\(?:\\\\\\(?:label\\|ref\\|eqref\\)\\)\\){\\(.+?\\)}"
(1 font-lock-keyword-face)
(2 font-lock-constant-face)))))
(use-package reftex
:bind (:map org-mode-map
("M-g r" . my/next-reference-or-label)
("M-g R" . my/previous-reference-or-label))
:config
(defvar-keymap my/reftex-jump-map
:repeat t
"r" 'my/next-reference-or-label
"R" 'my/previous-reference-or-label)
(defun my/next-reference-or-label (_arg)
"Jump to next LaTeX reference, label, citation or Org citation."
(interactive "p")
(let* ((prop))
(pcase-let
((`(,_ . ,ov)
(get-char-property-and-overlay (point) 'TeX-fold-type)))
(when ov (TeX-fold-hide-item ov)))
(save-excursion
(and (setq prop (text-property-search-forward
'face nil
(lambda (_ val)
(memq val '(font-lock-constant-face org-cite)))
t))))
(if prop
(progn (goto-char (prop-match-beginning prop))
(when (and (derived-mode-p 'org-mode) (org-invisible-p))
(org-fold-show-context 'link-search))
(when eldoc-mode (eldoc--invoke-strategy t))
(pcase-let
((`(,_ . ,ov)
(get-char-property-and-overlay (point) 'TeX-fold-type)))
(when ov (TeX-fold-show-item ov))))
(message "No more references/labels."))))
(defun my/previous-reference-or-label (_arg)
"Jump to previous LaTeX reference, label, citation or Org citation."
(interactive "p")
(let ((p))
(save-excursion
(and (text-property-search-backward
'face nil
(lambda (_ val)
(memq val '(font-lock-constant-face org-cite
TeX-fold-folded-face)))
t)
(setq p (point))))
(pcase-let
((`(,_ . ,ov)
(get-char-property-and-overlay (point) 'TeX-fold-type)))
(when ov (TeX-fold-hide-item ov)))
(when p
(goto-char p)
(when (and (derived-mode-p 'org-mode) (org-invisible-p))
(org-fold-show-context 'link-search))
(when eldoc-mode (eldoc--invoke-strategy t)))
(pcase-let
((`(,_ . ,ov)
(get-char-property-and-overlay (point) 'TeX-fold-type)))
(when ov (TeX-fold-show-item ov))))))
(use-package reftex-xref
:hook ((org-mode . reftex-xref-activate)
(org-mode . reftex-eldoc-activate)))
;; Make sure AucTeX is installed
(use-package TeX-fold
:ensure auctex
:hook (org-mode . TeX-fold-mode)
:config
(setq TeX-fold-type-list '(macro))
;; Faces
(set-face-attribute 'TeX-fold-folded-face nil :foreground nil :inherit 'shadow)
;; Custom folded display for labels and refs
(defun my/TeX-fold-ref (text)
(let* ((m (string-match "^\\([^:]+:\\)\\(.*\\)" text))
(cat (or (match-string 1 text) ""))
(ref (or (match-string 2 text) text)))
(when (> (length ref) 13)
(setq ref (concat (substring ref 0 6) "..." (substring ref -6))))
(concat "[" (propertize cat 'face 'shadow) ref "]")))
(defun my/TeX-fold-label (&rest texts)
(cl-loop for text in texts
for m = (string-match "^\\([^:]+:\\)\\(.*\\)" text)
for cat = (or (match-string 1 text) "")
for ref = (or (match-string 2 text) text)
collect (concat "[" (propertize cat 'face 'shadow) ref "]") into labels
finally return (mapconcat #'identity labels ",")))
(setq-default TeX-fold-macro-spec-list
'((my/TeX-fold-label ("cite"))
(my/TeX-fold-label ("label"))
(my/TeX-fold-ref ("ref" "pageref" "eqref" "footref")))))
(use-package eldoc
:defer
:config
(setq eldoc-echo-area-use-multiline-p t
max-mini-window-height 0.4))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment