This is a ruby-based back-end for The Little Brother’s Database (lbdb) that looks at a hard-coded org-contacts file. The idea comes from a 2011 Perl implementation by Karl Voit. Because I am not a Perl person, when it didn’t work out of the box I converted it to Ruby.

And because I’ve chosen to treat org-contacts as TODO items for purposes of remembering who to PING, FOLLOWUP, SKED, etc. it has to take the extra step of stripping those keywords from the returned name. Otherwise, my mails to Joe Grudd would be addressed to FOLLOWUP Joe Grudd.

That’s a small bit of inelegance in my plaintext CRM setup: As I’ve figured out more about how org-super-agenda works, I’ve had glimpses of how the plaintext CRM metadata could just be content in the :PROPERTIES: drawer, and hence invisible for purposes of tools like this, but a few other pieces of passive automation would have to become some sort of org-mode hook and I’d lose the utility of tools like Beorg, which can’t provide the automation of native Emacs.

For now, it’s one of those “this design isn’t the cleanest, but it’s simple and only creates a few easily solved problems” things.

Here’s the script itself. I put it in ~/bin as orgcontact.rb:

#!/usr/bin/env ruby

# Get the query string
query = ARGV[0]

# Set the path to your Org-contacts file
orgmodefile = "#{ENV['HOME']}/org/"

# Read in the whole contact file
raw_contacts ="\n** ")

# Iterate through each contact
raw_contacts.each do |contact|
  if contact.match?(/#{query}/i)
    # Extract the name and email from the contact
    name = contact[/^[^\n]*/].gsub(/(PING|INVITE|WRITE|PINGED|FOLLOWUP|SKED|NOTES|SCHEDULED|TIMEOUT|OK)\s+/i, "").strip
    email = contact[/:EMAIL:\s+(.*)$/, 1]
    # Remove tags from the name
    name.gsub!(/:\S+:/, '')
    puts "#{email}\t#{name}\t(org-contacts)" if name && email

Adding m_org_contacts to the METHODS setting then including a little wrapper in ~/.lbdbrc doesn’t follow the canonical advice on how to configure an lbdb backend, but it works, and it’s one less file to put somewhere:

METHODS="m_osx_addressbook m_org_contacts"

m_org_contacts_query() {
   ~/bin/orgcontact.rb "$1"

So, the outcome is just:

  1. Start a new message in mutt and start typing the name/address/etc.

  2. lbdb provides a list of matches from a few sources I’ve set up: org-contacts and macOS address book

  3. ENTER to select a candidate