About Archive Tags RSS Feed


After you've started it seems like a bad idea?

30 April 2013 21:50

To recap: given the absence of other credible alternatives I had two options:

  • Re-hack mutt to give me a sidebar that will show only folders containing new messages.
  • Look at writing a "simple mail client". Haha. Ha. Hah.

I think there is room for a new console client, because mutt is showing its age and does feel like it should have a real extension language - be it guile, lisp, javascript(!), Lua, or something else.

So I distilled what I thought I wanted into three sections:

  • mode-ful. There would be a "folder-browsing mode", a "message-browsing mode" and a "read-a-single-message" mode.
  • There would be scripting. Real scripting. I chose Lua.
  • You give it ~/Maildir as the configuration. Nothing else. If the damn computer cannot find your mailboxes something is wrong.

So how did I do? I wrote a ncurses-based client which has Lua backed into it. You can fully explore the sidebar-mode - which lets you select multiple folders.

From there you can view the messages in a list.

What you can't do is anything "real":

  • Update a messages flags. new -> read, etc.
  • GPG-validation.
  • MIME-handling.
  • Attachment viewing.

For a two-day hack it is remarkably robust, and allowing scripting shows awesomeness. Consider this:

-- show all folders in the Maildir-list.
function all()
   -- ensure that the sidebar displays all folders
   sidebar_mode = "all";
   -- we're going to be in "maildir browsing mode"
   cmail_mode = "sidebar";

-- Test code, show that the pattern-searching works.
-- To use this press ":" to enter the prompt, then enter "livejournal".
-- OR press "l" when in the sidebar-mode.
function livejournal()
   sidebar_pattern = "/.livejournal.2";
   sidebar_mode = "pattern";

-- There is a different table for each mode.
keymap = {}
keymap['sidebar'] = {}
keymap['index']   = {}
keymap['message'] = {}

-- In the sidebar-mode "b" toggles the sidebar <-> index.
-- ":" invokes the evaluator.
-- "q" quits the browser and goes to the index-mode.
-- "Q" quits the program entirely.
keymap['sidebar'][':'] = "prompt-eval"
keymap['sidebar']['b'] = "toggle"
keymap['sidebar']['q'] = "toggle"
keymap['sidebar']['Q'] = "exit"

-- show all/unread/livejournal folders
keymap['sidebar']['a'] = "all"
keymap['sidebar']['u'] = "unread"
keymap['sidebar']['l'] = "livejournal"

Neat, huh? See the cmail.lua file on github for more details.

My decision hasn't really progressed any further, though I can see that if this client were complete I'd love to use it. Its just that the remaining parts are the fiddly ones.

I guess I'll re-hack mutt, and keep this on the back-burner.

The code is ropey in places, but should you wish to view:

And damn C is kicking my ass.



Comments on this entry

icon Anonymous at 16:12 on 30 April 2013

Why are you writing this in C?

Also, Lua is barely passable as a language, and more importantly the C interface used to embed it and expose API to it ranks among the worst for extension languages. You might seriously consider choosing another extension language. Perhaps Scheme or Python.

icon Steve Kemp at 16:32 on 30 April 2013

I (mostly) like C, and picked it because I wanted to write it using S-Lang or curses.

Though I expect if I were to do further work I'd probably jump-ship to C++ to get access to STL. (Having vectors, etc, would be a lot simpler than rolling my own horrid linked-lists).

As for Lua I'm just going to say I disagree with you 100%. Lua is a fine extension language, certainly for this use-case where I'm calling into my application-code most of the time it works just fine. Lua is also significantly easier to embed, and lighter than Python would be.

I would be tempted by a lisp for the future. But to get started it was almost trivial in Lua.

icon Anonymous at 00:39 on 1 May 2013

Almost every language has a binding to curses. Slang seems somewhat less common, though most decent languages have an FFI.

I guess I just hate to see new code written in C when it doesn't absolutely need to be, especially for something like a mail client that deals with a lot of untrusted data in fun and exciting formats.

icon Asbjørn Sloth Tønnesen at 07:53 on 1 May 2013

Try to take a look at Lua Event Machine, that could simplify a lot of "fiddily ones", however it doesn't have a lem-ncurses extension yet, but a regular lua-ncurses could be used. A lem-gnutls is on the way, and will probably be pushed soon after Esmil is back from vacation next week.