Category Archives: pimpmyemacs

Pimp My Emacs

Along the lines of TV shows like Pimp My Ride, I’m thinking of
regularly blogging something along the lines of Pimp My Emacs. For
those readers who haven’t had to listen to me bubble for hours on end
about this text editor / way of life, Emacs is ostensibly a program
that you use to edit text files. Right. But because it’s insanely
programmable, there are all sorts of interesting things for it, like
more than five ways to read one’s e-mail.

Watch for it on Technorati with tags emacs or pimpmyemacs, or
subscribe to . =)

On Technorati: ,

Emacs: Automating the insertion of text

As the VP Education of Toast I.T. Toastmasters in downtown Toronto, I’m responsible for assigning people roles in upcoming meetings and confirming these roles by e-mail. We currently do our scheduling in a spreadsheet. Copying and pasting the roles for the spreadsheet results in the following text:

Ari Caylakyan
Anthony D'Costa
Chris Charabaruk
Michael Chan
Chris Charabaruk
Chris Charabaruk
Khalid Ghaffar
Natasha Guigova

Ari Caylakyan - C&L 5
Anthony D'Costa
Jackie Achonu
Sacha Chua

Adding role descriptions to this was a bit of a pain, so I wrote a
short Emacs Lisp function that inserted descriptions if and only if
there was a corresponding person assigned to that role.

(defun sacha/toast-add-roles ()
  "Add role descriptions."
  (mapcar (lambda (item)
            (goto-char (line-beginning-position))
            (unless (looking-at "^[ \t]*$")
              (insert item ": "))
            (forward-line 1))
          '("President" "Toastmaster" "Sgt at Arms" "Timekeeper" "Ah-counter"
            "Grammarian" "Table-topics Master" "General Evaluator" ""
            "Educational Speaker" "Guest Speaker"
            "Speaker #1" "Evaluator #1"
            "Speaker #2" "Evaluator #2"
            "Speaker #3" "Evaluator #3")))

Next step: Personalized e-mail that highlights upcoming roles, just as
I wrote Emacs Lisp functions to make it easier to send students
personalized feedback on their programs.

That’s one of the coolest things about Emacs – it’s so easy to automate tasks.

On Technorati: ,

Emacs hacks: Snail mail surprise

I like sending snail mail. This Emacs Lisp snippet displays all the
contacts for whom I have addresses, sorted according to country. This
makes it easy for me to, say, jump to all the USA contacts whom I
should mail before heading back over the border.

(defun sacha/bbdb-filter-records-for-address (records)
  "Filter records for addresses."
   (delq nil
          (lambda (rec) (and (bbdb-record-addresses rec) rec))
   (lambda (a b)
     (string< (bbdb-address-country (car (bbdb-record-addresses a)))
              (bbdb-address-country (car (bbdb-record-addresses b)))))))

;; Do the actual work here
(bbdb-display-records (sacha/bbdb-filter-records-for-address (bbdb-records)))

On Technorati: ,

Emacs: Keep track of messages sent

Because a Big Brother Database of my contacts isn’t complete if I
don’t keep track of what e-mail I sent them and when I sent it, this
bit of Emacs Lisp code adds Gnus subjects to the BBDB records of the
people to whom I sent e-mail.

(defun sacha/gnus-add-subject-to-bbdb-record ()
  "Add datestamped subject note for each person this message has been sent to."
  (let* ((subject (concat (planner-today)
                          ": E-mail: " (message-fetch-field "Subject") "\n"))
          (list (assoc 'recipients bbdb-get-addresses-headers)))
    (setq records
           (bbdb-get-addresses nil gnus-ignored-from-addresses 'gnus-fetch-field)
           nil nil))
    (mapc (lambda (rec)
            (bbdb-record-set-notes rec
                                   (concat subject
                                           (bbdb-record-notes rec))))
(add-hook 'message-send-hook 'sacha/gnus-add-subject-to-bbdb-record)

It should be really easy to set up Gnus to expand some kind of
!followup macro into a TODO item in my planner and an “I hope to hear
from you by ….”. Ridiculously easy with Emacs Lisp and an insanely
customizable editor, but I might not have enough battery life. I’ve
got 28 minutes, and then I’m off PC for a while.

On Technorati: , , , ,


More Emacs coolness: List of contacts

This bit of Emacs Lisp code produces a Planner-ready list of the contacts displayed in the BBDB window.

(defun sacha/planner-bbdb-annotation-from-bbdb (&optional record)
  "If called from a bbdb buffer, return an annotation.
Suitable for use in `planner-annotation-functions'."
  (when (or record (eq major-mode 'bbdb-mode))
    (setq record (if record (car record) (bbdb-current-record)))
    (or (bbdb-record-getprop record 'plan)
        ;; From a BBDB entry with a plan page; use that. Yay!
         (concat "bbdb://"
                    " " "." (bbdb-record-name record)))
         (bbdb-record-name record)))))
(defalias 'planner-bbdb-annotation-from-bbdb 'sacha/planner-bbdb-annotation-from-bbdb)

(defun sacha/yank-planner-bbdb-list ()
  "Copy the list of people displayed in the buffer."
   (mapconcat 'sacha/planner-bbdb-annotation-from-bbdb
              ", "))
        (sacha/planner-bbdb-annotation-from-bbdb rec))

It allows me to say, for example, that I met 23 people yesterday:
Bruce, Daniel Charles, Shane D’Costa, Emily, Greg A. Fitz, Clara Fong, Jay Goldman, Harvey, Kai Fai Ho, Iris, KC, Charles McCulloch, Jamie McQuay, Joshua Meles, Naomi, Helen Overland, W- Penney, Simon Rowland, San, Colin Smillie, Solomon, Le Quan Truong, Perry Wong

On Technorati: , , , ,

More Emacs fun: Composing mail to everyone with notes

(defun sacha/compose-mail-to-everyone (&optional subject)
  (mapc (lambda (rec)
          (setq rec (car rec))
          (when (bbdb-record-net rec)
            (bbdb-send-mail rec subject)
              (forward-line -2)
              (insert "\n---- NOTES ---\n" (bbdb-record-notes rec) "\n"))))

(defun sacha/gnus-delete-notes ()
  (goto-char (point-min))
  (when (re-search-forward "^--- NOTES ---" nil t)
    (goto-char (match-beginning 0))
(add-hook 'message-send-hook 'sacha/gnus-delete-notes)

On Technorati: , , , , ,