Category Archives: hack

Livening up your laptop lid: self-adhesive reusable surface

All you need to transform your laptop lid into a reusable surface where you can display your latest doodles are: one photo album with self-adhesive pages, a knife, and double-sided tape. Get a photo album that uses plastic and a sticky(ish) surface. Life is easier and neater if the strip that keeps the plastic attached to the book is on the outside edge. You'll see what I mean.

Step 1. Position the laptop face-down on one page of the photo album so that the strip that keeps the plastic attached to the book is along the top edge of the laptop lid. Trace laptop outline onto one page of the photo album. (If you feel particularly diligent, you can measure it instead.)

Step 2. Cut the photo album page to size. Trim a bit off the bottom part to avoid hitting the laptop hinge.

Step 3. Attach double-sided adhesive tape to the laptop.

Step 4. Mount photo album piece on laptop.

Step 5. Peel back plastic and put in stuff.

I like this approach because it doesn't require me to bring any special supplies in order to add to the display. For example, I can add fortunes from fortune cookies, Post-it notes, or even business cards.

This is handy for my wild idea about selling advertising on laptop. This laptop hack's primarily about creatively expressing yourself, though. =)

Good stuff.

I came up with a terrific plan B: a whiteboard with a plastic protector to keep it from being erased in one's backpack. That one's pretty cool, too. I'll blog about it more on Sunday, Aug 27. In the meantime... enjoy!

On Technorati: , , , , , , , ,

digg del.icio.us 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"))
         (bbdb-get-addresses-headers
          (list (assoc 'recipients bbdb-get-addresses-headers)))
         records)
    (setq records
          (bbdb-update-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))))
            records)))
(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: , , , ,

/mnt/media/sacha/notebook/emacs/dotgnus.el

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!
        (planner-make-link
         (concat "bbdb://"
                 (planner-replace-regexp-in-string
                    " " "." (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."
  (interactive)
  (kill-new
   (mapconcat 'sacha/planner-bbdb-annotation-from-bbdb
              bbdb-records
              ", "))
        (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, Wayne 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)
            (save-excursion
              (message-goto-signature)
              (forward-line -2)
              (insert "\n---- NOTES ---\n" (bbdb-record-notes rec) "\n"))))
        bbdb-records))

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

On Technorati: , , , , ,

Emacs: Show only people whom I haven’t pinged since…

One of the things I want in a contact management system is a quick way to find out who I haven't pinged in a while. The following code filters currently-displayed contacts to show who I might want to get back in touch with. Call it from a *BBDB* window and specify the date (could be 2006.01.01 for annual, -7 for the last seven days, etc.). This works incredibly well with the following hacks:

I should write a small book about how to build a contact management system with Emacs. ;) It's insanely powerful, you know.

(require 'planner)
(require 'bbdb)
(defun sacha/bbdb-show-only-no-contact-since (date)
  "Show only people who haven't been pinged since DATE or at all."
  (interactive (list (planner-read-date)))
  (let ((records bbdb-records)
        new-records
        last-match
        omit
        notes)
    (while records
      ;; Find the latest date mentioned in the entry
      (setq notes (or (bbdb-record-notes (caar records)) ""))
      (setq last-match nil omit nil)
      (while (string-match
              "[0-9][0-9][0-9][0-9]\\.[0-9][0-9]\\.[0-9][0-9]"
              notes
              (or last-match 0))
        (unless (string> date (match-string 0 notes))
          (setq omit t)
          (setq last-match (length notes)))
        (setq last-match (match-end 0)))
      (unless (and last-match omit)
        (add-to-list 'new-records (caar records) t))
      (setq records (cdr records)))
    (bbdb-display-records new-records)))

One of the other things I'd like to smooth over is keeping track of who owes whom e-mail... <laugh>

On Technorati: , , , , , ,

Crazy Emacs: Personalized signatures with random taglines

Of course, that naturally leads to the crazy idea: "What if I can personalize my signatures?" Knowing that Paul Lussier is an Emacs geek, I can reward him for reading all the way to the bottom of my message... ;)

(defun sacha/gnus-personalize-signature ()
  "Personalizes signature based on BBDB signature field.
BBDB signature field should be a lambda expression.
First person with a custom signature field gets used."
  (let* ((bbdb-get-addresses-headers
          (list (assoc 'recipients bbdb-get-addresses-headers)))
         (records (bbdb-update-records
                   (bbdb-get-addresses
                    nil
                    gnus-ignored-from-addresses 'gnus-fetch-field)
                   nil
                   nil))
         signature)
    (while (and records (not signature))
      (when (bbdb-record-getprop (car records) 'signature)
        (setq signature
              (eval (read (bbdb-record-getprop (car records)
                                               'signature)))))
      (setq records (cdr records)))
    (or signature t)))
(setq-default message-signature 'sacha/gnus-personalize-signature)

So then all I have to do is add the following field to his record:

      signature: (concat "Sacha Chua - Emacs geek
                 What crazy idea can I help you hack next?
                 Random Emacs symbol: "
                 (sacha/random-tagline
                  "~/.taglines.random-emacs-symbols"))

Emacs. One crazy idea at a time. Now I can use this to select random information, like my favorite networking books or a list of my upcoming events...

On Technorati: , , ,

Random Emacs symbol: sort-coding-systems-predicate - Variable: If non-nil, a predicate function to sort coding systems.