April 24, 2020

I use Emacs for general text editing for a couple of reasons, the main one of which is that it’s a lot of fun because it’s a world unto itself. It’s also reasonably OK on MacOS. My first encounter with it was back when I wanted to learn Common Lisp with an integrated REPL and I’ve used it off and on ever since. Textmate was my main editor for a while after I learned Emacs, and then Sublime Text, but I’ve always gone back to Emacs because, I suspect, that once you gain any facility with it at all, you come to like it. It’s got gravity.

Lately, I use it because I do work on a “company” machine. The company policy, insofar as I can understand it, is that you’re not allowed to use any of your own custom productivity tools. I’m guessing you can ask permission, or just ignore the rules (because no one actually cares in a kind of don’t-ask-don’t-tell policy). I decided to bend-the-knee as much as possible and thus use Emacs with lots of customization. Yes, Emacs is third-party, but it doesn’t require a license, which is the real objection.

So, I use org-mode for notes, task tracking, writing first-drafts for wiki pages or email and so on. It’s good enough, though I’d prefer OmniOutliner and something that I could use on mobile. Markdown would work, but I use org-mode as an outliner more than a document format, so markdown doesn’t cut it.

Here’s a customization:

(defvar kfi/timestamp-formats
  '(("March 15, 2020 @ 9:33 PM" . "%B %-d, %Y @ %-I:%M %p")
    ("March 15, 2020"           . "%B %-d, %Y")
    ("2020-03-15T21:33:54"      . "%Y-%m-%dT%H:%M:%S")
    ("2020-03-15"               . "%Y-%m-%d")
    ("2020-03-15 09:35 PM"      . "%Y-%m-%d %I:%M %p")
    ("2020-03-15T21:39:20-0700" . "%FT%T%z"))
  "Formats for inserting a timestamp into a document.")

(defun kfi/timestamp ()
  "Choose a format, then insert a timestamp."
  (interactive)
  (if-let* ((choices (mapcar #'car kfi/timestamp-formats))
            (choice (completing-read "Format:" choices))
            (format (cdr (assoc choice kfi/timestamp-formats))))
      (insert (format-time-string format))
    (insert "<error:nil-selection>")))

When I type M-x kfi/timestamp I’m presented with a list of example date/time format options. I pick one, and the date/time is inserted into the text. Although I haven’t, I could assign a key binding to the function, and a nice improvement would be to remember the last format I used and supply that as the first choice, or as a second function. I’d like to add some additional time-only (no date) formats, but, eh. I just insert something close, then edit.

Now, here’s the thing. Why not use VSCode? It’s a nice, graphical editor, it’s modern, it has tabs and file-tree sidebars and the notion of a project, all the add-on packages you could want including socket REPL connections.

One reason might be because there’s just too much chrome. But you can get rid of sidebars and tab-bars and scroll-bars and use a command to search for and load files within a project. You can kind of turn VSCode into something as visually simple as Emacs, but get an arguably better integration with language interpreters, completion modes and debuggers than you’d get with Emacs (at least out of the box). So, why don’t I switch to it?

I don’t know. I’ve used it, and it’s fine. I used it to work on a Python project and it provided all the completion hints I could want, the suggestions based on code-format-enforcers and all the goodies. (Same with working on a React-based web application.) But when I went back to Emacs and installed the similar tools on that platform, it was, somehow better. Just … better. Editing felt faster, somehow: as in moving the cursor around.

But it wasn’t that much better.

I think what’s the most fun about Emacs is that you can write dumb little functions like the timestamp-inserter above. It’s just a function in a config file: it’s not part of a package, doesn’t require you to learn a giant object hierarchy, or master much of anything beyond simple programming and a knack for searching documentation or the web. After cut/pasting other peoples’ modifications into your own config file, you start to see familiar patterns and eventually you know how to look things up. How do you present a menu and select from it? Ah! completing-read. Just pass in the choices and the system does the rest. It’s just a function.

I suspect you can’t just make random commands like this in VSCode, but I don’t really know that for sure. If you can’t, it makes sense: you maybe want the editor to be a shared experience for all users, with conventional ways of doing things. I’ll have to go find out. Even if I could make an insert-a-timestamp-here function outside of a package, I still won’t switch to it given a choice. Emacs has got that gravity.