doomemacs/modules/lang/org/autoload/contrib-roam2.el
Henrik Lissner ad6a3d0f33
refactor: deprecate featurep! for modulep!
featurep! will be renamed modulep! in the future, so it's been
deprecated. They have identical interfaces, and can be replaced without
issue.

featurep! was never quite the right name for this macro. It implied that
it had some connection to featurep, which it doesn't (only that it was
similar in purpose; still, Doom modules are not features). To undo such
implications and be consistent with its namespace (and since we're
heading into a storm of breaking changes with the v3 release anyway),
now was the best opportunity to begin the transition.
2022-08-14 20:43:35 +02:00

131 lines
5.7 KiB
EmacsLisp

;;; lang/org/autoload/contrib-roam2.el -*- lexical-binding: t; -*-
;;;###if (modulep! +roam2)
;;; Custom node accessors
;;;###autoload (autoload 'org-roam-node-doom-filetitle "lang/org/autoload/contrib-roam2" nil t)
(cl-defmethod org-roam-node-doom-filetitle ((node org-roam-node))
"Return the value of \"#+title:\" (if any) from file that NODE resides in.
If there's no file-level title in the file, return empty string."
(or (if (= (org-roam-node-level node) 0)
(org-roam-node-title node)
(org-roam-node-file-title node))
""))
;;;###autoload (autoload 'org-roam-node-doom-hierarchy "lang/org/autoload/contrib-roam2" nil t)
(cl-defmethod org-roam-node-doom-hierarchy ((node org-roam-node))
"Return hierarchy for NODE, constructed of its file title, OLP and direct title.
If some elements are missing, they will be stripped out."
(let ((title (org-roam-node-title node))
(olp (org-roam-node-olp node))
(level (org-roam-node-level node))
(filetitle (org-roam-node-doom-filetitle node))
(separator (propertize org-eldoc-breadcrumb-separator 'face 'shadow)))
(cl-case level
;; node is a top-level file
(0 filetitle)
;; node is a level 1 heading
(1 (concat (propertize filetitle 'face '(shadow italic))
separator title))
;; node is a heading with an arbitrary outline path
(t (concat (propertize filetitle 'face '(shadow italic))
separator (propertize (string-join olp separator) 'face '(shadow italic))
separator title)))))
;;;###autoload (autoload 'org-roam-node-doom-subdirs "lang/org/autoload/contrib-roam2" nil t)
(cl-defmethod org-roam-node-doom-subdirs ((node org-roam-node))
"Return subdirectories of `org-roam-directory' in which NODE resides in.
If there's none, return an empty string."
(thread-first
node
(org-roam-node-file)
(file-relative-name org-roam-directory)
(file-name-directory)))
;;;###autoload (autoload 'org-roam-node-doom-tags "lang/org/autoload/contrib-roam2" nil t)
(cl-defmethod org-roam-node-doom-tags ((node org-roam-node))
"Return tags formatted in the same way how they appear in org files."
(cl-remove-if (doom-rpartial
#'member (delq
nil (append
(list (bound-and-true-p org-archive-tag)
(bound-and-true-p org-attach-auto-tag))
(bound-and-true-p org-num-skip-tags))))
(org-roam-node-tags node)))
;;;###autoload (autoload 'org-roam-node-doom-type "lang/org/autoload/contrib-roam2" nil t)
(cl-defmethod org-roam-node-doom-type ((node org-roam-node))
"Return the directory relative to `org-roam-directory' as a note's \"type\"."
(when-let (dir (thread-first
node
(org-roam-node-file)
(file-relative-name org-roam-directory)
(file-name-directory)))
(directory-file-name dir)))
;;
;;; Hooks
;;;###autoload
(defun +org-roam-manage-backlinks-buffer-h ()
"Open or close roam backlinks buffer depending on visible org-roam buffers.
Intended to be added to `doom-switch-buffer-hook' in `org-roam-find-file-hook'.
Controlled by `+org-roam-open-buffer-on-find-file'."
(when (and +org-roam-auto-backlinks-buffer
(not org-roam-capture--node) ; not for roam capture buffers
(not org-capture-mode) ; not for capture buffers
(not (bound-and-true-p +popup-buffer-mode)))
(let ((visible-p (eq 'visible (org-roam-buffer--visibility))))
(if (cl-some #'org-roam-buffer-p (doom-visible-buffers))
(unless visible-p
(org-roam-buffer-toggle))
(when visible-p
(org-roam-buffer-toggle))
(unless (doom-buffers-in-mode 'org-mode)
(remove-hook 'doom-switch-buffer-hook #'+org-roam-manage-backlinks-buffer-h))))))
;;
;;; Advice
;;;###autoload
(defun org-roam-link-follow-link-with-description-a (args)
"Use a 'roam:X' link's description if X is empty."
(when (or (string-empty-p (car args))
(null (car args)))
(setcar
args (let ((link (org-element-context)))
(and (org-element-property :contents-begin link)
(org-element-property :contents-end link)
(buffer-substring-no-properties
(org-element-property :contents-begin link)
(org-element-property :contents-end link))))))
args)
;;;###autoload
(defun org-roam-link-replace-at-point-a (&optional link)
"Replace \"roam:\" LINK at point with an \"id:\" link."
(save-excursion
(save-match-data
(let* ((link (or link (org-element-context)))
(type (org-element-property :type link))
(path (org-element-property :path link))
(desc (and (org-element-property :contents-begin link)
(org-element-property :contents-end link)
(buffer-substring-no-properties
(org-element-property :contents-begin link)
(org-element-property :contents-end link))))
node)
(goto-char (org-element-property :begin link))
(when (and (org-in-regexp org-link-any-re 1)
(string-equal type "roam")
;; Added `desc' ref here
(setq node (save-match-data
(org-roam-node-from-title-or-alias
(if (string-empty-p path)
desc
path)))))
(replace-match (org-link-make-string
(concat "id:" (org-roam-node-id node))
(or desc path))))))))