Every week at work, I type a line in my org notes like so:
*** 2024-W46 [2024-11-11 Mon]--[2024-11-15 Fri]:
Clicking this date range opens the five-day agenda view for the week, and allows me to visualize all the meetings and date-stamped events I’ve recorded for the week in question.
Engineering and computer science types of people love to spend hours automating away minor inconveniences. Living in a LISP interpreter enables these automations to be written quickly, re-used, and improved over time without the crazy hassle of writing personal extensions in other popular text editors.
Now, rather than typing the line above, I can type M-x r/new-week
or
C-c n w
and have this line appear with no effort at all, saving
twenty or so keystrokes a week. C-c n m
runs r/new-meeting
which
adds a heading with the current time - enabling me to use the calendar
view in Emacs to jump to my notes for a particular time.
Running new week now adds the following to my buffer:
** 2024-W48 [2024-11-25 Mon]--[2024-11-29 Fri]:
*** Monday Morning Standup
At: <2024-11-25 Mon 09:00>
- =( the cursor will end up here )=
Running new meeting now adds the following to my buffer:
*** =( the cursor will end up here )=
At: <2024-11-26 Tue 12:12>
…by using the save-excursion
function, I can ensure my cursor ends
up right where I would write the title of the meeting, saving a bit of
navigation time.
Here’s the full source code:
;;; work.el --- Work related Elisp -*- lexical-binding: t; -*-
;;; Commentary:
;; Some simple functions to hack on for work at IBM.
;;; Code:
;; Libraries
(require 'cl-lib)
(require 'org)
(require 's)
(defun get-day (time day-of-week)
"Given the current TIME and DAY-OF-WEEK, return the 'day-shifted' time."
(let ((weekday (decoded-time-weekday (decode-time time))))
(message "Weekday: %s" weekday)
(cond
((= weekday day-of-week) time)
((> weekday day-of-week) (time-subtract time (days-to-time (- weekday day-of-week))))
((< weekday day-of-week) (time-add time (days-to-time (- day-of-week weekday))))
(t (error "Error! Imaginary time")))))
(defun get-monday (time)
"Given the current TIME, return the same time on Monday."
(get-day time 1))
(defun get-friday (time)
"Given the current TIME, return the same time on Friday."
(get-day time 5))
(defun r/new-meeting ()
"Prints a header for a new meeting to the org buffer."
(interactive)
(org-insert-heading)
;; Return to location where we'll enter the meeting title.
(save-excursion
(let ((now (current-time)))
(insert (format-time-string "\nAt: <%Y-%m-%d %a %H:%M>\n\n" now)))))
(defun r/new-week ()
"Prints a header for the current week's notes to the org file."
(interactive)
;; I usually organize my file into week-long headers,
;; so this action moves the weekly header left once.
(org-insert-heading)
(org-metaleft)
;; Write the current-week heading based on today's date.
(let ((now (current-time)))
(insert (format-time-string "%Y-W%W " now))
;; Org Timestamp Format: [2024-11-12 Tue 10:00]
(insert (format-time-string "[%Y-%m-%d %a]--" (get-monday now)))
(insert (format-time-string "[%Y-%m-%d %a]:\n" (get-friday now))))
;; Insert Monday Standup meeting
(org-insert-heading)
(org-metaright)
(insert "Monday Morning Standup\n")
(let ((now (current-time)))
(insert (format-time-string "At: <%Y-%m-%d %a 09:00>" (get-monday now)))
;; The cursor will now start ready at this first bullet point
(insert "\n\n- ")))
(provide 'work)
;;; work.el ends here
In the part of your configuration files where you set keybindings, add the following:
(require 'work)
(global-set-key (kbd "C-c n w") 'r/new-week)
(global-set-key (kbd "C-c n m") 'r/new-meeting)
In the future, I think I’ll update this script to snap the meeting time to the nearest previous 15-minute mark. If the meeting was scheduled for 10:15, chances are I won’t be writing notes until 10:17 or maybe even 10:28.
You’ve gotta love Emacs.
Comments