From 4ca76053d2124279636552e16eced088f78c5923 Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Sun, 15 Sep 2024 20:19:59 +0200 Subject: [PATCH] denote lazy loading --- emacs/module/module-denote-index.el | 146 +++++++++++++------------ emacs/module/module-denote-multidir.el | 112 ++++++++++--------- emacs/module/module-denote.el | 71 ++++++------ 3 files changed, 169 insertions(+), 160 deletions(-) diff --git a/emacs/module/module-denote-index.el b/emacs/module/module-denote-index.el index 166fba1..5465aab 100644 --- a/emacs/module/module-denote-index.el +++ b/emacs/module/module-denote-index.el @@ -9,85 +9,87 @@ (require 'module-denote) -(defvar my/denote-metadata-index-file (concat denote-directory "../denote-metadata.org") - "Path to the metadata index file.") +(with-eval-after-load 'denote -(defun my/extract-date-from-filename (file) - "Extract date from FILE name. Assumes first 8 characters are YYYYMMDD." - (substring (file-name-nondirectory file) 0 8)) + (defvar my/denote-metadata-index-file (concat denote-directory "../denote-metadata.org") + "Path to the metadata index file.") -(defun my/format-date (date-string) - "Format DATE-STRING (YYYYMMDD) as YYYY-MM-DD." - (format "%s-%s-%s" - (substring date-string 0 4) - (substring date-string 4 6) - (substring date-string 6 8))) + (defun my/extract-date-from-filename (file) + "Extract date from FILE name. Assumes first 8 characters are YYYYMMDD." + (substring (file-name-nondirectory file) 0 8)) -(defun my/extract-summary (file) - "Extract summary from FILE." - (with-temp-buffer - (insert-file-contents file) - (goto-char (point-min)) - (when (re-search-forward "^\\* Summary$" nil t) - (forward-line) - (let ((start (point))) - (if (re-search-forward "^\\*" nil t) - (string-trim (buffer-substring-no-properties start (line-beginning-position))) - (string-trim (buffer-substring-no-properties start (point-max)))))))) + (defun my/format-date (date-string) + "Format DATE-STRING (YYYYMMDD) as YYYY-MM-DD." + (format "%s-%s-%s" + (substring date-string 0 4) + (substring date-string 4 6) + (substring date-string 6 8))) -(defun my/update-denote-metadata-index () - "Update the metadata index for Denote notes in Org format." - (interactive) - (with-temp-file my/denote-metadata-index-file - (insert "#+TITLE: Denote Metadata Index\n") - (insert "#+AUTHOR: Your Name\n") - (insert "#+DATE: " (format-time-string "%Y-%m-%d") "\n\n") - (dolist (file (directory-files-recursively denote-directory "\\.org$")) - (let ((file-contents (with-temp-buffer - (insert-file-contents file) - (buffer-string)))) - (with-temp-buffer - (insert file-contents) - (goto-char (point-min)) - (when (re-search-forward "^#\\+title: \\(.+\\)$" nil t) - (let* ((title (string-trim (match-string 1))) - (keywords (denote-extract-keywords-from-path file)) - (date-string (my/extract-date-from-filename file)) - (formatted-date (my/format-date date-string)) - (is-journal (and (listp keywords) (member "journal" keywords))) - (summary (if is-journal - (format "Journal entry for [%s]" formatted-date) - (my/extract-summary file)))) - (with-current-buffer (find-file-noselect my/denote-metadata-index-file) - (goto-char (point-max)) - (insert (format "* [[file:%s][%s]]\n" file title)) - (insert " :PROPERTIES:\n") - (insert (format " :KEYWORDS: %s\n" keywords)) - (insert (format " :DATE: [%s]\n" formatted-date)) - (insert " :END:\n\n") - (insert (if summary - summary - "No summary provided.")) - (unless (string-suffix-p "\n\n" (or summary "")) - (insert "\n\n")))))))))) + (defun my/extract-summary (file) + "Extract summary from FILE." + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (when (re-search-forward "^\\* Summary$" nil t) + (forward-line) + (let ((start (point))) + (if (re-search-forward "^\\*" nil t) + (string-trim (buffer-substring-no-properties start (line-beginning-position))) + (string-trim (buffer-substring-no-properties start (point-max)))))))) + + (defun my/update-denote-metadata-index () + "Update the metadata index for Denote notes in Org format." + (interactive) + (with-temp-file my/denote-metadata-index-file + (insert "#+TITLE: Denote Metadata Index\n") + (insert "#+AUTHOR: Your Name\n") + (insert "#+DATE: " (format-time-string "%Y-%m-%d") "\n\n") + (dolist (file (directory-files-recursively denote-directory "\\.org$")) + (let ((file-contents (with-temp-buffer + (insert-file-contents file) + (buffer-string)))) + (with-temp-buffer + (insert file-contents) + (goto-char (point-min)) + (when (re-search-forward "^#\\+title: \\(.+\\)$" nil t) + (let* ((title (string-trim (match-string 1))) + (keywords (denote-extract-keywords-from-path file)) + (date-string (my/extract-date-from-filename file)) + (formatted-date (my/format-date date-string)) + (is-journal (and (listp keywords) (member "journal" keywords))) + (summary (if is-journal + (format "Journal entry for [%s]" formatted-date) + (my/extract-summary file)))) + (with-current-buffer (find-file-noselect my/denote-metadata-index-file) + (goto-char (point-max)) + (insert (format "* [[file:%s][%s]]\n" file title)) + (insert " :PROPERTIES:\n") + (insert (format " :KEYWORDS: %s\n" keywords)) + (insert (format " :DATE: [%s]\n" formatted-date)) + (insert " :END:\n\n") + (insert (if summary + summary + "No summary provided.")) + (unless (string-suffix-p "\n\n" (or summary "")) + (insert "\n\n")))))))))) -(defun my/search-denote-notes () - "Use consult-ripgrep to search only the Denote metadata index file." - (interactive) - (let* ((index-file my/denote-metadata-index-file) - (default-directory (file-name-directory index-file)) - (file-name (file-name-nondirectory index-file)) - (consult-ripgrep-args - (concat "rg --null --ignore-case --type org --line-buffered --color=never " - "--max-columns=500 --no-heading --line-number " - "--max-depth 0 " - (shell-quote-argument file-name)))) - (if (file-exists-p index-file) - (consult-ripgrep default-directory) - (message "Metadata index file not found: %s" index-file)))) + (defun my/search-denote-notes () + "Use consult-ripgrep to search only the Denote metadata index file." + (interactive) + (let* ((index-file my/denote-metadata-index-file) + (default-directory (file-name-directory index-file)) + (file-name (file-name-nondirectory index-file)) + (consult-ripgrep-args + (concat "rg --null --ignore-case --type org --line-buffered --color=never " + "--max-columns=500 --no-heading --line-number " + "--max-depth 0 " + (shell-quote-argument file-name)))) + (if (file-exists-p index-file) + (consult-ripgrep default-directory) + (message "Metadata index file not found: %s" index-file)))) -(global-set-key (kbd "C-x n /") #'my/search-denote-notes) + (global-set-key (kbd "C-x n /") #'my/search-denote-notes)) (provide 'module-denote-index) diff --git a/emacs/module/module-denote-multidir.el b/emacs/module/module-denote-multidir.el index 3c0cf0b..4ec6333 100644 --- a/emacs/module/module-denote-multidir.el +++ b/emacs/module/module-denote-multidir.el @@ -10,69 +10,73 @@ (require 'module-denote-index) (require 'module-alioth) ;; depends on alioth for some functions -(defvar my/denote-local-notes-directory "~/notes/") -(defvar my/denote-remote-notes-directory "~/alioth/notes/") +(autoload 'my/denote-create-note "denote" nil t) -(setq denote-directory my/denote-local-notes-directory) +(with-eval-after-load 'denote + + (defvar my/denote-local-notes-directory "~/notes/") + (defvar my/denote-remote-notes-directory "~/alioth/notes/") -(defun my/denote-open-or-create () - "Ensure alioth is mounted before creating or opening a note." - (interactive) - (ensure-alioth-mounted) - (let ((target (denote-file-prompt nil nil :no-require-match))) - (if (and target (file-exists-p target)) - (find-file target) - (denote--command-with-features (denote-command-prompt) :use-file-prompt-as-def-title nil nil nil)))) + (setq denote-directory my/denote-local-notes-directory) -(defun my/denote-echo-current-directory () - "Echo the current value of denote-directory." - (declare (interactive-only t)) - (interactive) - (message "Current Denote directory: %s" denote-directory)) + (defun my/denote-open-or-create () + "Ensure alioth is mounted before creating or opening a note." + (interactive) + (ensure-alioth-mounted) + (let ((target (denote-file-prompt nil nil :no-require-match))) + (if (and target (file-exists-p target)) + (find-file target) + (denote--command-with-features (denote-command-prompt) :use-file-prompt-as-def-title nil nil nil)))) -(defun my/denote-directory-segment () - "Return the current Denote directory for the mode line." - (when (bound-and-true-p denote-directory) - (format " Denote:%s " (file-name-nondirectory (directory-file-name denote-directory))))) + (defun my/denote-echo-current-directory () + "Echo the current value of denote-directory." + (declare (interactive-only t)) + (interactive) + (message "Current Denote directory: %s" denote-directory)) -(defun my/denote-switch-directory () - "Switch current denote working directory." - (interactive) - (let ((new-dir (if (string= denote-directory my/denote-local-notes-directory) - my/denote-remote-notes-directory - my/denote-local-notes-directory))) - (setq denote-directory new-dir) - (setq my/denote-metadata-index-file (concat denote-directory "../denote-metadata.org")) - (message "Denote directory switched to %s" new-dir))) + (defun my/denote-directory-segment () + "Return the current Denote directory for the mode line." + (when (bound-and-true-p denote-directory) + (format " Denote:%s " (file-name-nondirectory (directory-file-name denote-directory))))) -(defun my/denote-use-both-directories (orig-fun &rest args) - "Temporarily use both directories for a given ORIG-FUN and ARGS." - (let ((original-dir denote-directory) - (result nil)) - (setq denote-directory my/denote-local-notes-directory) - (setq result (apply orig-fun args)) - (setq denote-directory my/denote-remote-notes-directory) - (setq result (append result (apply orig-fun args))) - (setq denote-directory original-dir) - result)) + (defun my/denote-switch-directory () + "Switch current denote working directory." + (interactive) + (let ((new-dir (if (string= denote-directory my/denote-local-notes-directory) + my/denote-remote-notes-directory + my/denote-local-notes-directory))) + (setq denote-directory new-dir) + (setq my/denote-metadata-index-file (concat denote-directory "../denote-metadata.org")) + (message "Denote directory switched to %s" new-dir))) -(defun my/denote-create-note () - "Create a note in directory of choice." - (interactive) - (let* ((dirs (list my/denote-local-notes-directory my/denote-remote-notes-directory)) - (chosen-dir (completing-read "Choose directory: " dirs))) - (let ((denote-directory chosen-dir)) - (call-interactively #'denote)))) + (defun my/denote-use-both-directories (orig-fun &rest args) + "Temporarily use both directories for a given ORIG-FUN and ARGS." + (let ((original-dir denote-directory) + (result nil)) + (setq denote-directory my/denote-local-notes-directory) + (setq result (apply orig-fun args)) + (setq denote-directory my/denote-remote-notes-directory) + (setq result (append result (apply orig-fun args))) + (setq denote-directory original-dir) + result)) -(advice-add 'denote-directory-files - :around #'my/denote-use-both-directories) -(advice-add 'denote-directory-subdirectories - :around #'my/denote-use-both-directories) + (defun my/denote-create-note () + "Create a note in directory of choice." + (interactive) + (let* ((dirs (list my/denote-local-notes-directory my/denote-remote-notes-directory)) + (chosen-dir (completing-read "Choose directory: " dirs))) + (let ((denote-directory chosen-dir)) + (call-interactively #'denote)))) -(global-set-key (kbd "C-x n f") #'my/denote-open-or-create) -(global-set-key (kbd "C-x n n") #'my/denote-create-note) -(global-set-key (kbd "C-x n d s") #'my/denote-switch-directory) -(global-set-key (kbd "C-x n d d") #'my/denote-echo-current-directory) + (advice-add 'denote-directory-files + :around #'my/denote-use-both-directories) + (advice-add 'denote-directory-subdirectories + :around #'my/denote-use-both-directories) + + (global-set-key (kbd "C-x n f") #'my/denote-open-or-create) + (global-set-key (kbd "C-x n n") #'my/denote-create-note) + (global-set-key (kbd "C-x n d s") #'my/denote-switch-directory) + (global-set-key (kbd "C-x n d d") #'my/denote-echo-current-directory)) (provide 'module-denote-multidir) diff --git a/emacs/module/module-denote.el b/emacs/module/module-denote.el index 764884b..1fbbca8 100644 --- a/emacs/module/module-denote.el +++ b/emacs/module/module-denote.el @@ -11,42 +11,45 @@ (pkg/require 'denote) -(denote-rename-buffer-mode 1) +(with-eval-after-load 'denote -(setq denote-save-buffers nil - denote-known-keywords '("emacs" "golang" "dev") - denote-infer-keywords t - denote-sort-keywords t - denote-file-type nil - denote-history-completion-in-prompts nil - denote-prompts '(title keywords) - denote-excluded-directories-regexp nil - denote-excluded-keywords-regexp nil - denote-rename-confirmations '(rewrite-front-matter modify-file-name) - denote-date-prompt-use-org-read-date t - denote-date-format nil - denote-backlinks-show-context t) + (denote-rename-buffer-mode 1) -(global-unset-key (kbd "C-x n")) -(global-set-key (kbd "C-x n c") #'denote-region) -(global-set-key (kbd "C-x n !") #'denote-date) -(global-set-key (kbd "C-x n z") #'denote-signature) -(global-set-key (kbd "C-x n s") #'denote-subdirectory) -(global-set-key (kbd "C-x n S-n") #'denote-type) -(global-set-key (kbd "C-x n t") #'denote-template) -(global-set-key (kbd "C-x n l l") #'denote-link) -(global-set-key (kbd "C-x n l a") #'denote-add-links) -(global-set-key (kbd "C-x n l f") #'denote-find-link) -(global-set-key (kbd "C-x n b l") #'denote-backlinks) -(global-set-key (kbd "C-x n b f") #'denote-find-backlink) -(global-set-key (kbd "C-x n r r") #'denote-rename-file) -(global-set-key (kbd "C-x n r f") #'denote-rename-file-using-front-matter) -(let ((map dired-mode-map)) - (define-key map (kbd "C-x n d") #'denote-dired-mode) - (define-key map (kbd "C-x n i") #'denote-link-dired-marked-notes) - (define-key map (kbd "C-x n k") #'denote-dired-rename-marked-files-with-keywords) - (define-key map (kbd "C-x n r r") #'denote-dired-rename-files) - (define-key map (kbd "C-x n r f") #'denote-dired-rename-marked-files-using-front-matter)) + (setq denote-save-buffers nil + denote-known-keywords '("emacs" "golang" "dev") + denote-infer-keywords t + denote-sort-keywords t + denote-file-type nil + denote-history-completion-in-prompts nil + denote-prompts '(title keywords) + denote-excluded-directories-regexp nil + denote-excluded-keywords-regexp nil + denote-rename-confirmations '(rewrite-front-matter modify-file-name) + denote-date-prompt-use-org-read-date t + denote-date-format nil + denote-backlinks-show-context t) + + (global-unset-key (kbd "C-x n")) + (global-set-key (kbd "C-x n n") #'denote) + (global-set-key (kbd "C-x n c") #'denote-region) + (global-set-key (kbd "C-x n !") #'denote-date) + (global-set-key (kbd "C-x n z") #'denote-signature) + (global-set-key (kbd "C-x n s") #'denote-subdirectory) + (global-set-key (kbd "C-x n S-n") #'denote-type) + (global-set-key (kbd "C-x n t") #'denote-template) + (global-set-key (kbd "C-x n l l") #'denote-link) + (global-set-key (kbd "C-x n l a") #'denote-add-links) + (global-set-key (kbd "C-x n l f") #'denote-find-link) + (global-set-key (kbd "C-x n b l") #'denote-backlinks) + (global-set-key (kbd "C-x n b f") #'denote-find-backlink) + (global-set-key (kbd "C-x n r r") #'denote-rename-file) + (global-set-key (kbd "C-x n r f") #'denote-rename-file-using-front-matter) + (let ((map dired-mode-map)) + (define-key map (kbd "C-x n d") #'denote-dired-mode) + (define-key map (kbd "C-x n i") #'denote-link-dired-marked-notes) + (define-key map (kbd "C-x n k") #'denote-dired-rename-marked-files-with-keywords) + (define-key map (kbd "C-x n r r") #'denote-dired-rename-files) + (define-key map (kbd "C-x n r f") #'denote-dired-rename-marked-files-using-front-matter))) (provide 'module-denote)