2012-10-15

mu4e v0.9.9 is out!

I few months ago, I introduced mu4e, a modest little emacs mail client that I wrote. It seems many people picked it up, great!

what's new?

I have just released mu/mu4e version 0.9.9. There are quite a few changes, both user-visible and 'under-the-hood'. I've also spent some time on improving the manual (pdf), and I'm quite happy about it.

Some of the more visible new things in mu4e are:

  • Support for crypto (decrypting messages, signing them)
  • Support for refiling (like mutt, Wanderlust)
  • Dynamic folders (instead of hard-coding the sent/draft/trash/refile folder, they can be functions that return different folders based on the message we're dealing with, see the example below)
  • Same for the folder to save attachments
  • A lot of smaller and bigger UI improvements

Also, the core mu program has seen a lot of improvements (many of which directly improve mu4e as well)

  • Better support for non-ascii locales / character sets, such as ISO-2022-JP
  • Improved on-line help ('mu help ...')
  • Performance improvements for threaded display (~ 25% for 23K messages)

For a more complete list, see NEWS.

dynamic folders

As mentioned, mu4e now supports dynamic folders. Before, you'd set your trash folder to some static string:

(setq mu4e-trash-folder "/trash")

In some cases, you may want to have a bit more flexibility – for example, have a separate trash-folder (or sent-folder, drafts-folder, refile-folder) for private mail and work mail. You can now do something like:

(setq mu4e-trash-folder
  (lambda (msg)
    (if (and msg ;; msg may be nil
          (mu4e-message-contact-field-matches msg :to "me@work.com"))
      "/trash-work"
      "/trash")))

refiling

After I have dealt with some e-mail, I either delete it or move it to some archive folder – refiling. For this, there is now the r keybinding, and mu4e-refile-folder; and a place where dynamic folders really shine:

(setq mu4e-refile-folder
  (lambda (msg)
    (cond
      ;; messages to the mu mailing list go to the /mu folder
      ((mu4e-message-contact-field-matches msg :to
         "mu-discuss@googlegroups.com")
        "/mu")
      ;; messages sent directly to me go to /archive
      ;; also `mu4e-user-mail-address-regexp' can be used
      ((mu4e-message-contact-field-matches msg :to "me@example.com")
        "/private")
      ;; messages with football or soccer in the subject go to /football
      ((string-match "football\\|soccer" (or (mu4e-message-field msg :subject) ""))
        "/football")
      ;; everything else goes to /archive
      ;; important to have a catch-all at the end!
      (t "/archive"))))

How cool is that? After reading my inbox folder, I select all messages (C-x h), press r, and they're all moved to the right refiling folder.

crypto support

mu4e already supported signing/encrypting messages, but now it supports decryption and verifying signatures as well. This was one of the most requested new features. I think it is still a bit rough, but it has been working very well for me.

so…

I think version 0.9.9 is a great new step for mu4e. It already goes far beyond I ever planned to do. I received a lot of suggestions for new features, which is great! I'm not planning to implement all of those, but I will try to make mu4e even more programmable – it should be easy to augment mu4e with your own little elisp-snippets – the Barbapapa principle of software, already so clearly present in emacs itself.

2012-08-20

introducing mu4e, an e-mail client for emacs

background

I've haven't written too much here lately. This is because I have spent most of my emacs hacking time on mu4e, an emacs e-mail client. It's only slightly over six months old since its first release, but it has progressed rather quickly! So, I think it is time to give it an introduction to a wider audience. In future posts, I'll go into more detail.

E-mail is a very important means of communication for me; and for purposes of integration, it prefer to do my e-mail with emacs. For a long time, I used mutt with emacs as the editor; a few years back I switched to Wanderlust, and wrote a few articles about it.

There's a lot to like about Wanderlust: it's very featureful, and allows for a lot of customization. Still, there were a few things I was not fully happy with; the most important one was the speed of some operations; another annoyance was the fact that I got rather frequent cache-corruptions when using newer emacs versions.

So, what was I to do? Well, a few years back, I had written an e-mail indexer/searcher, called mu. It takes the messages in a maildir-folder, and allows you to query them. I wondered if I could use mu as the backend for an emacs-based e-mail client. So, I fired up emacs, started writing some code and some later I had a first version of… mu4e.

how does it work?

mu4e is an emacs front-end for mu; when you start it, mu4e connects to a mu server process (started on-demand). It accepts simple commands, and responds with emacs s-expressions, in asynchronous fashion. In practice, all the heavy work is done in this server process, and emacs shows the results when it is ready (usually almost instantly). Emacs does not need to wait for the backend, and things stay snappy, even with tens of thousands (or more) e-mail messages. The only operation that may still require some waiting is sending mail, since that uses the emacs built-in smtpmail, which blocks during its operation.

mu expects your e-mail messages to be stored in a maildir (a one-file-per-message system); you can get these mails there through tools like offlineimap or fetchmail. mu periodically indexes the messages, and stores the results in a Xapian database. A lot of what mu4e does is querying this database – so for example, what you see as 'my inbox folder' in the mu4e-frontend, is in fact just the result of a query of all message that happen to live in that folder. You can query for many things – message sender, subject, date, words in the body and more.

mu4e does not just query messages; it can also move messages between folders, delete them, modify their flags and so on (and afterwards update the database). All 'state' is in the file system, and the database is just a quick way to get to it; if you delete the database and then re-index, nothing is lost, and changes made with other tools (e.g. mutt) are picked up by mu as well.

trying mu4e

Some Linux distributions ship mu4e, but not necessarily a very recent version; and because mu4e is developing quickly, you may want to use the latest official release, or (if you are more adventurous) check out the git repository. You'll need GNU/Emacs 23 or 24, GLib, GMime >= 2.4 and Xapian.

After installing mu4e, you can check the mu4e manual, which should be fairly complete. In fact, one of the goals of mu4e is to make it easy to set up; for that reason, the documentation includes complete examples of how to set things up. The Getting started chapter should get you up to speed quickly.

So, give it a try if you're interested; the mu=/=mu4e project is very open to suggestions (and even bugs reports!), so feel free to put them here or subscribe to the mu mailing list.

a small tour

I'll end this with a number of screenshots, to give you a rough idea of how things look.

The main screen

When you start mu4e (M-x mu4e), you're taken to the main screen, which list the things you can do. The entries should speak for themselves. Note that you can define you're own bookmarks. In general, mu4e tries to make things as easy as possible, and provide auto-completions where possible.

The headers / view split-screen

The results of your queries are shown as a list of headers; if you click one of the headers, mu4e splits the screen horizontally (optionally, you can split the screen vertically, or only show the message view). You can customize the headers shown, re-order them and so on.

The message view supports html message, inline images, and has a mechanism to associate user-functions with messages and attachments (such as 'view in browser' or 'pipe through command'); see the manual for some examples.

The message composition view

Obviously, you can reply to messages, forward them, or compose a new message. For writing and sending messages, mu4e reuses emacs' built-in message-mode. There's support for auto-completing addresses (based on the e-mails you've sent/received before).

There's even (experimental) support for writing you're messages using org-mode, and then sending them as rich-text (html) messages.

parting thoughts

So, this was a short introduction to mu4e, barely scratching the surface, but hopefully conveying the main ideas. The manual discusses things in much more detail, and I'll write more about it in the future.

mu4e is still a young project, but, for what's it worth, I've been using it full-time for over six months, and a growing number of people are doing the same. So, if you're interested, give it try and let us know you think!

Have fun!

2012-08-10

file management with sunrise-commander

I tend to do a lot of file management from the shell (zsh, in my case); this is very flexible / powerful and so on. But, for some things a bit more graphical approach is nicer.

There are fully graphical file-managers like Nautilus or Thunar, but for a bit more keyboard-friendly file-management, there are so-called orthodox file managers - the archetypical Norton Commander and its descendants, like midnight-commander (mc) and gnome commander.

Not surprisingly, emacs has its own incarnation - it is called the sunrise commander and happily it's obtainable through ELPA. It's become an important of my workflow. When you're used to Midnight Commander, you'll feel right at home.

If you want to use emacs for yet another of your computer-based activities, give it a try.

2012-07-09

replace-regexp and numbering lines

I saw the Got Emacs? posting showing off the new emacs-24 rectangle-number-lines command, to number a bunch of lines in buffer, i.e..:

foo
bar
cuux

becomes:

1 foo
2 bar
3 cuux

Very cool! An alternative is to use cua-mode, mark the column for the numbers with cua-set-rectangle-mark (C-RET), and then use M-x cua-sequence-rectangle (which takes you throught the steps, and has a lot of flexibility.

But let's look at yet another way: using replace-regexp. If we select (mark) the list once more, we can do M-x replace-regexp RET ^ RET \#. RET Note that the # is a special meta-character that represents the number of replacements already made. This has the somewhat clumsy side-effect that your list be numbered, starting at 0 rather than 1, so you should add a dummy-element at the beginning. Clearly, replace-regexp is inferior for simply adding some line numbers – however, it has the flexibility to do some smarter things.

Smarter things? Yes! replace-regexp allows you to use arbitrary Lisp-expressions in the replace strings. So, let's suppose that we want to use letters instead of numbers for our lines. Easy – again, select (mark) your lines, M-x replace-regexp RET ^ RET \,(format "%c. " (+ ?a \#)) RET and we get:

a. foo
b. bar
c. cuux

Admittedly, not the most world-shattering thing, but it does show the powers hidden in something as common as replace-regexp.

2012-06-20

who holds this value?

Something from the category of useful things hiding in emacs… Suppose you are looking for the variable that holds a certain value. How to find it?

Easy: M-x apropos-value

So, for example, finding all variables that hold your e-mail address:

M-x apropos-value RET me@example.com RET

and you'll get all the matches in the *Apropos*-buffer. HT: Stephen Eglen.

Also check the various other M-x apropos-... commands, they all help you find useful information if you can remember a word. Except for… M-x apropos-zippy… eh?

2012-06-06

euro 2012 games in your org-mode agenda

Things have been rather quiet at emacs-fu - reason for this is that most of my emacs hacking time has been spent on mu4e, the emacs e-mail client I wrote. It's been shaping up pretty nicely, I should probably write some emacs-fu posts about it :)

Another interesting pastime (esp. in Europe) is football/soccer, in particular the Euro2012 games; long-time readers will remember the schedule for world cup games; I made a new one for Euro2012: https://github.com/djcb/org-euro2012.

In order to have the games show up in your agenda, make sure the file is in your org-agenda-files. If needed, you could add it with something like this in your org-mode settings (change the directory path to wherever you have put euro2012.org):

(add-to-list 'org-agenda-files "~/org/euro2012.org")

One small issue with the schedule is that it uses the central-european summer time (UTC+2), and there is no automatic way to adjust times for the local time zone. As a work-around, Juan Pechiar provided the following function which makes it easy to update all org-timestamps in a file:

(defun update-org-hours (n)
  "Change all org-mode timestamps in the current buffer by N hours."
  (interactive "nAdd hours: ")
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "[[<]" nil t)
      (when (org-at-timestamp-p t)
        (org-timestamp-change n 'hour)))))

Evaluate this function. After that, you can go to the file with the schedule, and give an M-x update-org-hours, provide the offset for your timezone, compared to UTC+2.

Let the games begin!

2012-03-16

social networking with bitlbee and erc

Instant messaging (IM) is one of the great time sinks of our age. Emacs-users, social butterflies as we are, of course want to take part in that -- preferrably from the comfort of our own environment.

There are various ways to use services like MS Live Messenger, Facebook Chat, GTalk, Yahoo etc. from within emacs – the one I use is called BitlBee. BitlBee is a program that presents all the various forms of IM as IRC-channels. In other words, while BitlBee knows all the details about communicating with these networks, all you need is an IRC-client to connect to BitlBee. This IRC-client does not have to be Emacs-based - any client can be used - but I am using ERC. Note, the below assumes you are somewhat familiar with it.

So, let's see how we can set up BitlBee on our system; there are public BitlBee-servers available online, but in the case of IM, I wouldn't necessarily want to trust them with my account data… so I'm using my own.

Setting up Bitlbee

So, how can we set this up? First, install BitlBee – many distributions have ready-made packages, otherwise you can build from source. In the examples below, I am assuming you are using Bitlbee version 3 or higher; if you use a different version, the details will vary a bit.

You can either run Bitlbee as a system-wide daemon, or just use it on your own. I am doing the former (for the latter, bitlbee.el is useful).

To connect ERC to the Bitlbee daemon, you can use something like the following:

(defun i-wanna-be-social ()
  "Connect to IM networks using bitlbee."
  (interactive)
  (erc :server "localhost" :port 6667 :nick "user"))

I'm sure you can come up with a better nick than user… Anyhow, with this function in your ~/.emacs, we can connect to bitlbee with:

M-x i-wanna-be-social RET

This should connect us to BitlBee; when all goes well, this will look something like this:

*** You have joined channel &bitlbee
*** mindcrime has changed mode for &bitlbee to +t
*** Users on &bitlbee: @user @root
*** Topic for &bitlbee: Welcome to the control channel. Type help for help
    information.
<root> Welcome to the BitlBee gateway!
<root>
<root> If you've never used BitlBee before, please do read the help
  information using the help command. Lots of FAQs are answered there.
<root> If you already have an account on this server, just use the identify
  command to identify yourself.
<root> The nick is (probably) not registered
*** &bitlbee modes: +t
<ERC>

Now, this first time, you will need to register yourself (this is only needed once); use the same nick (user in the example) that you used before:

<user> register user secretpassword
<root> Account successfully created

We're registered! This means, that bitlbee knows about you, and will save your settings.

Re-entering bitlbee

Just to complete the bitlbee-connecting part: the next time you want to use bitlbee, use i-wanna-be-social as before. However, now you need to identify yourself (rather than register):

<user> identify user secretpassword
<root> Password accepted, settings and accounts loaded

This can be automated by adding something like the following to your config:

(defun bitlbee-identify ()
  (when (and (string= "localhost" erc-session-server)
          (string= "&bitlbee" (buffer-name)))
    (erc-message "PRIVMSG" (format "%s identify user secretpassword"
                             (erc-default-target)
                             djcb-bitlbee-password))))

(add-hook 'erc-join-hook 'bitlbee-identify)

Modify user and secretpassword as desired. If you don't want write out your passwords in your emacs config files, take a look at keeping your secrets secret.

Adding accounts

Now, let's add some IM-accounts (just some examples here; also see Bitlbee Quickstart. Note, add any point during this, you can see your accounts with the command:

<user> account list

and using the numbers (or the accounts 'tag') you can switch an account on (and off):

<user> account 0 on

There are many other commands – use help command the consult the built-in documentation.

Connecting to IM networks

To connect to IM networks, you have to add the accounts to BitlBee. It will save them, so you only need to do that once. Let's do it - in each case, replace user and password with whatever you use for those.

You can see your combined logged-in buddy list using M-x erc-channel-names (or C-c C-n). Or use the blist command (see help blist).

After adding an account, it's a good idea to issue the save command, to ensure that bitlbee saves it.

Jabber

<user> account add jabber foobar@jabber.org mypassword
<root> Account successfully added with tag jabber
<user> account jabber on
<root> jabber - Logging in: Connecting
<root> jabber - Logging in: Connected to server, logging in
<root> jabber - Logging in: Converting stream to TLS
<root> jabber - Logging in: Connected to server, logging in
<root> jabber - Logging in: Authentication finished
<root> jabber - Logging in: Authenticated, requesting buddy list
<root> jabber - Logging in: Logged in

(and of course, you can use other servers beside jabber.org)

GoogleTalk

GoogleTalk (gtalk) is implemented using XMPP (jabber), and it's recommended to use oauth for authentication. Note, the foobar below is just a placeholder (for a password); bitlbee wants us to put something there, but since we'll be using oauth, it's not actually used.

<user> account add jabber myaccount@gmail.com foobar
<root> Account successfully added with tag gtalk
<user> account gtalk set oauth on
<root> oauth = `on'
<user> account gtalk set nick_source full_name
<root> nick_source = `full_name'
<user> account gtalk on
<root> gtalk - Logging in: Starting OAuth authentication

Now, a second window will open with a URL:

<jabber_oauth> Open this URL in your browser to authenticate:
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.\
com/auth/googletalk&response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob&client_i\
d=78312399893489.apps.googleusercontent.com

<jabber_oauth> Respond to this message with the returned authorization
token.

Follow this URL in your browser, and it will take you to some Google page for authentication. When that is completed, you will receive some string cookie, which you paste back into the newly opened window.

<user> 4/sIns904fdlkP5nudjCF4mBHF7Go_-E0g8
*** jabber_oauth is AWAY: Offline

Et voilà! We're connected to Gtalk (don't worry about the Offline-warning).

Facebook

Apart from being a social website, Facebook can also be used for IM. You can do this through the website, or you can use its jabber interface. It works very similar to gtalk; only important thing is that you get yourself a Facebook username:

<user> account add jabber myusername0@chat.facebook.com
<root> Account successfully added with tag fb
<root> You can now use the /OPER command to enter the password
<root> Alternatively, enable OAuth if the account supports it: account
  fb set oauth on
<user> account fb set oauth on
<root> oauth = `on'
<user> account gtalk set nick_source full_name
<root> nick_source = `full_name'
<user> account fb on
<root> fb - Logging in: Starting OAuth authentication

Then, go through the oath-authentication steps (see the discussion about adding Gtalk accounts above).

Once authenticated, you'll get something like this:

<root> fb - Logging in: Requesting OAuth access token
<root> fb - Logging in: Connecting
<root> fb - Logging in: Connected to server, logging in
<root> fb - Logging in: Converting stream to TLS
<root> fb - Logging in: Connected to server, logging in
<root> fb - Logging in: Authentication finished
<root> fb - Logging in: Server claims your JID is
  `-748234518@chat.facebook.com' instead of
  `myusername0@chat.facebook.com'. This mismatch may cause problems with
  groupchats and possibly other things.
<root> fb - Logging in: Authenticated, requesting buddy list
<root> fb - Logging in: Logged in

It's to now act upon the warning, so, we log out, change the user name and long back in:

<user> account fb off
<root> fb - Signing off..
<user> account fb set username -748234518@chat.facebook.com
<root> username = `-748234518@chat.facebook.com'
<user> account fb on

MSN / Live Messenger

MSN uses its own protocol (although apparently they're also supporting XMPP ("jabber") now). Suppose you have an account there, user partygirl89@hotmail.com with password iamcute:

<user> account add msn partygirl89@hotmail.com iamcute
<root> Account successfully added
<user> account msn on
<root> msn - Logging in: Connecting
<root> msn - Logging in: Connected to server, waiting for reply
<root> msn - Logging in: Transferring to other server
<root> msn - Logging in: Connected to server, waiting for reply
<root> msn - Logging in: Authenticated, getting buddy list
<root> msn - Login error: Error reported by MSN server: Invalid
       (non-existent) handle                                      [12:17]
<root> msn - Logging in: Logged in

The 'Error reported' does not seem to matter.

Other accounts

It's similarly easy to setup Twitter-accounts and Identi.ca-accounts; I've stopped using those though, as it turned out to be a little too easy for some typing in the wrong window to end op as a tweet… The risk is less with twittering-mode and identica-mode.

For ICQ/Yahoo/AIM see below – replace the username/password with your own.

  • ICQ
    <user> account add oscar ICQ-ID PASSWORD login.icq.com
    <root> ...
    
  • AIM
    <user> account add oscar AIM-NICK PASSWORD login.aol.oscar.com
    <root> ...
    
  • Yahoo!
    <user> account add yahoo YAHOO-NICK PASSWORD
    <root> ...
    

    And I'm not even talking about combining bitlbee and Skype – yes, that is possible, too.

Chatting

Now, chatting is easy, following the normal ERC conventions (and settings). When people talk to you, a window opens (or a frame – see erc-auto-query. And you can initiate conversations with people by using /msg nick, with nick of course being the nickname of the person you want to talk to.

ERC/Bitlbee also work together nicely with Sauron, the emacs event tracker.

Have fun! I have only scratched the surface here - you now have the full arsenal of Elisp and ERC power available for your chatting.

2012-02-10

special characters

Special characters

Living in a post-ASCII world offers great opportunities, but brings some problems, too. After all, it's nice to be able to write Ångström or Καλημέρα or ☺☎☯, but it's not necessarily easy to enter those characters.

input methods

So - what to do? First, you can set the input-method, as explained in the emacs manual. This is the best solution if you're writing a non-Latin language – Russian, Thai, Japanese, …

If you only occasionally need some accented character, input methods like latin-postfix (e" -> ë), latin-prefix ("e -> ë) or TeX (\"e -> ë) are useful. They also tend to annoy me a bit, as they often assume I need an accented character, when all I want is to put a word in quotation marks…

compose key

Another method is to use a special compose key; for example, under Gnome 3 it's in the the Region and Language applet, under Options..., in Gnome 2 it's in the Keyboard applet in Layouts/Options…. This works for all programs, not just emacs (see this Ubuntu help page for some details). I've set my Compose-key to Right-Alt, so Right-Alt "e -> ë.

Using the compose key works pretty well for me; setting the input method may be more convenient when you need to write a lot of accented characters.

Now, his may be good and well for the accented characters and other variants of Latin characters, such as the German Ess-Zet ligature "ß" (note, you can get that character with latin-prefix "s -> ß, latin-postfix s" -> ß or <compose-key> ss -> ß). But what about Greek characters? Mathematical symbols? Smileys?

ucs-insert

One way to add characters like α, or is to use ucs-insert, by default bound to C-x 8 RET. If you know the official Unicode name for a character, you can find it there; note that there's auto-completion and you can use * wild-cards. For the mentioned characters, that would be GREEK SMALL LETTER ALPHA, INFINITY and WHITE SMILING FACE.

You can also use the Unicode code points; so C-x 8 RET 03b1 RET will insert α as well, since its code point is U+03B1. In case you don't know the code points of Unicode characters, a tool like the Character Map (gucharmap) in Gnome may be useful.

abbrev

Since ucs-insert may not be convenient in all cases, you may want to add shortcuts for oft-used special characters to you abbrev table. See the entry on Abbrevs in the emacs manual. I usually edit the entries by hand with M-x edit-abbrevs, and I have entries like:

(text-mode-abbrev-table)
"Delta0"       0    "Δ"
"^2"           0    "²"
"^3"           0    "³"
"almost0"      0    "≈"
"alpha0"       0    "α"
"any0"         0    "∀"
"beta0"        0    "β"
"c0"           0    "©"
"deg0"         0    "℃"
"delta0"       0    "δ"
"elm0"         0    "∈"
"epsilon0"     0    "ε"
"eta0"         0    "η"
"heart0"       0    "♥"
"inf0"         0    "∞"
"int0"         0    "∫"
"notis0"       0    "≠"

Now, alpha0 will be auto-replaced with α. I'm using the 0 suffix for most entries so I can easily remember them, without making it hard to use alpha as a normal word. Note, abbrevs are a bit picky when it comes to the characters in the shortcut – for example, setting != -> won't work.

inheriting abbrevs from other modes

If you have set up a nice set of abbreviations for text-mode, you may want to use them in other modes as well; you can accomplish this by including the text-mode abbreviations into the table for the current one, for example in your ERC setup:

;; inherit abbrevs from text-mode
(abbrev-table-put erc-mode-abbrev-table :parents (list text-mode-abbrev-table))

2012-02-01

update

Regular emacs-fu programming will resume shortly, but for now I'll provide a brief update on some of my projects.

  • Recently, I discussed sauron, and event-tracking tool for emacs. I added some new features, fixed some bugs, and got some contributions (yay!)
    • tweak/improve priority handling
    • add a backend for the emacs-24 notification system
    • add settings to make the sauron frame 'sticky', and to hide the mode-line
    • enable dbus-message source outside your session; useful for cron/procmail etc.
    • display events in a tabular fashion
    • add support for John Wiegley's event.el
    • much improved documentation
    • other things…

    Sauron version 0.2 is available through Marmalade (see Package Management Revisited)

  • I released version 0.9.8 of mu (e-mail searcher/indexer, previously discussed in Searching e-mails with Wanderlust and mu). Now, for emacs-users I've added mu4e (manual), a new & experimental e-mail client. It won't be big and professional like gnus, but it's fun to hack on, and I've been using it for a few months.