Content AND Presentation

2025-09-15 Entering dates in Emacs Calc

I perform date arithmetic pretty often in Emacs Calc. One problem I’ve always had with that is that entering date forms is very far from ergonomic. (To be fair to Calc, once you get used to how Org mode allows to enter dates, basically any other way of entering them feels slow and inconvenient. This is what Org manual says about it: “The actions of the date/time prompt may seem complex, but I assure you they will grow on you, and you will start getting annoyed by pretty much any other way of entering a date/time out there” – and boy, is it true!)

So, it occurred to me that it would be great to be able to use the Org date prompt in Calc. Of course, this is Emacs, so it shouldn’t be difficult, right?

I started with pressing C-h c and C-h k in Calc and instrumenting Calc functions for Edebug to see which functions I could use. This led me to functions like calc-push and math-read-expr, which would work perfectly fine for my use-case. However, in parallel I asked an LLM how to programmatically push something to Emacs Calc stack (fully expecting gibberish!), and to my surprise, I actually got a reasonable answer. The LLM first told me about calc-push and then reminded me about calc-eval, which I already knew how to use but completely forgot! (I think one of the reasons the answer was so good is that Calc manual actually does document Calc’s internals pretty well.)

So, the only things that remained were to actually code this and find a suitable keybinding. Let’s do the coding first.

(defun calc-enter-date-with-org ()
  "Use `org-read-date' to read a date form and push it onto the Calc stack."
  (interactive)
  (let ((org-read-date-prefer-future nil))
    (calc-eval (format "<%s>" (org-read-date)) 'push)))

(Note that while Calc allows for second resolution of the date forms, org-read-date apparently cannot go below a minute.)

Now for the keybinding. Calc uses angle brackets for date forms, very similar to Org (active) timestamps. It turns out that C-c . (the Org key sequence used for org-timestamp, which inserts an active timestamp at point) is not allocated in Calc mode (which is not surprising given that according to Emacs key binding conventions it is reserved for minor modes – Org does not comply with those conventions, but given that it’s a huge application more than just a “major mode”, it is completely forgivable). So, let’s just put this in my init.el:

(keymap-set calc-mode-map "C-c ."
            'calc-enter-date-with-org)

and we’re good to go! (Of course, this way I have violated the convention, too. But it’s completely ok – it’s my init.el, I can do whatever I want. It would be completely different if I was writing a major mode to be distributed.)

Now, witness the power of Org date prompt in your Calc date calculations;-)!

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryOrgMode

Comments on this page

2025-09-08 Emacs Artist clock

A few months ago I mentioned Artist mode. It seems that at least one person liked that post enough to mention it (thanks!), even if indirectly. That very post also mentioned svg-clock, which is a cute analog clock displayed directly in Emacs.

Of course, my immediate thought was, why not create an ASCII-art analog clock using Artist mode? The task seems easy enough – in fact, the most non-obvious thing was doing the geometric calculations (including simple trigonometry, correction for the 2:1 aspect ratio and transforming between the Artist mode coordinate system and the (sort of) polar coordinate system of the clock, where angle 0 is headed up instead of to the right).

artist-clock.png

The code could probably be a bit more polished – it’s possible that (for example) the switch-to-buffer is not the best idea (it is a function which should not usually be called non-interactively), although in this particular case it seems to do exactly the right thing. (The assumption is that the user themselves will create the window which should display the clock.) Also, the clock is not really “optimized” – each minute (or second) the whole thing is just erased and redrawn, but Artist mode actually allows to “undraw” shapes.

Perhaps one of the two most interesting tidbits (which I knew about but completely forgot) is a very special case of the run-at-time function where the first argument given is t – that function is then ideally suited to displaying clocks. Another one is the second (optional) argument to get-buffer-window, which makes Emacs look for the window displaying the given buffer also on non-selected frames.

That’s it for today, I hope you like my clock!

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2025-09-01 Differentiating between C-c C-c and C-c C-k

Some of the habits I use Beeminder for are maintaining a journal and weighing myself. The way I do these things is that I have a few capture templates with a nonempty :after-finalize property set to a lambda which sends a datapoint to Beeminder.

The problem is, it also sends its datapoint if I press C-c C-k, effectively canceling the entry. How to make it not do so?

It turns out that the answer is pretty simple (if a little bit ugly). There is a (special, and hence global) variable called org-note-abort which is set to t whenever the user presses C-c C-k in circumstances like typing in a captured thing. This means that the only thing I need to do is to wrap the contents of my lambda in (unless org-note-abort ...).

Something worth remembering is that this of course only works in Org mode. For example, Magit’s C-c C-c and C-c C-k are implemented differently, and to achieve a similar effect there you’d need to check the hooks in the with-editor package.

That’s it for today – a niche tip for sure, but maybe someone will find it useful!

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryOrgMode

Comments on this page

More...

CategoryEnglish, CategoryBlog