303 lines
16 KiB
EmacsLisp
303 lines
16 KiB
EmacsLisp
;; -*- mode: emacs-lisp; buffer-read-only: t; -*-
|
|
(require 'org-roam)
|
|
|
|
(setq org-roam-directory "/mnt/Data/Documents/org-files/org-roam")
|
|
|
|
;; be paranoid, only open org files in read-only mode.
|
|
;;
|
|
;;(defun myorg-open-read-only-mode ()
|
|
;; "Enable `read-only-mode' for Org mode files."
|
|
;; (when (and buffer-file-name
|
|
;; (string-match "\\.org\\'" buffer-file-name))
|
|
;; (read-only-mode 1)))
|
|
|
|
;;(add-hook 'org-mode-hook 'myorg-open-read-only-mode)
|
|
|
|
|
|
;;;; add inactive timestamp to every org-item
|
|
;; https://stackoverflow.com/a/52815573/5115219
|
|
;; https://emacs.stackexchange.com/a/45369/29404
|
|
(defun insert-created-date (&rest ignore)
|
|
"Insert inacative timestamp property,
|
|
but only in org-items, not in org-item-checkboxes."
|
|
(interactive)
|
|
(if (not (org-at-item-checkbox-p))
|
|
(progn
|
|
(insert (format-time-string
|
|
(concat "\n"
|
|
":properties:\n"
|
|
":created: "
|
|
"[%Y-%m-%d %a %H:%M]\n"
|
|
":end:"
|
|
)))
|
|
;; in org-capture, this folds the entry; when inserting a heading, this moves point back to the heading line
|
|
(org-back-to-heading)
|
|
;; when inserting a heading, this moves point to the end of the line
|
|
(move-end-of-line ()))))
|
|
;;;; add inactive timestamp to entries in org-mode
|
|
(advice-add 'org-insert-heading :after #'insert-created-date)
|
|
|
|
;; ----------------------------------------------------------------------
|
|
;;; org-roam
|
|
;; ----------------------------------------------------------------------
|
|
;;;; Filter nodes
|
|
;; https://www.reddit.com/r/emacs/comments/vb989o/orgroam_show_only_file_nodes_when_inserting_a_node/ic8bc7l/?context=3
|
|
|
|
;;;;; Define regexp for filtering daily journal files like `2022-05-22'
|
|
(setq my-date-regexp "^[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} [A-Za-z]+")
|
|
|
|
;;;;; Define filter functions to be used in `org-roam-node-find' function.
|
|
(defun ugt-filter-org-roam-node-file-p (node)
|
|
"Filter nodes that represent files.
|
|
So exclude nodes that are outline items in org files.
|
|
|
|
Usage example:
|
|
(org-roam-node-read nil #'ugt-filter-org-roam-node-file-p)
|
|
"
|
|
(and
|
|
(= (org-roam-node-level node) 0)
|
|
(not (string-match my-date-regexp (org-roam-node-title node)))))
|
|
|
|
(defun ugt-filter-org-roam-node-exclude-dates (node)
|
|
"Exclude journal files like `2022-05-17' from nodes list."
|
|
(not (string-match my-date-regexp (org-roam-node-title node))))
|
|
|
|
(defun ugt-filter-org-roam-node-exclude-archived-and-journal-files (node)
|
|
"Exclude these files / nodes
|
|
- tagged `archive'
|
|
- in folder `archive'
|
|
- journal files."
|
|
(and
|
|
;; no journal files
|
|
(not (string-match my-date-regexp (org-roam-node-title node)))
|
|
;; not tagged `archive'
|
|
(not (member "archive" (org-roam-node-tags node)))
|
|
;; not in any folder named `archive'
|
|
(not (string-match-p "archive/" (org-roam-node-file node)))))
|
|
|
|
;;;;; Define custom `org-roam-node-find' functions with filters.
|
|
(defun ugt-org-roam-node-find nil
|
|
"Refined search for org-roam nodes.
|
|
Exclude elements tagged `archive'."
|
|
(interactive)
|
|
;; nb: can add initial search string like "^"
|
|
(org-roam-node-find :other-window nil #'ugt-filter-org-roam-node-exclude-archived-and-journal-files))
|
|
|
|
(defun ugt-org-roam-node-find-document-nodes nil
|
|
"Refined search for org-roam nodes.
|
|
Search for only document level nodes. Exclude dates."
|
|
(interactive)
|
|
;;(org-roam-node-find :other-window)
|
|
(org-roam-node-find :other-window nil #'ugt-filter-org-roam-node-file-p))
|
|
|
|
;;;; Custom `org-roam-dailies-goto-today' function
|
|
(defun ugt-org-roam-dailies-goto-today nil
|
|
"Open todays journal in other window."
|
|
(interactive)
|
|
(split-window-right)
|
|
(other-window 1)
|
|
(org-roam-dailies-goto-today))
|
|
|
|
(setq org-roam-node-display-template
|
|
(concat "${title:70}"(propertize "${tags:30}" 'face 'org-tag) "${file:48}"))
|
|
(setq org-roam-capture-templates '(
|
|
("d" "default (personal notes)"
|
|
plain "%?"
|
|
;; could use
|
|
;; (file (concat org-directory "/org-roam/personal/templates/personal.org"))
|
|
:if-new (file+head "personal/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+startup: showall\n\n")
|
|
:immediate-finish t
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
("q" "FreeBSD"
|
|
plain "%?"
|
|
:if-new (file+head "personal/freebsd/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: FreeBSD\n#+startup: showall\n\n")
|
|
:immediate-finish t
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
("l" "Japanese"
|
|
plain "%?"
|
|
:if-new (file+head "personal/japanese/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: Japanese\n#+startup: showall\n\n")
|
|
:immediate-finish t
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
|
|
|
|
("z" "Blog Post"
|
|
plain "%?"
|
|
:if-new (file+head "~/omnia/weblog/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: blog_post\n#+startup: showall\n
|
|
#+AUTHOR: Alexandro Longo \n
|
|
#+HTML_HEAD_EXTRA: <style>*{font-size: medium;}</style> \n
|
|
#+OPTIONS: toc:nil \n
|
|
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="fix/morris.css">\n
|
|
\n")
|
|
:immediate-finish t
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
("c" "Math Ideas"
|
|
plain "%?"
|
|
:if-new (file+head "personal/math-ideas/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: mathematical_ideas\n#+startup: showall\n\n")
|
|
:immediate-finish t
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
("t" "Proofs"
|
|
plain "%?"
|
|
:if-new (file+head "personal/math-ideas/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: mathematical_proofs\n#+startup: showall\n\n")
|
|
:immediate-finish t
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
("x" "Real Analysis"
|
|
plain "%?"
|
|
:if-new (file+head "personal/math-ideas/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: real_analysis\n#+startup: showall\n\n")
|
|
:immediate-finish t
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
("m" "mechanics"
|
|
plain "%?"
|
|
:if-new (file+head "personal/mechanics/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: mechanics\n#+startup: showall\n\n")
|
|
:immediate-finish t
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
("s" "stoicism"
|
|
plain "%?"
|
|
:if-new (file+head "personal/stoicism/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: stoicism\n#+startup: showall\n\n")
|
|
:immediate-finish t
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
("n" "My Readings"
|
|
plain "%?"
|
|
:if-new (file+head "my-readings/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: My_readings \n#+startup: content\n")
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
("g" "Guix"
|
|
plain "%?"
|
|
:if-new (file+head "guix/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: Guix \n#+startup: content\n")
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
|
|
("e" "Emacs related notes"
|
|
plain "%?"
|
|
:if-new (file+head "emacs/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+filetags: emacs\n#+startup: content\n")
|
|
:empty-lines 1
|
|
:unnarrowed t)
|
|
|
|
("w" "work notes"
|
|
plain "%?"
|
|
:if-new (file+head "work/${slug}.org"
|
|
"#+title: ${title}\n#+date: %<%Y-%m-%d %a %R>\n#+updated: \n %R>\n#+filetags: work_notes\n\n")
|
|
:immediate-finish t
|
|
:empty-lines 1
|
|
:unnarrowed t))
|
|
time-stamp-start "#\\+updated: [\t]*")
|
|
(setq org-roam-dailies-capture-templates '(("d" "default" entry
|
|
"\n* %<%H:%M> %?\n:properties:\n:created: %U\n:end:\n"
|
|
:target (file+head "%<%Y-%m-%d>.org"
|
|
"#+title: %<%Y-%m-%d %a>\n#+startup: showall\n")
|
|
;;:unnarrowed t
|
|
;;:jump-to-captured t
|
|
:empty-lines 1
|
|
)))
|
|
;; Change file-name (slug) creation
|
|
;; Replace whitespace with dashes instead of underscores.
|
|
;; See
|
|
;; - https://github.com/org-roam/org-roam/issues/686
|
|
;; - https://github.com/org-roam/org-roam/pull/1544[[id:2022-06-12T213159.588064][test mest hest]]
|
|
(cl-defmethod org-roam-node-slug ((node org-roam-node))
|
|
"Return the slug of NODE."
|
|
(let ((title (org-roam-node-title node))
|
|
(slug-trim-chars '(;; Combining Diacritical Marks https://www.unicode.org/charts/PDF/U0300.pdf
|
|
768 ; U+0300 COMBINING GRAVE ACCENT
|
|
769 ; U+0301 COMBINING ACUTE ACCENT
|
|
770 ; U+0302 COMBINING CIRCUMFLEX ACCENT
|
|
771 ; U+0303 COMBINING TILDE
|
|
772 ; U+0304 COMBINING MACRON
|
|
774 ; U+0306 COMBINING BREVE
|
|
775 ; U+0307 COMBINING DOT ABOVE
|
|
776 ; U+0308 COMBINING DIAERESIS
|
|
777 ; U+0309 COMBINING HOOK ABOVE
|
|
778 ; U+030A COMBINING RING ABOVE
|
|
779 ; U+030B COMBINING DOUBLE ACUTE ACCENT
|
|
780 ; U+030C COMBINING CARON
|
|
795 ; U+031B COMBINING HORN
|
|
803 ; U+0323 COMBINING DOT BELOW
|
|
804 ; U+0324 COMBINING DIAERESIS BELOW
|
|
805 ; U+0325 COMBINING RING BELOW
|
|
807 ; U+0327 COMBINING CEDILLA
|
|
813 ; U+032D COMBINING CIRCUMFLEX ACCENT BELOW
|
|
814 ; U+032E COMBINING BREVE BELOW
|
|
816 ; U+0330 COMBINING TILDE BELOW
|
|
817 ; U+0331 COMBINING MACRON BELOW
|
|
)))
|
|
(cl-flet* ((nonspacing-mark-p (char) (memq char slug-trim-chars))
|
|
(strip-nonspacing-marks (s) (string-glyph-compose
|
|
(apply #'string
|
|
(seq-remove #'nonspacing-mark-p
|
|
(string-glyph-decompose s)))))
|
|
(cl-replace (title pair) (replace-regexp-in-string (car pair) (cdr pair) title)))
|
|
(let* ((pairs `(("[^[:alnum:][:digit:]]" . "-") ;; convert anything not alphanumeric
|
|
("--*" . "-") ;; remove sequential underscores
|
|
("^-" . "") ;; remove starting underscore
|
|
("-$" . ""))) ;; remove ending underscore
|
|
(slug (-reduce-from #'cl-replace (strip-nonspacing-marks title) pairs)))
|
|
(downcase slug)))))
|
|
;; https://org-roam.discourse.group/t/v2-set-id-to-a-timestamp/1492/2
|
|
;; (setq org-roam-capture-templates
|
|
;; '(("p" "personal" plain
|
|
;; (function org-roam--capture-get-point) "%?"
|
|
;; :file-name "personal/%<%Y-%m-%dT%H%M%S>"
|
|
;; :head "---\ntitle: ${title}\nid: %<%Y-%m-%dT%H%M%S.%6N">\nmodified: <>\n---\n"
|
|
;; :unnarrowed t)))
|
|
(org-roam-db-autosync-mode)
|
|
;; If using org-roam-protocol
|
|
(require 'org-roam-protocol)
|
|
|
|
;;;; Go to item text after capture
|
|
(defun ugt-org-capture-after-finalize-hook nil
|
|
(org-capture-goto-last-stored)
|
|
(end-of-buffer)
|
|
(recenter-top-bottom '(4)) ;; center of window
|
|
)
|
|
(add-hook 'org-capture-after-finalize-hook #'ugt-org-capture-after-finalize-hook)
|
|
|
|
;;;; Hide drawers after creation
|
|
(defun my-org-capture-hook ()
|
|
(when (plist-member org-capture-plist :org-roam)
|
|
(org-cycle-hide-drawers 'overview)))
|
|
(add-hook 'org-capture-mode-hook #'my-org-capture-hook)
|
|
|
|
;;;; Hide drawers in all cases in org-roam.
|
|
(defun my-org-roam-hook () (org-cycle-hide-drawers 'overview))
|
|
(add-hook 'org-roam-mode-hook #'my-org-roam-hook)
|
|
|
|
;;;; Jump to the end of buffer when today's journal is opened
|
|
(defun ugt-org-roam-dailies-find-file-hook nil (end-of-buffer))
|
|
(add-hook 'org-roam-dailies-find-file-hook #'ugt-org-roam-dailies-find-file-hook)
|
|
|
|
;;;; add inactive timestamp to journal entries in org-roam
|
|
(add-hook 'org-roam-dailies-capture-today #'insert-created-date)
|
|
|
|
|