Homepage: https://git.sr.ht/~swflint/time-block-command
Author: Samuel W. Flint
Updated:
Block running commands using time
This package requires [`ts.el`](https://github.com/alphapapa/ts.el) to
handle time parsing.
Download `time-block.el` to somewhere on your `load-path' and
load with `(require 'time-block)`.
Usage
To use this package it's necessary to do two things: define time
blocking groups and define time blocked commands.
Time Blocking Groups
Customize the variable `time-block-groups'. An example of a groups
definition is below.
(setf time-block-groups '((workday . ((1 . (("09:00" . "17:00")))
(2 . (("09:00" . "17:00")))
(3 . (("09:00" . "17:00")))
(4 . (("09:00" . "17:00")))
(5 . (("09:00" . "17:00")))))))
This variable is an alist of names (keywords) to group definitions. A
group definition is an alist from days of the week (as numbers, Sunday
= 0/7, etc.) to lists of start/stop pairs (times in "HH:MM" form).
It is also possible to ignore time blocking on holidays. This is
globally set using the `time-block-skip-on-holidays-p' variable.
This defaults to nil, which does not ignore blocking on holidays.
If set to t, time blocking will be ignored on any holiday. It may
also be set to a regular expression or a list. Holidays which
match either representation will cause time blocking to be ignored.
Defining Time Blocked Commands
Commands are only time-blocked if they're defined. This is done
using the `define-time-blocked-command` macro, which behaves
similarly to `defun`. After the lambda list, it has a list
describing blocking and blocking messages. This is composed of a
symbol (a key in `time-block-groups') a block message, and an
optional override prompt (if present, the command will ask if you'd
like to override the block using `time-block-confirm-override').
An example is shown below.
(define-time-blocked-command my/start-elfeed ()
(workday "You have decided not to check news currently."
"You have decided not to check news currently.\nStill start elfeed?")
"Start `elfeed'.
Time blocked according to `time-block-groups'."
(interactive)
(elfeed))
Advising commands to be time-blocked
Commands can also be advised to use timeblocking. This works for
simpler commands, and as a bonus, can make it harder to access the
commands when blocked. Overall, the arguments for `group`,
`block-message` and `override-prompt` are as above. Consider the
following example.
(time-block-advise my/elfeed-block-advice 'elfeed workday "You have decided not to check news currently."
"You have decided not to check news currently.\nStill start elfeed?")
Focus Mode
A "focus mode" may be enabled using the `time-block-focus-mode'
command. This global minor mode by default will block all
block-groups, but this behavior may be changed using
`time-block-block-checkers'.
Relaxed Mode
A "relaxed mode" (disabling all blocking) may be enabled with the
`time-block-relaxed-mode' command. This global minor mode will
disable all block groups (and ignore `time-block-focus-mode'). At
present, this behavior is not configurable.
Checking if A Group Is Blocked
You may check if a group is currently blocked using the
`time-block-blocked-p' function, which uses the functions in
`time-block-block-checkers' to determine if a group is presently
blocked. Functions in this hook must take one argument, a group
name, and return non-nil if the group is to be blocked.
Manually advising commands to be time-blocked
Commands can also be manually advised. This can be done to prevent
only certain cases from happening. For instance, I use the following
code to delay myself from editing my Emacs configuration during the
workday.
(defun my/buffer-sets-around-advice (orig name)
"Check if NAME is 'emacs', if so, follow time blocking logic before calling ORIG (`buffer-sets-load-set')."
(unless (and (string= name "emacs")
(time-block-blocked-p :workday)
(not (time-block-confirm-override "You have decided not to edit your emacs configuration at this time.\nContinue?")))
(funcall orig name)))
(advice-add 'buffer-sets-load-set :around #'my/buffer-sets-around-advice)
Confirmation Functions
When an automatically-advised function or function defined with
`define-time-block-command' provides an override prompt, the
function `time-block-confirm-override' is used to confirm that the
block should be overriden. This is done following the logic of
`time-block-override-confirmation-functions', an alist from block
groups (or default t) to prompting functions. The prompting
function should take one argument (a confirmation prompt) and
return non-nil if the block should be overridden. The default is
`yes-or-no-p', but the functions
`time-block-override-math-question' and
`time-block-override-random-string' may be used as well.