Tue, 13 Oct 2009

Good Python Habits: vim + pyflakes

Here is a neat little hack for running pyflakes on Python files after you save them. I like using pyflakes for quickly catching dumb errors, but you could easily replace it with a more comprehensive tool like pychecker, or pylint for more strict PEP8 compliance.

All you have to do is throw this in your ~/.vimrc

au BufWritePost *.py !pyflakes %

This has saved me *tons* of time and frustration over the past few weeks, and I have no idea I lived without it.


posted at: 13:32 | link | Tags: , , | 4 comments

Wed, 31 Dec 2008

Taming the fox (part 2)

So, in my previous post I wrote a script that uses xdotool to put firefox to sleep when it does not have focus. The implementation was pretty straight-forward, but not optimal. Thanks to some help from Jordan Sissel, I threw together a Python script that accomplishes this goal much more effectively, using the python-xlib module instead of xdotool.

http://lmacken.fedorapeople.org/tamefox.py
import os
from signal import SIGSTOP, SIGCONT
from Xlib import X, display, Xatom

def watch(properties):
    """ A generator that yields events for a list of X properties """
    dpy = display.Display()
    screens = dpy.screen_count()
    atoms = {}
    wm_pid = dpy.get_atom('_NET_WM_PID')

    for property in properties:
        atomid = dpy.get_atom(property, only_if_exists=True)
        if atomid != X.NONE:
            atoms[atomid] = property

    for num in range(screens):
        screen = dpy.screen(num)
        screen.root.change_attributes(event_mask=X.PropertyChangeMask)

    while True:
        ev = dpy.next_event()
        if ev.type == X.PropertyNotify:
            if ev.atom in atoms:
                data = ev.window.get_full_property(ev.atom, 0)
                id = int(data.value.tolist()[0])
                window = dpy.create_resource_object('window', id)
                if window.id == 0: continue
                pid = int(window.get_full_property(wm_pid, 0).value.tolist()[0])
                title = window.get_full_property(Xatom.WM_NAME, 0).value
                yield atoms[ev.atom], title, pid, data

def tamefox():
    """ Puts firefox to sleep when it loses focus """
    alive = True
    ff_pid = None
    for property, title, pid, event in watch(['_NET_ACTIVE_WINDOW']):
        if title.endswith('Firefox') or title.endswith('Vimperator'):
            ff_pid = pid
            if not alive:
                print 'Waking up firefox'
                os.kill(ff_pid, SIGCONT)
                alive = True
        elif ff_pid and alive and not title.startswith('Opening') and \
                title not in ('Authentication Required', 'Confirm', 'Alert'):
            print 'Putting firefox to sleep'
            os.kill(ff_pid, SIGSTOP)
            alive = False

if __name__ == '__main__':
    tamefox()


posted at: 07:03 | link | Tags: , | 9 comments

Taming the fox

As with most people these days, I have firefox running at all times. I also usually have about 50-100 tabs open (how I manage that insanity should probably be left for it's own blog post). When I'm not actively using it, firefox "idles" about as well as an ADHD kid after a case of Red Bull, and ends up waking my kernel up hundreds of times a second. When I'm hacking in vim, do I really want or need javascript/flash/animations/etc to be running? Probably not...

So tonight I threw together a little script to "solve" this "problem".

#!/bin/bash
# A tool for putting firefox to sleep when it does not have focus.
alive=1
while true; do
    if xwininfo -id $(xdotool getactivewindow) | egrep -q '(Firefox|Vimperator)' ; then
        if [ ! $alive ]; then
            kill -CONT `pidof firefox`
            alive=1
        fi
    else
        if [ $alive ]; then
            kill -STOP `pidof firefox`
            alive=
        fi
    fi
    sleep 1
done

Obviously the most efficient way to do this would be to hook into X's focus events, but I'm lazy...
*UPDATE*: I got un-lazy and implemented a better version using the python-xlib module. See Taming the fox (part 2).

This script uses xdotool, which I just packaged and pushed into review for Fedora. (update: Oops, looks like xdotool is already in Fedora :)


posted at: 04:23 | link | Tags: , | 11 comments

Sat, 19 May 2007

Dealing with multiple email addresses in mutt

I recently watched Bram Moolenaar's "7 Habits for Effective Text Editing 2.0" Google Tech Talk presentation, which inspired me to dust off the old vimrc and poke around for a bit. I tend to live most of my life inside of vim, which is actually a pretty kickass place to live (I even started working on a life.vim script to replace my [excessive] tomboy usage, and add a bit of GTD sauce).

I use mutt for my email accounts, and recently made some modifications to my vimrc to help automate a task that utilizes far too many of my keystrokes each day: changing the From field of outgoing messages.

let g:addresses = ['lewk csh rit edu', 'lmacken redhat com', 'lmacken fedoraproject org']
function NextEmailAddress()
    if !exists("g:email_idx")
        let g:email_idx = 0
    endif
    s@^\(From:.*<\).*>@\=submatch(1) . g:addresses[g:email_idx % len(g:addresses)] . ">"@
    let g:email_idx += 1
endfunction
map <silent> @ :call NextEmailAddress()<CR>

This lets you cycle through your email addresses by pressing '@' when composing a new mail. From here, my messages go through esmtp, which ships them off to the proper SMTP server based on the identity of the mail.

I'd be curious to hear of any other tweaks people have made to their vimrc's to help improve their mutt usage, or of any life-changing hack that saves you tons of keystrokes every day.


posted at: 19:15 | link | Tags: , , , | 1 comments