diff --git a/oni-org/oni-org.el b/oni-org/oni-org.el index 51b862f..a3431b0 100644 --- a/oni-org/oni-org.el +++ b/oni-org/oni-org.el @@ -4,8 +4,8 @@ ;; Author: Tom Willemse ;; Keywords: local -;; Version: 2024.0509.130831 -;; Package-Requires: (oni-yasnippet oni-alert oni-hydra org org-bullets org-edna diminish all-the-icons olivetti form-feed org-pretty-table ob-async org-ql org-super-agenda) +;; Version: 2024.0701.144646 +;; Package-Requires: (oni-yasnippet oni-hydra org org-edna diminish olivetti org-pretty-table) ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -39,7 +39,6 @@ (require 'diminish) (require 'hydra) (require 'ob) -(require 'ob-async) (require 'org) (require 'org-clock) (require 'org-edna) @@ -47,9 +46,7 @@ (require 'org-faces) (require 'org-habit) (require 'org-protocol) -(require 'org-ql) (require 'org-roam) -(require 'org-super-agenda) (require 'range) (require 'subr-x) (require 'yasnippet) @@ -90,90 +87,6 @@ (expand-file-name "tickler.org" oni-org-todo-dir) "The tickler file for TODO notes of the future.") -;;; Fake org-roam -- oni-org-exocortex -;; 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-exocortex-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-exocortex-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-exocortex-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-exocortex-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-exocortex-directory’. If the file doesn’t -;; exist yet, it’s created and the title is inserted into it. -(defun oni-org-find-exocortex-file () - (interactive) - (let* ((default-directory oni-org-exocortex-directory) - (completions (oni-org--get-exocortex-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-exocortex-directory’ into the current -;; buffer. Don’t visit the file, just insert a link to it. -(defun oni-org-insert-exocortex-link () - (interactive) - (let* ((completions (oni-org--get-exocortex-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-exocortex-directory) "][" pick "]]"))) - ;;; Functions (defun oni-org-document-add-inline-images-startup () @@ -235,15 +148,6 @@ located at the start of the line." (setq-local yas-buffer-local-condition '(looking-back (rx line-start (one-or-more (not space)))))) -(defun oni-org-setup-prettify-symbols-mode () - "Set up prettify symbols mode for org mode." - (setq-local prettify-symbols-alist - '(("[ ]" . ?) - ("[X]" . ?) - ("#+TITLE: " . "") - ("#+title: " . ""))) - (prettify-symbols-mode)) - (defun oni-org-snippets-initialize () "Initialize the snippets for ‘oni-org’." (when (boundp 'yas-snippet-dirs) @@ -352,44 +256,6 @@ _di_: Add inlineimages STARTUP "^[ \t]*#\\+end" lim-up lim-down)))) -(defun oni-org-at-origin-property-p () - "Non-nil when point is in an origin property." - (save-match-data - (save-excursion - (goto-char (line-beginning-position)) - (and (looking-at org-property-re) - (string= (match-string 2) "ORIGIN"))))) - -(defun oni-org-dblock-write-backlinks (_params) - "Generate backlinks to org headings." - (let ((current-heading (nth 4 (org-heading-components))) - (current-heading-id - (or (alist-get "CUSTOM_ID" (org-entry-properties) nil nil #'string=) - (org-id-get))) - backlinks) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward (rx-to-string `(and "*" ,current-heading "]")) nil t) - (unless (or (oni-org-in-dblock-p) - (oni-org-at-origin-property-p)) - (let ((components (org-heading-components))) - (push (cons (nth 2 components) (nth 4 components)) backlinks))))) - (when (not (null current-heading-id)) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward (rx-to-string `(or (seq "[[id:" ,current-heading-id "]") - (seq "#" ,current-heading-id "]"))) nil t) - (unless (or (oni-org-in-dblock-p) - (oni-org-at-origin-property-p)) - (let ((components (org-heading-components))) - (push (cons (nth 2 components) (nth 4 components)) backlinks)))))) - (insert (string-join - (mapcar (lambda (link) - (concat "- [[*" (cdr link) "][" (if (car link) (format "%s - " (car link)) "") (cdr link) "]]")) - (sort (seq-uniq backlinks (lambda (a b) (string= (cdr a) (cdr b)))) - (lambda (a b) (string< (cdr a) (cdr b))))) - "\n")))) - (defun oni-org-wrap-region-in-block (block-name beginning end) "Create a block BLOCK-NAME and wrap the text between BEGINNING and END in there." (interactive "sName: \nr") @@ -403,8 +269,6 @@ _di_: Add inlineimages STARTUP (insert "#+begin_" block-name) (unless (looking-at (rx "\n")) (insert "\n")))) -(defalias 'org-dblock-write:oni-backlinks 'oni-org-dblock-write-backlinks) - ;; Create a new archive for each year. This way archives don't keep growing ;; indefinitely and opening the archive doesn't load every single language I've ;; ever used because there are code blocks in there. @@ -457,58 +321,6 @@ and not a state update." (setq org-default-notes-file (expand-file-name "inbox.org" oni-org-todo-dir)) (setq org-bibtex-autogen-keys t) -(defun oni-org-find-heading-in-file (heading file &optional move) - "Try to find HEADING somewhere in FILE. -This function returns nil if HEADING couldn’t be found, and the -position where the chapter starts otherwise. If MOVE is non-nil -also move point to the start of the heading." - (let ((buffer (find-file-noselect file))) - (with-current-buffer buffer - (save-excursion - (goto-char (point-min)) - (org-find-exact-headline-in-buffer heading buffer (not move)))))) - -(defun oni-org-create-book-heading (book-title file) - "Create a new heading for BOOK-TITLE in FILE." - (let ((buffer (find-file file))) - (with-current-buffer buffer - (goto-char (point-max)) - (insert "\n* " book-title "\n\n ")))) - -(defun oni-org-create-chapter-heading (book-title chapter-title file) - "Create a new heading under BOOK-TITLE for CHAPTER-TITLE in FILE." - (let ((buffer (find-file file))) - (with-current-buffer buffer - (goto-char (point-min)) - (goto-char (oni-org-find-heading-in-file book-title file t)) - (goto-char (org-element-property :end (org-element-at-point))) - (unless (= (point) (point-max)) - (open-line 2)) - (insert "\n** " chapter-title "\n\n ")))) - -(defun oni-org-create-chapter-section (chapter-title file) - "Create a new notes section under CHAPTER-TITLE in FILE." - (let ((buffer (find-file file))) - (with-current-buffer buffer - (goto-char (point-min)) - (goto-char (oni-org-find-heading-in-file chapter-title file t)) - (goto-char (org-element-property :contents-end (org-element-at-point))) - (insert "\n")))) - -(defun oni-org-reading-note () - "Find the org-header associated with the current chapter or page." - (let* ((headers (split-string (format-mode-line header-line-format) ":" t " ")) - (book-name (car headers)) - (chapter-name (cadr headers)) - (notes-file (oni-org-expand-to-home "documents/gtd/reading-notes.org")) - (chapter-start (oni-org-find-heading-in-file chapter-name notes-file))) - (if (not chapter-start) - (let ((book-start (oni-org-find-heading-in-file book-name notes-file))) - (unless book-start - (oni-org-create-book-heading book-name notes-file)) - (oni-org-create-chapter-heading book-name chapter-name notes-file)) - (oni-org-create-chapter-section chapter-name notes-file)))) - (defun oni-org-todo-maybe-hide-body () "Hide the current outline body if ‘org-state’ is a DONE state." (when (member org-state org-done-keywords) @@ -521,10 +333,7 @@ also move point to the start of the heading." (org-update-all-dblocks))) (setq org-todo-keywords - '((sequence "TODO(t)" "WIP" "BLOCKED(b@)" "|" "DONE(d!)") - (sequence "READ(r)" "READING(!)" "|" "FINISHED(!)" "STOPPED(@)") - (sequence "WATCH(w)" "WATCHING" "|" "WATCHED(!)") - (sequence "LISTEN(l)" "LISTENING" "|" "DONE(d!)") + '((sequence "TODO(t)" "WIP" "WAITING(W@)" "|" "DONE(d!)") (sequence "|" "CANCELLED(c@)"))) (add-hook 'org-after-todo-state-change-hook 'oni-org-todo-maybe-hide-body) @@ -557,12 +366,6 @@ also move point to the start of the heading." (add-hook 'org-mode-hook 'yas-minor-mode) (org-edna-mode) -(org-super-agenda-mode) - -(unless (eq system-type 'windows-nt) - (require 'org-bullets) - (add-hook 'org-mode-hook 'org-bullets-mode) - (add-hook 'org-mode-hook #'oni-org-setup-prettify-symbols-mode)) ;;;###autoload (global-set-key (kbd "C-c o") '("Org commands" . oni-hydra-org/body)) @@ -703,30 +506,6 @@ After running it once remove it from `org-capture-after-finalize-hook'." (let ((title (oni-org-get-url-title url))) (format "[[%s][%s]]" url title))) -(defun oni-org-format-months () - (let* ((time (org-timestamp-to-time - (org-timestamp-from-string (concat "<" (org-read-date) ">")))) - (decoded (decode-time time)) - (next-month - (time-add time (days-to-time (date-days-in-month - (decoded-time-year decoded) - (decoded-time-month decoded)))))) - (concat (format-time-string "%b " time) - (format-time-string "%b " next-month) - (format-time-string "%Y" time)))) - -(defun oni-org-ask-names () - (let ((n 1) - article-name - names) - (while (not (string-empty-p (setq article-name (read-string (format "Article Name %d: " n))))) - (push article-name names) - (cl-incf n)) - (reverse names))) - -(defun oni-org-format-names (names) - (mapconcat (lambda (n) (format "** READ %s" n)) names "\n")) - (defun org-edna-finder/next-sibling-first-child () "A finder for ‘org-edna’ to find the first child of the next sibling." (save-excursion @@ -1229,29 +1008,17 @@ same code all the time." (map-insert ,collection ,key-name ,value-name)) ,value-name))))) -(oni-org--map-put org-agenda-custom-commands "P" - '("Stuck projects" ((org-ql-block '(and (todo) (children) (not (children (todo)))))))) - -(oni-org--map-put org-agenda-custom-commands "o" - '("Overview" ((org-ql-block '(and (todo) - (children) - (not (children (todo)))) - ((org-ql-block-header "Stuck projects"))) - (org-ql-block '(and (todo) (not (children))) - ((org-super-agenda-groups '((:auto-parent))) - (org-ql-block-header "Todo"))) - (agenda "" - ((org-agenda-span 3)))))) - +(defvar oni-org--capture-D-date nil) (oni-org--map-put org-capture-templates "D" - '("A DONE item for my to-done list." entry (file oni-org-todo-main-file) - "* DONE %? + '("A DONE item for my to-done list." entry (file oni-org-todo-main-file) "* DONE %? +CLOSED: %(setq oni-org--capture-D-date (format-time-string (org-time-stamp-format t t) (org-read-date t t nil \"Date: \"))) :PROPERTIES: -:CREATED: %U +:CREATED: %(progn oni-org--capture-D-date) :END: :LOGBOOK: -- State \"DONE\" from \"TODO\" %U -:END:")) +- State \"DONE\" from \"TODO\" %(progn oni-org--capture-D-date) +:END:" + :after-finalize (lambda () (setq oni-org--capture-D-date nil)))) (oni-org--map-put org-capture-templates "t" '("A simple TODO item." entry (file "") "* TODO %?