Showing posts with label emacs-lisp. Show all posts
Showing posts with label emacs-lisp. Show all posts

Wednesday, February 6, 2013

Configuring emacs to send iCloud mail on Mac OS X

Pic from ajc1 on Flikr
It's handy to be able to send emails from emacs, and this guide will show how to set up SMTP via an iCloud email account.

Step 1. Install gnutls

iCloud requires you to send emails over secure channel, and emacs supports sending email with starttls or gnutls. gnutls is available through brew

To install it is easy:

brew install gnutls

Wait a few minutes while your Mac gets hot downloading and compiling!

Step 2. Create an authinfo file

emacs can look in a file ~/.authinfo to find your login credentials, so create that file and fill in the blanks.

touch ~/.authinfo
chmod 600 ~/.authinfo

The contents of the file should read:

machine smtp.mail.me.com port 587 login YOURNAME@icloud.com password YOURPASSWORD
Step 3. Configure emacs

Add the following to your .emacs file:


(setq
 send-mail-function 'smtpmail-send-it
 message-send-mail-function 'smtpmail-send-it
 user-mail-address "YOURNAME@icloud.com"
 user-full-name "YOUR FULLNAME"
 smtpmail-starttls-credentials '(("smtp.mail.me.com" 587 nil nil))
 smtpmail-auth-credentials  (expand-file-name "~/.authinfo")
 smtpmail-default-smtp-server "smtp.mail.me.com"
 smtpmail-smtp-server "smtp.mail.me.com"
 smtpmail-smtp-service 587
 smtpmail-debug-info t
 starttls-extra-arguments nil
 starttls-gnutls-program (executable-find "gnutls-cli")
 smtpmail-warn-about-unknown-extensions t
 starttls-use-gnutls t)

Note that your gnutls program may be in a different spot. Find it with:

mdfind -name gnutls-cli 
Step 4. Testing

To compose an email C-x m

Enter an email and hit C-c c to send it.

If it works, great! If not switch to the *Messages* buffer for hints on what may have gone wrong.

Step 5. Sending emails from elisp code



(message-mail recipient subject)
(message-send-and-exit)))))


Monday, December 26, 2011

Making a emacs lisp expression expand itself to XML

My response to the blog article An Emacs Programming Challenge

The goal is to make the emacs lisp record below execute itself and produce XML. My lisp has gotten rusty so it took me a couple of hours to get this working, but I think I got there...

You can see it properly formatted and coloured here

It's fairly straightforward. The only complexity is the use of lexical-let. emacs lisp is dynamically scoped, so in the function I create for each keyword, where it prints the symbol name is a free variable at runtime. So if sym-name is not defined you'll get an error, otherwise you'll get whatever it is defined as instead of the value you wanted.

By using lexical-let any variables are bound lexically, that is stored in an environment that stays with the function we create when it is executed (a closure).
(require 'cl) ;; uses lexical-let

(defun make-xml-izer(name)
"Given a symbol NAME this makes a function that outputs an xml string for that
symbol and using fset binds it to the same symbol so it becomes executable.
This pollutes the global function namespace so be careful with which names you
pass in"
(lexical-let ((sym-name name))
(fset (intern name)
(lambda(&rest input)
"returns a string representing the xml encoding of the input sexp"
(let ((res (format "<%s>" sym-name)))
(dolist (item input)
(if (listp item)
(setf res (concat res (eval item)))
(setf res (format "%s%s" res item))))
(setf res (format "%s" res sym-name))
res)))))

;; executing this makes all the symbols in the list below executable
(mapcar (lambda(s)
(make-xml-izer
(symbol-name s)))
'(record date millis sequence logger level class method thread emessage exception frame line))

;; the sample record
(record
(date "2005-02-21T18:57:39")
(millis 1109041059800)
(sequence 1)
(logger nil)
(level 'SEVERE)
(class "java.util.logging.LogManager$RootLogger")
(method 'log)
(thread 10)
(emessage "A very very bad thing has happened!")
(exception
(emessage "java.lang.Exception")
(frame
(class "logtest")
(method 'main)
(line 30))))

Tuesday, June 14, 2011

Emacs progress indication

When programming in emacs lisp, there is an easy way to show progress feedback to the user when a task will take some time. Here's a block of code from the elisp manual showing how to do it.

(let ((progress-reporter
(make-progress-reporter "Collecting mana for Emacs..."
0 500)))
(dotimes (k 500)
(sit-for 0.01)
(progress-reporter-update progress-reporter k))
(progress-reporter-done progress-reporter))

I've incorporated this into my duplicate files code, linked below...

http://code.google.com/p/justinhj-emacs-utils/source/browse/trunk/duplicates.el


Wednesday, June 1, 2011

Finding duplicate files in a dired buffer



picture by Donald MacLeod

This is a an example of programming emacs in emacs-lisp just to give an idea of what you can put together in an hour or two. I was looking at a dired buffer with a bunch of photos in, and some were the same photo that I'd downloaded twice. So I started thinking about writing a utility in emacs to automatically find and remove the duplicate files. In this post I'll just show the code for finding the files and display their filenames in a buffer.

I've put the source on google code.

After downloading you can load the source into emacs and call `eval-buffer', then open up a dired buffer to try it out. For this to be useful you need some duplicated files, so make some if you need to.

Mark the files you want to check for duplicates. For example to mark all jpg files you would type %m to mark files matching a regexp and type .*\.jpg

Now execute the command `dired-show-marked-duplicate-files' and after a short delay (in my test 80 jpg photos took about 5 seconds) you'll see a buffer called 'Duplicated files' which contains a list of the files which have the same contents.

Next steps for this little project will be to give you an interactive way to delete the duplicated files. I haven't decided quite how I'd like that to work, drop me an email if you have an idea. I've been thinking about perhaps resetting which files are marked so that only the duplicates are marked. At that point you can then hit R to move them to another spot, or delete them with x.

Now some comments about the code involved...

Most of the work is done in the function dired-show-marked-duplicate-files. First line " (interactive)" makes it an interactive function, meaning the user of emacs can invoke it.

"(if (eq major-mode 'dired-mode)" will check that we're in the right kind of buffer, because it makes no sense to run this in another mode.

In order to find the duplicate files I just need to walk the list of marked files, generate the md5 value of the contents of each one and add it to hash table. The keys in the hash table will be the md5, and the values will be a list of files with that md5. Once we've done that, finding duplicates is a simple matter of walking the hash table keys and displaying any where the value has multiple entries.

"(let ((md5-map (make-hash-table :test 'equal :size 40)))" Creates the hash table, making sure we use 'equal to match our filenames.

"(let ((filenames (dired-get-marked-files)))" this gets the marked files as a list of filenames

The next little bit of code is just to store the item in the hash table after getting the md5. There's no function in emacs to get the md5 of a file, but you can get the md5 of a string, so I wrote a helper function for getting the contents of a file into a temporary buffer first.

(defun md5-file(filename)
"Open FILENAME, load it into a buffer and generate the md5 of its contents"
(interactive "f")
(with-temp-buffer
(insert-file-contents filename)
(md5 (current-buffer))))

Finally I want to display the results, so I create a buffer and then use maphash (walks the keys of a hash table executing a function on each) with a helper function `show-duplicate' which simply writes the values of the hash table entry into that buffer.

Wednesday, August 26, 2009

Simple budget forecasts in emacs

Money

When I first moved from England to North America one of the things I found hard to get used to was getting paid every two weeks instead of monthly. This means that some of your bills are monthly, some are biweekly, and occasionally I had more or less money than I expected as they got out of sync.

I've been using a simple elisp program I wrote to let you manage your upcoming bills, weekly budget items like groceries, and your regular income. It runs through a period of dates you supply, and a list of incomes and expenses, and produces a csv file and a buffer that contains the output of the forecast. It shows the highest and lowest balance of the period too, so you can spot if you will go over drawn, and also see peaks when it's a good time to move money to savings.

The code is hosted on google code as emacs-easy-budget and is also released as GPL v3. Hope somebody finds it useful.