Tuesday, October 10, 2006

Send a Gmail Message from Vim

Using Gmail on my laptop through the web interface can be quite time consuming. I use the Linux version of Firefox, and it's not exactly known around the world for its great speed. Anyways, sometimes I just want to shoot off a quick email, and it would take just as long to load the Gmail compose form as it would to type the email content. For these times I wrote a little vim-python script as follows:

" Make sure the Vim was compiled with +python before loading the script...
if !has("python")
        finish
endif

:command! -nargs=? GMSend :call GMailSend("<args>")

function! GMailSend(args)
python << EOF
import vim
to = vim.eval('a:args')
GSend(to)
EOF
endfunction

python << EOF
########### BEGIN USER CONFIG ##########
account = 'MY_GMAIL_ACCOUNT'
password = 'MY_GMAIL_PASSWORD'
########### END USER CONFIG ###########


def GSend(to):
    """
    Send the current buffer as a Gmail message to a given user.
    """
    import libgmail

    subject = vim.current.buffer[0]
    body = '\n'.join(vim.current.buffer[2:])

    ga = libgmail.GmailAccount(account, password)
    try:
        ga.login()
    except libgmail.GmailLoginFailure:
        print "Login failed. (Wrong username/password?)"

    gmsg = libgmail.GmailComposedMessage(to, subject, body)

    if ga.sendMessage(gmsg):
        print "Message sent `%s` successfully." % subject
    else:
        print "Could not send message."

EOF

It's a really simple script, and it uses Python so it will only work if your Vim was compiled with the +python option. Of course, you'll also need to edit the script to put in your own Gmail user name and password (lines 18 and 19).

Installation

Drop the above script (or download it from here) into your ~/.vim/plugin/ directory. Reload Vim or source the file with :so ~/.vim/gmail.vim.

Usage

It's even easier to use. The first line in the buffer is the email's subject, and the rest is the body. Once the email is composed in this fashion, type :GMSend <dest> where <dest> is the email address that you want to send this message to. If all is well, you'll see a message at the bottom of your Vim window indicating that all is well, and that the message was sent successfully.

Hopefully somebody out there will find this useful. The version I am actually using is a little more complex. I've extended the script to download messages by folder or label and stick the id, subject, and author in an active buffer. From there I can select one of the shown messages and the script will display the body in the same buffer. I've kept the rest to myself as I'm not real thrilled with the UI part, and I'm not sure it will work as expected for everyone. If you are interested, leave a comment. I'm pretty confident that the script posted above (the one that just sends mail) will work as expected. Enjoy!

15 comments:

  1. I really like this idea. I have not tried it myself yet but I have been looking for a way to do mail with vim. Maybe you could get more attention about this script if you added it to the vim.org scripts section? I think lots of people would find this useful. Once I get a chance to try it I will let you know how it works for me.

    ReplyDelete
  2. Well it's more of a function I suppose than an actual script :). I consider scripts to be more complex than this. If this code covered email *management* or something then I could see it as a script.

    Also it requires Python. I think (personally) that it's better to keep the vim.org collection as pure Vim scripted scripts.

    All that said, I could see it having a place in the Tips section. That may be useful. Hopefully you can get it working for you. A friend of mine had trouble getting it to work at first, but it turned out to be because his version of libgmail wasn't current enough.

    Thanks for the comment!

    ReplyDelete
  3. I am also having troubles. I have python and python enabled vim but I did not have libgmail. So I thought it would be easy to install. Not so.

    I downloaded, unzipped and ran the setup.py:

    %> python2.3 setup.py install
    running install
    error: invalid Python installation: unable to open
    /usr/lib/python2.3/config/Makefile (No such file or directory)

    No matter which version I try and run the setup.py against I do not have that Makefile. SO I think that it must require python2.3-dev which seems pretty silly just to install a script don't you think? I cannot install python2.3-dev because I am on a work machine and cannot be root. I am sure there should be a way to install it without python2.3-dev but I am a newbie to py so I don't know how to do it and couldn't find it on the web anywhere.

    My other options are to try it at home or to convince IT that we need python2.3-dev installed. This would be a tall task since I am a contractor and my gig is nearly up. :)

    I am determined to get it working at some point both because I want the tool and it should help me learn a bit more about python!

    ReplyDelete
  4. Yes, unfortunately, to install packages using the Python distutils method you need the -dev packages (thanks Debian).

    Luckily, I just had a look inside the libgmail tarball to discover two lonely .py files. This means that if you drop these files into the same directory as the script that uses them, you should be golden. Give that a shot and see how it goes.

    ReplyDelete
  5. Hello Dennis,

    I would like to be able to use your scipt.
    But I guess something is wrong.

    Vim says:

    Error detected while processing function GMailSend:
    line 5:
    Traceback (most recent call last):
    File " string ", line 3, in ?
    File " string ", line 18, in GSend
    File "/usr/lib/python2.4/site-packages/libgmail.py", line 302, in login
    pageData = self._retrievePage(req)
    File "/usr/lib/python2.4/site-packages/libgmail.py", line 331, in _retrievePage
    resp = urllib2.urlopen(req)
    File "/usr/lib/python2.4/urllib2.py", line 130, in urlopen
    return _opener.open(url, data)
    File "/usr/lib/python2.4/urllib2.py", line 358, in open
    response = self._open(req, data)
    File "/usr/lib/python2.4/urllib2.py", line 376, in _open
    '_open', req)
    File "/usr/lib/python2.4/urllib2.py", line 337, in _call_chain
    result = func(*args)
    File "/usr/lib/python2.4/urllib2.py", line 1029, in https_open
    return self.do_open(httplib.HTTPSConnection, req)
    File "/usr/lib/python2.4/urllib2.py", line 996, in do_open
    raise URLError(err)
    urllib2.URLError: urlopen error (111, 'Connection refused')

    Because of the last line I guess it is something with the proxy which I am behind.
    Do you happen to know how to use your script when you're behind a proxy?

    Thanks in advance!

    Greetz,

    ReplyDelete
  6. I really like using gmail.vim. It's so useful. The less I have to use different programs the better. I use vim to produce all my documents with LaTeX.

    So sending mail is great, but I'd love to be able to check mail from as well. I'd like to start using the "complex" version. I'm not much of a Vim scripter and haven't looked at libgmail, but perhaps could help with the UI.

    ReplyDelete
  7. hey thanks for this, i keep my todo list in gmail using the plus addressing. Now, i can zip off my todo note right where i am the most (vim)

    this is really great, again, thanks

    ReplyDelete
  8. This is simply *great* :)

    I'd love to see the more advanced version, if you decide to release it.

    I'd love to see something that downloads a list of gmail conversations, that could be expanded and collapsed with vim folding :)

    ReplyDelete
  9. Thanks for a great plugin! Would it be possible to take a peek at the more complex script? I would love to be able to check mail from Vim.. I would rarely have to leave it then!!
    Many many thanks,
    Nuky.

    ReplyDelete
  10. Hi,
    I tried to install this on my OS FC5.
    when I ran the initial command I got this error :-

    $ python2.4 setup.py install Could not find platform independent libraries prefix Could not find platform dependent libraries exec_prefix
    Consider setting $PYTHONHOME to prefix :exec_prefix
    'import site' failed; use -v for traceback
    Traceback (most recent call last):
    File "setup.py", line 7, in ?
    import libgmail
    File "/home/sameer/libgmail-0.1.5.1/libgmail.py", line 43, in ?
    import os,pprint
    ImportError: No module named os

    Can anyone pls help me in this?
    I installed Python 2.5.1 for this. still no success.

    regards
    Sameer.

    ReplyDelete
  11. I don't know how to compile vim with the +python option, can you teach me how?

    ReplyDelete
  12. @ptn: If you are compiling vim from svn, you need to modify the src/Makefile and uncomment the line that looks like

    CONF_OPT_PYTHON = --enable-pythoninterp

    Then when you build, you will have +python enabled.

    ReplyDelete
  13. Nice script! Thanks mate.
    I installed it in Leopard and it worked great.

    I dropped libgmail in ~/.vim/plugin as Dennis suggested. I also had to install ClientCookie because my Mac didn't seem to include it, so I tried copying it to the same folder and all went pretty well :)

    Can we take a look at the other version? It'll be so wicked to read email from Vim.

    Thank you!
    Greetings from Mexico.

    ReplyDelete
  14. Nice! What about autocompletion for addresses?

    ReplyDelete
  15. Very good, I post in my blog about: http://vivaotux.blogspot.com/2009/08/ultimate-vim-python-setup.html

    ReplyDelete