diff --git a/oni-org/oni-org.el b/oni-org/oni-org.el index 489faf0..662b43f 100644 --- a/oni-org/oni-org.el +++ b/oni-org/oni-org.el @@ -4,7 +4,7 @@ ;; Author: Tom Willemse ;; Keywords: local -;; Version: 2021.0724.001742 +;; Version: 2021.0724.010848 ;; Package-Requires: (oni-yasnippet oni-alert oni-hydra org org-contrib org-bullets org-edna diminish all-the-icons olivetti) ;; This program is free software; you can redistribute it and/or modify @@ -49,6 +49,8 @@ (require 'subr-x) (require 'yasnippet) +;;; Constants + (defconst oni-org-root (file-name-directory (or load-file-name @@ -63,20 +65,105 @@ (expand-file-name "icons" oni-org-root) "The directory where ‘oni-org’ stores its icons.") +;;; Fake org-roam +;; I tried using org-roam v2 with Orgro, but it didn’t work. I’ve only been +;; using org-roam to more easily find and insert strings. The file renaming in +;; v1 always seemed to have some issue, so I never really used that. And I +;; didn’t even look any further into any of the functionality. So these +;; functions are my re-implementation of the convenience of org-roam. This way +;; Orgro still works and I can easily build up my knowledge base as well. I call +;; it fake org-roam for now because I’m too tired to think of anything else, +;; it’s not actually enough to be a fake anything. + +(eval-when-compile (require 'cl-macs)) + +(defvar oni-org-knowledge-directory (expand-file-name "~/documents/org")) + +;; Expected (I need to turn these into tests): + +;; - C++ :: c +;; - Crafting Interpreters - 10 - Fucntions - Native Functions :: crafting_interpreters_10_functions_native_functions + +;; This is a helper function to turn the strings into the same kind of slugs +;; that org-roam uses so I stay consistent in my naming. +(defun oni-org--slugify (str) + "Turn STR into a filesystem-safe slug." + (let ((regexp (rx (one-or-more (not alphanumeric))))) + (downcase + (replace-regexp-in-string regexp "_" (string-trim-right str regexp))))) + +;; This mimicks the file name pattern of org-roam with a date and time, followed +;; by a filesystem-safe slug of the actual title. +(defun oni-org--create-name (title) + (interactive "MTitle: ") + (format "%s-%s.org" + (format-time-string "%Y%m%d%H%M%S") + (oni-org--slugify title))) + +;; Collect all of the files under the ‘oni-org-knowledge-directory’. org-roam indexes +;; all of the files in a database, but I really didn’t want to recreate that +;; today. For the moment I don’t have so many files that parsing all of them +;; like this is a huge problem. +(defun oni-org--get-knowledge-files () + (cl-labels ((add-titles (file) + (list (with-temp-buffer + (insert-file-contents (expand-file-name file)) + (goto-char (point-min)) + (let ((line-end-position (line-end-position))) + (when (search-forward ":" line-end-position t) + (buffer-substring-no-properties (1+ (point)) line-end-position)))) + file)) + (unimportant-file-p (file) + (or (string-prefix-p "." (file-name-nondirectory file)) + (string-match-p (rx bos "#" (one-or-more any) "#" eos) (file-name-nondirectory file)))) + (unimportant-directory-p (directory) + (not (string-match-p (rx "/.") directory)))) + (mapcar #'add-titles + (cl-delete-if #'unimportant-file-p + (directory-files-recursively oni-org-knowledge-directory (rx bos (repeat 14 digit) "-" (one-or-more (any alphanumeric "_")) ".org") nil #'unimportant-directory-p))))) + +;; Find and visit a file in the ‘oni-org-knowledge-directory’. If the file doesn’t +;; exist yet, it’s created and the title is inserted into it. +(defun oni-org-find-knowledge-file () + (interactive) + (let* ((completions (oni-org--get-knowledge-files)) + (pick (completing-read "File: " completions)) + (file (car (alist-get pick completions nil nil #'string=)))) + (if file + (find-file file) + (find-file (oni-org--create-name pick)) + (insert "#+TITLE: " pick "\n\n")))) + +;; Insert a link to a file in the ‘oni-org-knowledge-directory’ into the current +;; buffer. Don’t visit the file, just insert a link to it. +(defun oni-org-insert-knowledge-link () + (interactive) + (let* ((completions (oni-org--get-knowledge-files)) + (pick (completing-read "File: " completions)) + (file (car (alist-get pick completions nil nil #'string=)))) + (unless file + (setq file (oni-org--create-name pick)) + (with-current-buffer (find-file-noselect file) + (insert "#+TITLE: " pick "\n\n") + (save-buffer))) + (insert "[[file:" (file-relative-name file oni-org-knowledge-directory) "][" pick "]]"))) + +;;; Functions + (defun oni-org-document-add-inline-images-startup () "Add a line to the current org buffer that will make it load images inline." (interactive) (unless (derived-mode-p 'org-mode) (error "Not currently in an org-mode buffer")) (save-excursion - (goto-char (point-min)) - (let ((header-end (or (search-forward "\n\n" nil t) - (point-max))) - (case-fold-search t)) - (goto-char (point-min)) - (unless (search-forward "#+startup: inlineimages" header-end t) - (goto-char (1- header-end)) - (insert "#+STARTUP: inlineimages\n"))))) + (goto-char (point-min)) + (let ((header-end (or (search-forward "\n\n" nil t) + (point-max))) + (case-fold-search t)) + (goto-char (point-min)) + (unless (search-forward "#+startup: inlineimages" header-end t) + (goto-char (1- header-end)) + (insert "#+STARTUP: inlineimages\n"))))) (defun oni-org-document-remove-inline-images-startup () "Remove a line to the current org buffer that will make it load images inline." @@ -191,9 +278,8 @@ located at the start of the line." _a_: Show Agenda _b_: Switch to org buffer _t_: Note _c_: Capture new heading _s_: Save all org buffers _A_: Appointment _l_: Store link ^^ _j_: Journal entry -^^ ^^ _f_: Add roam note +^^ ^^ _f_: Find note ^^ ^^ _i_: Insert other note -^^ ^^ _I_: Insert and edit note ^^ ^Document^^^ ^^^^^^------------------------------------------------------------------------ _di_: Add inlineimages STARTUP @@ -206,15 +292,8 @@ _di_: Add inlineimages STARTUP ("t" (org-capture nil "t")) ("A" (org-capture nil "a")) ("j" (org-capture nil "j")) - ("f" (if (require 'oni-org-roam nil t) - (call-interactively 'org-roam-find-file) - (error "Couldn’t load org-roam, you should install ‘oni-org-roam’"))) - ("i" (if (require 'oni-org-roam nil t) - (call-interactively 'org-roam-insert-immediate) - (error "Couldn’t load org-roam, you should install ‘oni-org-roam’"))) - ("I" (if (require 'oni-org-roam nil t) - (call-interactively 'org-roam-insert) - (error "Couldn’t load org-roam, you should install ‘oni-org-roam’"))) + ("f" oni-org-find-knowledge-file) + ("i" oni-org-insert-knowledge-link) ("di" oni-org-document-add-inline-images-startup)) (defun oni-org-in-dblock-p ()