Skip to content

Instantly share code, notes, and snippets.

@pragmat1c1
Last active April 1, 2024 05:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pragmat1c1/094dd8d4a8dc47307e871025bc0638d2 to your computer and use it in GitHub Desktop.
Save pragmat1c1/094dd8d4a8dc47307e871025bc0638d2 to your computer and use it in GitHub Desktop.
Creating journal entries in your Obsidian vault via Emacs! Yay!
;;; Capture into Obsidian journal files
;; author: u/pragmat1c1
;; Friday, 29. March 2024 22:59
(defvar obsidian-journal-dir "/Users/pragmat1c1/Documents/Obsidian_vaults/Journal"
"Directory where journal files are stored.")
(defun ugt-journal-get-journal-file-today ()
"Return filename for today's journal entry and open the file at the last line."
(let* ((date (format-time-string "%Y-%m-%d"))
(file-name (expand-file-name (format "%s.md" date) obsidian-journal-dir)))
(unless (file-exists-p file-name)
(with-temp-buffer
(insert "---\n")
(insert (format "title: %s\n" date))
(insert (format "date: %s\n" date))
(insert (format "created: \"%s\"\n" (format-time-string "%Y-%m-%d %H:%M")))
(insert "type: journal\n")
(insert "---\n\n# Happenings\n\n")
(write-file file-name)))
(find-file file-name) ; Open the file
(goto-char (point-max)) ; Move cursor to the end of the buffer
file-name))
(defun ugt-journal-markdown-capture (file heading content)
"Append content to a Markdown file under a specific heading with time prefix."
(find-file file)
(goto-char (point-max))
(let ((time-prefixed-heading (format "## %s - %s\n" (format-time-string "%H:%M") heading)))
(unless (search-backward time-prefixed-heading nil t)
(goto-char (point-max))
(insert (format "\n%s\n" time-prefixed-heading))) ; Ensure a newline is added after the heading
(insert (format "%s\n" content))
(save-buffer)))
(define-minor-mode ugt-journal-markdown-capture-mode
"Minor mode for special key bindings in a Markdown capture buffer."
:lighter " MDCap"
:keymap (let ((map (make-sparse-keymap)))
(define-key map (kbd "C-c C-c") 'ugt-journal-finish-markdown-capture)
(define-key map (kbd "C-c C-k") 'ugt-journal-abort-markdown-capture)
map)
(setq-local header-line-format
(substitute-command-keys
" Write to today's journal file. | Finish `\\[ugt-journal-finish-markdown-capture]', abort `\\[ugt-journal-abort-markdown-capture]'.")))
(defun ugt-journal-finish-markdown-capture ()
"Function to finish capturing and append to the Markdown file."
(interactive)
(let* ((content (buffer-string))
(lines (split-string content "\n" t))
(heading (car lines))
(body (mapconcat 'identity (cdr lines) "\n"))
(file (ugt-journal-get-journal-file-today)))
(kill-buffer)
(ugt-journal-markdown-capture file heading body)
(message "Markdown capture completed.")))
(defun ugt-journal-abort-markdown-capture ()
"Function to abort the Markdown capturing process."
(interactive)
(kill-buffer)
(message "Markdown capture aborted."))
(defun ugt-journal-capture-to-markdown ()
"Capture input in a temporary buffer and append it
to a Markdown file, with special minor mode for key bindings."
(interactive)
(let ((input-buf (generate-new-buffer "*Markdown Capture*")))
(switch-to-buffer input-buf)
(markdown-mode)
(ugt-journal-markdown-capture-mode 1)
;;(message "Type your notes. Finish 'C-c C-c', abort 'C-c C-k'.")
))
;;; Shortcuts
(global-set-key (kbd "s-j") 'ugt-journal-capture-to-markdown) ; s-j to capture a new entry.
(global-set-key (kbd "s-t") (lambda ()
(interactive)
(find-file (ugt-journal-get-journal-file-today)))) ; s-t to open today's journal.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment