Created
December 1, 2019 18:19
-
-
Save amitp/7a133026dafac2131e5f023d43acbc16 to your computer and use it in GitHub Desktop.
My org-mode journal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; my-diary.el --- | |
;;; Commentary: | |
;; My daily diary, inspired by org-journal, but customized for my needs. | |
;; Timestamps rounded to the nearest 5 minutes. | |
;; | |
;; My keybindings: H-j to open the diary file (global binding), then | |
;; H-j to add an entry (local binding). C-c C-b, C-c C-f to move days | |
;; (like org-journal). H-i to search previous headings for completion, | |
;; so that I can reuse headings and then analyze them. | |
;;; Code: | |
(require 'org) | |
;;; Configuration variables | |
(defvar my-diary-directory "~/Documents/journal/") | |
(defvar my-diary-filename (expand-file-name (concat my-diary-directory "%Y-%m-%d.org"))) | |
(defvar my-diary-filename-regexp | |
(concat "\\`" | |
(s-replace "%Y-%m-%d" "\\(....-..-..\\)" | |
(regexp-quote my-diary-filename)) | |
"\\'")) | |
(add-to-list 'auto-mode-alist (cons my-diary-filename-regexp 'my-diary-mode)) | |
;;; Helper functions | |
(defun my-diary-filename-to-date (filename) | |
(let ((str (cadr (s-match my-diary-filename-regexp (expand-file-name filename))))) | |
(when str | |
(let* ((time (parse-time-string str)) | |
(date (list (nth 4 time) (nth 3 time) (nth 5 time)))) | |
date)))) | |
(defun my-diary-calendar-day-to-time (calendar-day) | |
"Emacs day/time functions are … lacking" | |
(encode-time 0 0 0 (nth 1 calendar-day) (nth 0 calendar-day) (nth 2 calendar-day))) | |
(defun my-diary-change-day (dir) | |
"Construct filename 'dir' days from current filename" | |
(let* ((day (calendar-absolute-from-gregorian (my-diary-filename-to-date (buffer-file-name)))) | |
(newday (calendar-gregorian-from-absolute (+ day dir)))) | |
(format-time-string | |
my-diary-filename | |
(my-diary-calendar-day-to-time newday)))) | |
;;; Commands | |
(defun my-diary-today () | |
"Open today's diary file" | |
(interactive) | |
(find-file (format-time-string my-diary-filename)) | |
(when (equal (point-max) 1) | |
(let ((calendar-date (my-diary-filename-to-date (buffer-file-name)))) | |
(insert (format-time-string | |
(read-file-into-string | |
(concat my-diary-directory "/diary-template.org")) | |
(my-diary-calendar-day-to-time calendar-date))))) | |
(goto-char (point-max))) | |
(defun my-diary-new-entry () | |
"Make a new entry, rounded to the nearest 5 minutes" | |
(interactive) | |
(my-diary-today) | |
(insert (format-time-string "** %H:%M " (org-current-time 5)))) | |
(defun my-diary-search-headings () | |
"Search through previous headings for completion" | |
(interactive) | |
(let ((headings (split-string | |
(shell-command-to-string | |
(concat "rg --no-filename '^[*][*] \\d\\d:\\d\\d (.*)$' --replace '$1' " my-diary-directory " | sort | uniq -c | sort -n -r | perl -pe 's/^ *\\d* *//'")) | |
"\n"))) | |
(ivy-read "Headings: " | |
headings | |
:caller 'my-diary-heading | |
:action #'insert))) | |
(defun my-diary-next-day () | |
"Move to the next day's diary file" | |
(interactive) | |
(find-file (my-diary-change-day 1))) | |
(defun my-diary-prev-day () | |
"Move to the previous day's diary file" | |
(interactive) | |
(find-file (my-diary-change-day -1))) | |
(define-derived-mode my-diary-mode org-mode "Journal" | |
"Mode for writing diary entries" | |
(face-remap-add-relative 'default :family "Work Sans" :height 1.1) | |
(turn-on-visual-line-mode) | |
(run-mode-hooks)) | |
(provide 'my-diary) | |
;;; my-diary.el ends here |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I used org-capture for several years and then org-journal for five years. I switched to my own code because org-journal was getting slower over time (I have 2000+ journal files and my laptop is 7+ years old), and also because org-journal didn't let me customize some things.
The main thing I needed was to open a file, move the cursor to the end, and insert a headline. This is similar to org-capture. Other features I wanted:
Factorio :game:
, so I can typef
a
c
and complete the rest of this.