abhi's logbook

Adventures in coding and coding for adventures.


I converted to Emacs at the end of 2010 when I joined my first real engineering job after completing college.

Emacs is not really an “editor” per se. It is a Lisp Machine posing as an editor. Considering its origins at the MIT AI Labs and Richard Stallman’s involvement the legacy can be seen in the way it functions.

Most text editors bring you down to the way they want to function based on what the original authors had in mind. There might be flexiblity but it is more than likely that it is difficult to modify the builtin structures to behave the way you want.

Emacs makes the distinction in that anything is customizable. There is a thin layer of C code which basically just runs the Emacs Lisp.

I won’t recommend fully jumping into Emacs (i.e using ERC, Gnus and all) start off small. Some of tools do show their age and certain things are just plain painful to use because Emacs is single threaded. I say start using org-mode and go from there.

Also, learn something new everyday, learn Emacs Lisp and add small custom functionality. As an engineer you spend most of your time in your editor so might as well make it behave to your command.


Keystroke Description
M-x align-regexp Select a region and pick a regex and it'll align based on that.
M-SPC Removes space around block of text and replace it with one space.
M-^ Join two lines removes spaces around it.
M-q fill-paragraph. Splits the columns into correct fill-column size.
M-t transpose two words
C-x ENT f Pick the correct encoding. I.e. unix removes ^M ^J ^L
C-x 4 a If you are in a ChangeLog file. This creates a new changelog item.
C-S-[Backspace] Kills the current line.
C-s C-w Search for the word at mark. Can keep adding C-w to add more words.
M-x flush-lines RET ^$ RET Remove blank lines

Paste and Indent

This allows you to paste and automatically indent the region correctly.

(defun yank-and-indent ()
  "Yank and then indent the newly formed region according to mode."
  (call-interactively 'indent-region))
(global-set-key "\C-y" 'yank-and-indent)

Export org-mode file as a Batch Job

emacs --batch --eval "(setq org-export-headline-levels 6)" --visit=schedule.org --execute "(org-export-as-html nil nil nil nil t)"

Emacs Email


(add-to-list 'load-path "~/Dropbox/Mew")
(autoload 'mew "mew" nil t)
(autoload 'mew-send "mew" nil t)

;; Optional setup (Read Mail menu for Emacs 21):
(if (boundp 'read-mail-command)
    (setq read-mail-command 'mew))
;; Optional setup (e.g. C-xm for sending a message):
(autoload 'mew-user-agent-compose "mew" nil t)
(if (boundp 'mail-user-agent)
    (setq mail-user-agent 'mew-user-agent))
(if (fboundp 'define-mail-user-agent)

(setq mew-config-alist
         ("mailbox-type" . imap)
         ("proto" . "%")
         ("imap-server" . "imap.gmail.com")
         ("imap-ssl" . t)
         ("imap-user" . "[email protected]") ;; to be completed
         ("prog-ssl" . "/use/local/bin/stunnel")
         ("user" . "ykabhinav")
         ("mail-domain" . "gmail.com")
         ("name" . "Abhi Yerra")
         ("imap-delete" . nil)
         ("imap-size" . 0)
         ("smtp-ssl"    . t)
         ("smtp-ssl-port". "465")
         ("smtp-auth-list" . ("PLAIN" "LOGIN" "CRAM-MD5"))
         ("smtp-user"   . "[email protected]")
         ("smtp-server" . "smtp.gmail.com")
         ("inbox-folder" . "%INBOX")
         ("imap-friend-folder" . "%from")
         ("imap-trash-folder" . "%[Gmail]/All Mail"))))

(setq mew-use-unread-mark t)
(setq mew-delete-unread-mark-by-mark nil)


Make sure that you have stunnel 4.33 or lower for the trunk version of VM.

(add-to-list 'load-path "~/Dropbox/vm/lisp")
(require 'vm-autoloads)

(setq mail-user-agent 'vm-user-agent)

(setq vm-folder-directory "~/Mail")
(setq vm-primary-inbox "~/Mail/vminbox")
(setq vm-crash-box "~/Mail/inbox.crash.mbox")

(setq vm-imap-expunge-after-retrieving nil)

(setq vm-mutable-frames nil)
(setq vm-imap-account-alist
      '(("imap-ssl:imap.gmail.com:993:login:[email protected]:*" "gmail")))

(setq vm-primary-inbox "imap-ssl:imap.gmail.com:993:inbox:login:[email protected]:*")

(setq vm-debug t)
(setq vm-keep-imap-buffers t)
(setq vm-imap-log-sessions t)

(setq vm-use-menus 1)
(setq vm-stunnel-program "stunnel")

(setq send-mail-function 'smtpmail-send-it
      message-send-mail-function 'smtpmail-send-it
      '(("smtp.gmail.com" 587 nil nil))
      (expand-file-name "~/.authinfo")
      smtpmail-default-smtp-server "smtp.gmail.com"
      smtpmail-smtp-server "smtp.gmail.com"
      smtpmail-smtp-service 587
      smtpmail-debug-info t)
(require 'smtpmail)

(setq mail-default-headers "From: Abhi Yerra <[email protected]>\n")

(setq  vm-mime-type-converter-alist
      '(("text/html" "text/plain" "elinks -dump /dev/stdin")
        ("message/delivery-status"  "text/plain")
        ("application/zip"  "text/plain" "listzip")
        ("application/x-zip-compressed"  "text/plain" "zipinfo /dev/stdin")
        ("application/x-www-form-urlencoded"  "text/plain")
        ("message/disposition-notification"  "text/plain")
        ("application/mac-binhex40" "application/octet-stream" "hexbin -s")))

(define-key vm-mode-map "#" 'vm-imap-synchronize)


;; bbdb
(add-to-list 'load-path "~/.emacs.d/plugins/bbdb/lisp")
(require 'bbdb)
(require 'bbdb-gnus)
(bbdb-initialize 'gnus 'message)
(add-hook 'gnus-startup-hook 'bbdb-insinuate-gnus)
(setq bbdb-send-mail-style 'gnus)
(setq bbdb-complete-name-full-completion t)
(setq bbdb-completion-type 'primary-or-name)
(setq bbdb-complete-name-allow-cycling t)

Syncing with Google Contacts

At this point I’d recommend just using google-contacts.el. When I first wrote this script the elisp script didn’t exist so I didn’t use it. I think at this point this is obsolete code.

I store my contacts in Google because I love their sync service and I use it with my iPhone all the time. Makes managing contacts quite easy. I wanted my BBDB contacts to be synced. I discovered googlecl which is a nifty command line way to access many Google services.

This allowed me to update my records.

 '(lambda (x)
    (bbdb-create-internal (first x) nil nil nil (second x)))
     '(lambda (x) (split-string x ","))
     (process-lines "/usr/local/bin/google" "contacts" "list" "name,email")))

Placing a Call via Skype (on Mac)

BBDB 3.0 has an updated function called bbdb-dial-number. You can use this to make calls using Skype on the Mac by interfacing with AppleScript.

(setq bbdb-dial-function
      '(lambda (phone-number)
           "tell application \"Skype\"\n"
           "send command \"CALL +" phone-number "\" script name \"Call from BBDB\"\n"
           "end tell"))))

Post to Jekyll

; Jekyll move to org-capture binding.
(defun new-blog-post (title)
  "Create a new Jekyll blog post."
  (interactive "sPost Title: ")
  (let ((draft-file (concat "~/Dropbox/docs/blogfiles/"
                            (format-time-string "%Y-%m-%d-")
                             " " "-" (downcase
                                       "[^A-Za-z0-9 ]" "" title)))
    (find-file draft-file)
    (insert (format
             (concat "#+BEGIN_HTML\n"
                     "layout: post\n"
                     "title: %s\n"
                     "\n") title))))


The three choices for NewsTicker w3, w3m, htmlr are mostly crappy in the way they output html or don’t work with Emacs 23. A better alternative is to output it using Lynx. Here is how to set up NewsTicker to use Lynx to render the item buffer.

(defun lynx-renderer (start end &optional url charset)
  (shell-command-on-region start end
   (format "lynx -force_html -dump -stdin %s" url)

(setq newsticker-html-renderer 'lynx-renderer)

Send Messages to Boxcar

I was bored and wanted to send something to my phone from emacs so I wrote this. This sends a message to Boxcar. This can also likely modifed to work with the Twilio API.

(defun send-region-to-boxcar (start end)
  (interactive "r")
  (let ((url-request-method "POST")
        (url-request-extra-headers `(("Content-Type" . "application/x-www-form-urlencoded")))

        (url-request-data (concat "email=INSERT_MD5_OF_EMAIL&Body=123" "&"
                                  "notification[from_screen_name]=c0rnbot" "&"
                                  "notification[message]=" (url-hexify-string (buffer-substring start end)))))

(global-set-key "\C-ct" 'send-region-to-boxcar)


If you want to include a cron task in your Emas this is the format to do it.

Here we check if a folder exists. Then we run a task at 10 am conintuing at 30 minute intervals.

(if (file-exists-p "~/Dropbox/Public/Space")
     '(lambda ()
         "*Space Photo Download*"
         "sh" (concat
               (getenv "HOME")