abhi's logbook

Adventures in coding and coding for adventures.

Introduction

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.

Commands

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."
  (interactive)
  (yank)
  (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

Mew

(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)
    (define-mail-user-agent
      'mew-user-agent
      'mew-user-agent-compose
      'mew-draft-send-message
      'mew-draft-kill
      'mew-send-hook))

(setq mew-config-alist
      '(("default"
         ("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)

VM

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
      smtpmail-starttls-credentials
      '(("smtp.gmail.com" 587 nil nil))
      smtpmail-auth-credentials
      (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

;; bbdb
(add-to-list 'load-path "~/.emacs.d/plugins/bbdb/lisp")
(require 'bbdb)
(require 'bbdb-gnus)
(bbdb-initialize 'gnus 'message)
(bbdb-insinuate-gnus)
(bbdb-insinuate-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.

(mapcar
 '(lambda (x)
    (bbdb-create-internal (first x) nil nil nil (second x)))
    (mapcar
     '(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)
         (do-applescript
          (concat
           "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-")
                            (replace-regexp-in-string
                             " " "-" (downcase
                                      (replace-regexp-in-string
                                       "[^A-Za-z0-9 ]" "" title)))
                            ".org")))
    (find-file draft-file)
    (insert (format
             (concat "#+BEGIN_HTML\n"
                     "---\n"
                     "layout: post\n"
                     "title: %s\n"
                     "---\n"
                     "#+END_HTML\n"
                     "\n") title))))

NewsTicker

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)
  (interactive)
  (shell-command-on-region start end
   (format "lynx -force_html -dump -stdin %s" url)
   (current-buffer)))

(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)))))
    (url-retrieve-synchronously
     "http://boxcar.io/devices/providers/8SF0X9Diup0m0cK1QmzZ/notifications")))


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

Cron

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")
    (run-at-time
     "10:00AM"
     3600
     '(lambda ()
        (start-process
         "space-photo-download"
         "*Space Photo Download*"
         "sh" (concat
               (getenv "HOME")
               "/Dropbox/Sites/abhiyerra.com/scripts/download_space_photo.sh")))))