Witam na mojej prywatnej stronie internetowej!
[If this is all Polish to you, click here: English]
Uwaga: z oczywistych powodów nie mogę zagwarantować swojej nieomylności, choć staram się o zgodność tego, co piszę, z Prawdą. Jest również oczywiste, że nie gwarantuję takiej zgodności w przypadku komentarzy. Umieszczenie linku do strony spoza niniejszego serwisu nie musi oznaczać, że podzielam poglądy autora tej strony, a jedynie, że uważam ją za wartościową z takich czy innych powodów.
Marcin ‘mbork’ Borkowski
A long time ago I wrote about the datefudge tool, which can be very useful to test time-related code (not only in Elisp). Today I’m going to write about another way of solving a similar problem.
I am currently building (yet another) tool on top of Org mode. This tool heavily uses the notion of “today”. I made a conscious effort to always use the org-today
function to get today’s date, precisely because I want to be able to mock it for tests.
However, writing automated tests is one thing, and testing stuff manually while developing it is another – both have their place. I thought that it would be pretty cool if I could interactively make org-today
return any given date, so that I’d be able to test things quickly.
One thing that bothers me is this. Assuming I write an interactive wrapper around (advice-add 'org-today :override ...)
, how do I make sure I won’t forget to remove that advice?
And then, an idea occurred to me. I could (again!) write my own version of execute-extended-command
which would first ask for a date (using org-read-date, of course) and then run the given command with org-today
advised.
;;; -*- lexical-binding: t -*- (defun org-fake-today--create-advice (fake-date) "Return the function used to advise `org-today'." (lambda () fake-date)) (defun org-fake-today-execute-command (prefix-arg) "Execute a command with `org-today' temporarily advised. First ask the user for the date." (interactive "P") (advice-add 'org-today :override (org-fake-today--create-advice (time-to-days (org-read-date nil t))) '((name . org-fake-today))) (execute-extended-command prefix-arg) (advice-remove 'org-today 'org-fake-today)) (global-set-key (kbd "C-s-X") #'org-fake-today-execute-command)
Note the comment setting lexical-binding
to t in the first line – we need the value returned from org-fake-today--create-advice
to be a closure which will take the place of org-today
. This means that the above snippet needs to be in a file on its own – or a part of a file where lexical binding is on.
And now I can say, for example, this: C-s-X -7 RET org-agenda RET a
and see the agenda as it had been shown a week ago. How cool is that?
CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryOrgMode