Sunday, October 08, 2006

VimPastebin - Post to Pastebin from within Vim

The VimPastebin script is a Vim plugin script that posts selected text to the Pastebin of your choice and optionally sends the URL to your pasted text as Gajim message to someone in your roster. The syntax is chosen from the current filetype in the Vim editor. For example, if you are editing a Python file, the text sent to Pastebin will automatically be highlighted with Python syntax.

Requirements

This script is mostly written in Python, so it will only work if your Vim was compiled with the --enable-pythoninterp=yes configure option. To see if your installed Vim is compiled with this option, simply type the :version command inside Vim and look for +python. If you see -python in the list, this script will not work, otherwise you're golden!

Installation

Drop this script into your ~/.vim/plugin directory or somewhere else in your $VIMRUNTIME path. It will be sourced automatically next time you start Vim. You can source it manually by typing :source /path/to/script if you like.

There are a couple of configuration options in the script that should be modified for your particular settings. You can set your preferred Pastebin on line 38, and your preferred username on line 40. By default, the script included on this wiki page will post to http://pastebin.com as the user "vimuser".

Usage

To use the script is very simple. Just visually block (Shift-v) the lines of code you want to send to the Pastebin and enter the command :PasteCode. The blocked text will be sent to the Pastebin and the new URL will be shown on the Vim statusline. Optionally, you could enter the command :PasteGajim somename@somejid.org to send the new URL to the JID somename@somejid.org providing that JID appears in your roster. To make it even easier, you can send it to someone in your roster by only specifying their name, like :PasteGajim dcraven will send it to user name dcraven. This is handy if you cannot remember the person's full JID.

That's It!

That's pretty much all there is to it. If you missed the link to the actual script above, you can download it here. Enjoy!

Here's the code if you just want to have a quick look:

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

" Map a keystroke for Visual Mode only (default:F2)
:vmap <f2> :PasteCode<cr>

" Define two commands.. One for just pastebinning alone, and another for
" Gajiming the results
:command -range -nargs=* PasteCode :call PasteMe(<line1>,<line2>,"None")
:command -range -nargs=* PasteGajim :call PasteMe(<line1>,<line2>,"<args>")

function! PasteMe(line1,line2,args)
python << EOF
import vim

line1 = vim.eval('a:line1')
line2 = vim.eval('a:line2')
jid = vim.eval('a:args')
format = vim.eval('&ft')

url = PBSend(line1, line2, format)
if not jid == "None":
    gajim_send_url(jid, url)
print "Pasted at %s" % url
EOF
endfunction

python << EOF
import vim
from urllib2 import urlopen
from re import compile

def PBSend(line1, line2, format='text'):
################### BEGIN USER CONFIG ###################
    # Set this to your preferred pastebin
    pastebin = 'http://pastebin.com'
    # Set this to your preferred username
    user = 'vimuser'
#################### END USER CONFIG ####################

    supported_formats = {
        'text' : 'text', 'bash' : 'bash', 'python' : 'python', 'c' : 'c',
        'cpp' : 'cpp', 'html' : 'html4strict', 'java' : 'java',
        'javascript' : 'javascript', 'perl' : 'perl', 'php' : 'php',
        'sql' : 'sql', 'ada' : 'ada', 'apache' : 'apache', 'asm' : 'asm',
        'aspvbs' : 'asp', 'dcl' : 'caddcl', 'lisp' : 'lisp', 'cs' : 'csharp',
        'css' : 'css', 'lua' : 'lua', 'masm' : 'mpasm', 'nsis' : 'nsis',
        'objc' : 'objc', 'ora' : 'oracle8', 'pascal' : 'pascal',
        'basic' : 'qbasic', 'smarty' : 'smarty', 'vb' : 'vb', 'xml' : 'xml'
    }

    if not (pastebin[:7] == 'http://'):
        pastebin = 'http://' + pastebin

    code = '\n'.join(vim.current.buffer[int(line1)-1:int(line2)])
    if format in supported_formats.keys():
        data = "format=%s&paste=Submit&code2=%s&poster=%s" % \
                (supported_formats[format], urlencode(code),
                urlencode(user))
    else:
        data = "format=text&paste=Submit&code2=%s&poster=%s" % \
                (urlencode(code), urlencode(user))

    u = urlopen(pastebin, data)
    f = "".join(u.readlines())
    rx = compile("<a.*?/(\d+)\">")
    ar = rx.findall(f)
    if len(ar) > 0:
        url = pastebin + '/' + ar[0]
        return url
    else:
        print 'An error occured.'

def gajim_send_url(jid, url):
    try:
        import dbus
        sbus = dbus.SessionBus()
        obj = sbus.get_object('org.gajim.dbus', '/org/gajim/dbus/RemoteObject')
        interface = dbus.Interface(obj, 'org.gajim.dbus.RemoteInterface')

        # Try to get the actual JID from your contact list
        list = interface.__getattr__('list_contacts')
        roster = list()
        for contact in roster:
            if jid.lower() == contact['name'].lower():
                jid = contact['jid']

        send = interface.__getattr__('send_message')
        if not send(jid, url):
            print "%s not found in Gajim roster." % jid
    except:
        print "Error sending message to %s." % jid

def urlencode(data):
    out = ""
    for char in data:
        if char.isalnum() or char in ['-','_']:
            out += char
        else:
            char = hex(ord(char))[2:]
            if len(char) == 1:
                char = "0" + char
            out += "%" + char
    return out
EOF

6 comments:

  1. Hi, good but, can i obtain a version that just send the full file ? :)

    ReplyDelete
  2. Hello,
    I'm modifying your script to use paste.debian.net which use xml-rpc but it seem you didn't specify any license or copyright for this script. Is it in the public domain? Under what condition would it be acceptable to redistribute my modification ?

    You can reply me in a comment here or by mail : olethanh@gmail.com

    Olivier

    ReplyDelete
  3. *Awesome* plugin. Thanks a zillion. Besides, it looks easy to extend. Hmm... would you accept a patch for pidgin or empathy?

    ReplyDelete
  4. link to script is broken

    ReplyDelete
  5. Hi, I've updated your script. Now it's working. It's here: http://padovan.org/blog/2009/07/vim-plugin-for-pastebin/

    ReplyDelete
  6. I get
    "An error has occured.
    Pasted at None."

    This is using the script as is (only change username, oh, and changed the keybinding from F2 to F12)), with vim 7.2 on debian 6.0, python 2.6.6
    I copied the script and stuck it in ~/.vim/plugins/pastebin.vim

    ReplyDelete