;;; ha-focus.el --- Emacs lisp code to focus my thoughts. -*- lexical-binding: t; -*- ;; ;; Copyright © 2021,2024 Howard X. Abrams ;; ;; Author: Howard X. Abrams ;; Maintainer: Howard X. Abrams ;; Created: May 28, 2021 ;; ;; This file is not part of GNU Emacs. ;; ;;; Commentary: ;; ;; Find details of this code on my website at: ;; https://www.howardism.org/Technical/Emacs/focused-work.html ;; ;; *NB:* Do not edit this file. Instead, edit the original literate file at: ;; ~/website/Technical/Emacs/focused-work.org ;; And tangle the file to recreate this one. ;; ;;; Code: (defvar ha-focus-timer nil "A timer reference for the ha-focus functions") (defun ha-focus-countdown-timer (minutes fun) (let ((the-future (* minutes 60))) (setq ha-focus-timer (run-at-time the-future nil fun)))) (defun ha-focus-begin () "Start a concerted, focused effort, ala Pomodoro Technique. We first clock into the current org-mode header (or last one), start some music to indicate we are working, and set a timer. Call `ha-focus-break' when finished." (interactive) (ha-focus-countdown-timer 25 'ha-focus-break) (ha-focus--command "tell application \"Spotify\" to play") (if (eq major-mode 'org-mode) (org-clock-in) (org-clock-in-last)) (message "🍅 Started clocked %s" (substring-no-properties (org-clock-get-clock-string)))) (defun ha-focus-break () "Stop the focused time by stopping the music. This also starts another break timer, that calls `ha-focus-break-over' when finished." (interactive) (run-with-idle-timer 30 nil 'ha-focus-capture) (ha-focus--command "tell application \"Spotify\" to pause") (ha-focus-countdown-timer 5 'ha-focus-break-over) (message "🍅 Time to take a break.")) (defun ha-focus-capture () "Spin up a capture window." (ignore-errors (org-capture nil "cc") (sit-for 1) (org-clock-out))) (defun ha-focus-break-over () "Message me to know that the break time is over. Notice that this doesn't start anything automatically, as I may have wandered off." (ha-focus--command "set v to output volume of (get volume settings) set volume output volume 1 say \"Break time over. Back on your head.\" set volume output volume v") (message "🍅 Type to restart the timer.")) (defun ha-focus-interrupt () "Interrupt the current focused timer, if set." (interactive) (when (timerp ha-focus-timer) (cancel-timer ha-focus-timer) (ignore-errors (org-clock-out)))) (require 'async) (defun ha-focus--command (osascript) "Runs OSASCRIPT by passing to the `osascript' command asynchronously." (async-start-process "focus-os" "osascript" 'ha-focus--command-callback "-e" osascript)) (defun ha-focus--command-callback (proc) "Asynchronously called when the `osascript' process finishes." ;; ... ) (provide 'ha-focus) ;;; ha-focus.el ends here