feat(notetaking): add custom views

This commit is contained in:
Tibo De Peuter 2026-07-11 20:26:10 +02:00
parent f6ec07f646
commit f07ed4336c
No known key found for this signature in database
GPG key ID: 9187B5FA0F4B6F6D
3 changed files with 133 additions and 14 deletions

View file

@ -21,12 +21,13 @@
];
emacsDependencies = with pkgs; [
hunspell
hunspellDicts.nl_NL
hunspellDicts.en_GB-large
ghostscript
graphviz
hunspell
hunspellDicts.en_GB-large
hunspellDicts.nl_NL
imagemagickBig
pandoc
poppler-utils
ripgrep
@ -60,6 +61,7 @@
epkgs.unicode-fonts
pkgs.shellcheck
epkgs.guess-language
];
})
@ -72,7 +74,6 @@
#})
pkgs.ankiAddons.anki-connect
pkgs.pandoc
])
] ++ emacsDependencies;
};

View file

@ -138,9 +138,54 @@
(auto-dark-mode)
)
;; TODO org-roam stores everything with a prefix. Is there a way to disable that or not?
(defvar my/pre-zen-menu-bar nil "Store menu bar state before zen mode.")
(defvar my/pre-zen-tool-bar nil "Store tool bar state before zen mode.")
(defvar my/pre-zen-scroll-bar nil "Store scroll bar state before zen mode.")
(defvar my/pre-zen-line-numbers nil "Stores line number state before zen mode.")
(define-minor-mode my/zen-mode
"A complete full-screen, distraction-free environment."
:init-value nil
:global t
(if my/zen-mode
(progn ;; ON
(setq my/pre-zen-menu-bar (bound-and-true-p menu-bar-mode))
(setq my/pre-zen-tool-bar (bound-and-true-p tool-bar-mode))
(setq my/pre-zen-scroll-bar (bound-and-true-p scroll-bar-mode))
(setq my/pre-zen-line-numbers (bound-and-true-p global-display-line-numbers-mode))
(olivetti-mode 1)
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(display-line-numbers-mode -1)
(set-frame-parameter nil 'fullscreen 'maximized))
(progn ;; OFF
(olivetti-mode -1)
(menu-bar-mode (if my/pre-zen-menu-bar 1 -1))
(tool-bar-mode (if my/pre-zen-tool-bar 1 -1))
(scroll-bar-mode (if my/pre-zen-scroll-bar 1 -1))
(display-line-numbers-mode (if my/pre-zen-line-numbers 1 -1))
(set-frame-parameter nil 'fullscreen nil))
))
(define-minor-mode my/presentation-mode
"A clean, scaled-up environment."
:init-value nil
:global t
(if my/presentation-mode
(progn ;; ON
(my/zen-mode 1) ;; Inherit zen mode
(face-remap-set-base 'default :height 180)) ;; Scale font to 18pt
(progn ;; OFF
(my/zen-mode -1)
(face-remap-set-base 'default))
))
(global-set-key (kbd "<f11>") 'my/zen-mode)
(global-set-key (kbd "<f12>") 'my/presentation-mode)
;; TODO Put exports in their own directory? (now filename-prefix.pdf)
;; TODO Put dailies in "journals" instead of "daily"
;; TODO I store my lecture PDFs in ~/Nextcloud/Documents/UGent/<course>/theory/*.pdf, is there some way to make a shortcut for this (related to Fuzzy finding files etc.). Maybe consider integrating with Zotero and storing PDFs there?
;; Additional package to explore
@ -151,9 +196,6 @@
;; TODO (add-hook 'text-mode-hook 'auto-fill-mode)
;; Do I want this?
;; TODO Automatically save buffer when going to other file -- maybe interactively?
;; TODO Spellchecking (UK & Dutch)
;; TODO Finally, compare experience to organice https://organice.200ok.ch/
;; TODO org-compile-file: File "/tmp/nix-shell.UEk6Ye/orgtexcJso3E.dvi" wasn’t produced Please adjust ‘dvipng’ part of ‘org-preview-latex-process-alist’.

View file

@ -21,12 +21,16 @@
(add-hook 'org-mode-hook 'visual-line-mode) ;; Make text wrap in org mode
(add-hook 'org-mode-hook (lambda () (display-line-numbers-mode -1))) ;; Hide line numbers in org mode
:custom
(org-hide-emphasis-markers t) ;; Required for org-appear to work
;(org-hide-emphasis-markers t) ;; Required for org-appear to work
(org-pretty-entities t)
(org-image-actual-width nil) ;; Allow resizing images
(org-link-window-setup 'current-window) ;; Force links to open in the current window
(org-startup-folded 'showall) ;; https://orgmode.org/manual/Initial-visibility.html
(org-html-with-latex 'lualatex-svg) ;; Tell HTML export to use SVG image pipeline
:bind
(:map org-mode-map
("M-s r" . (lambda () (interactive) (consult-ripgrep my-org-roam-base-dir))) ;; Search in whole roam directory
)
:config
(setq org-latex-compiler "lualatex")
@ -65,9 +69,9 @@
(org-roam-dailies-directory "dailies/")
(org-roam-completion-everywhere t)
:bind (
("C-c r f" . org-roam-node-find) ;; TODO This is case sensitive, make it insensitive
("C-c r j" . org-roam-dailies-capture-today)
("C-c r f" . org-roam-node-find)
("C-c r t" . org-roam-dailies-goto-today)
("C-c r j" . my/org-roam-journal-stream)
)
:init
(setq org-roam-mode-sections ;; https://www.orgroam.com/manual.html#Configuring-what-is-displayed-in-the-buffer-1
@ -84,8 +88,9 @@
'(("d" "default" plan "%?"
:target (file+head "notes/%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n")
:unnarrowed t))
)
:unnarrowed t)))
(setq org-roam-node-display-template
(concat "${title:*} " (propertize "${tags:20}" 'face 'org-tag)))
(add-to-list 'display-buffer-alist
'("\\*org-roam\\*"
@ -97,6 +102,41 @@
) ;; Open backlinks on the right.
)
(defun my/org-roam-dailies-prune ()
"Scan org-roam dailies and prune empty entries."
(let* ((daily-dir (expand-file-name "dailies" my-org-roam-base-dir))
(files (directory-files daily-dir t "^[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.*\\.org$"))
(empty-files '()))
(dolist (file files)
(when (file-exists-p file)
(with-temp-buffer
(insert-file-contents file)
(let* ((content (buffer-string))
(no-title (replace-regexp-in-string "^#\\+title:.*$" "" content))
(no-properties (replace-regexp-in-string "^:PROPERTIES:\n\\(.*\n\\)*?:END:\n" "" no-title))
(clean (replace-regexp-in-string "[ \t\n\r]+" "" no-properties)))
(when (string-empty-p clean)
(push file empty-files))))))
(if empty-files
(let ((buf (get-buffer-create "*Empty Journals to Prune*")))
(with-current-buffer buf
(erase-buffer)
(insert "The following journal files appear to be empty:\n\n")
(dolist (f empty-files)
(insert (format "- %s\n" (file-name-nondirectory f)))))
(display-buffer buf '((display-buffer-in-direction) (direction . bottom)))
(let ((proceed (yes-or-no-p (format "Found %d empty journal files. Delete them? " (length empty-files)))))
(when proceed
(dolist (f empty-files)
(delete-file f))
(message "Empties pruned."))
(kill-buffer buf)
t)) ;; Return t to allow exit
t))) ;; Return t to allow exit if no empties found
(add-hook 'kill-emacs-query-functions #'my/org-roam-dailies-prune)
(use-package org-download
:ensure t
:after org
@ -127,6 +167,42 @@
)
)
(defun my/org-roam-journal-stream ()
"Create a virtual buffer showing journal entries."
(interactive)
(let* ((buf (get-buffer-create "*Journal-Stream*"))
(daily-dir (expand-file-name "dailies" my-org-roam-base-dir))
(files (reverse (sort (directory-files daily-dir t "^[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.*\\.org$") 'string<)))
)
(with-current-buffer buf
(setq default-directory daily-dir)
(read-only-mode -1)
(erase-buffer)
(insert "#+title: Journal Timeline\n#+options: toc:nil num:nil\n\n")
(if (null files)
(insert "* No journal entries found.\n")
(dolist (file files)
(let ((date-str (file-name-base file)))
(insert (format "* %s\n" date-str))
(let ((content (with-temp-buffer
(insert-file-contents file)
(goto-char (point-min))
(when (re-search-forward "^:PROPERTIES:\n\\(.*\n\\)*?:END:\n" nil t)
(replace-match ""))
(goto-char (point-min))
(when (re-search-forward "^#\\+title:.*\n" nil t)
(replace-match ""))
(goto-char (point-min))
(while (re-search-forward "^\\*" nil t)
(replace-match "**"))
(buffer-string))))
(insert content)
(insert "\n\n")))))
(org-mode)
(read-only-mode 1)
(org-overview))
(switch-to-buffer buf)))
;; Integrations
(use-package org-anki ;; https://github.com/eyeinsky/org-anki