tron's blog

Automated Revision Control with vim

By default, vim keeps the last version of whatever files you've edited. By default, the backup file is stuck in the same path as the original with a ~ appended to its name. After a while, you end up with this sort of thing:

[tron@altair][~]$ ls projects/browser
Makefile                browser.ui              moc_browser.cpp
Makefile~               browser.ui~             moc_browser.cpp~
browser                 browsertab.cpp          moc_browser.o
browser.cpp             browsertab.cpp~         moc_browsertab.cpp
browser.cpp~            browsertab.h            moc_browsertab.cpp~
browser.h               browsertab.h~           moc_browsertab.o
browser.h~              browsertab.o            ui_browser.h
browser.o               browsertab.ui           ui_browser.h~
browser.pro             browsertab.ui~          ui_browsertab.h
browser.pro~            main.cpp                ui_browsertab.h~
browser.pro.user        main.cpp~
browser.pro.user~       main.o

Sure, you could run rm *~, but god help you if make a mistake writing that. You could write a bash function, script, alias, what-have-you to do that for you. Or, you could write a short script for your editor (It's vim, right?) to automatically keep diffs of every file you edit from the time you first :write a file with the plugin loaded to now.

Viewing Unmodifiable Files with vim

I've been playing around with my vim configuration files. There's this little script in $VIMRUNTIME/macros called less.vim that lets you view files basically in the same way less does, but with all of vim's cool features - like windows. The problem is, this script doesn't integrate nicely with your own vimrc, nor does it allow editing of one file while viewing another - something that would be quite useful if you wanted to have the documentation and the file you're editing on the same screen without using screen or twm.

So I wrote my own version. vim has the autocmd command which allows you to bind functions to certain events like BufEnter, which is called when the cursor enters that buffer. All you have to do is check if the file is read-only on load and display appropriately.

NOTE: The code on the full page is quite long. I had to split this post so it wouldn't clog up the home page.

gmail-notifier

I finally got around to putting my gmail-notifier and generic-notifier up on github. They're tiny scripts that sit in your taskbar and notify you of new emails and whatnot.

Initially, I only needed a userland daemon that would poll gmail at specified intervals and send destop notifications that integrate with Ubuntu derivatives. I had written a shell script to do just that using wget and notify-send, but then I started working on machines that weren't using libnotify, so a better solution was in order.

I needed something to sit in the taskbar, have an easy way to change account settings, and fallaback to an at least decent notification bubble if it couldn't use libnotify. Qt offered a remarkably simple GUI setup, decent fallback for notifications, and python bindings. Pynotify (now python-notify) has python bindings for libnotify, but not everyone had pynotify installed back then. Dbus-python was more likely to be on systems that supported the notification spec (since that relies on dbus). I gave up trying to decide which to use, and just did both. Now I had a gmail scraper that did everything I wanted it to.

Gatlin pointed out that quite a few people could use something like this, so I decided to write a more generic version. I designed it so that, to extend the functionality to a different type of account, you would extend the GenericNotifier and PollingDaemon classes. The idea behind this was to have a different process running for each account. Why use threads and manage your own resources when the OS can do it for you?

That said, I'm starting to think that having a manager process running that just forks the different PollingDaemons would be a better UI design.

What do you think?

Now with 100% more mobile UI!

After finally getting one of these new-fangled mobile internet browsing devices, I became quickly annoyed that my own blag didn't have any sort of mobile UI. Enter the Mobile Theme module and my own variant of the Adaptivetheme Mobile theme. I haven't noticed any problems with it yet, but I'm sure some will pop up soon.

Your code snippet for this post is the entirety of the base.css for the mobile theme.

gmail-command

It turns out text messages from my phone to an email address are free. Google calendar can send sms notifications for calendar events. So now I'm working on a command interface that scrapes gmail messages and does... things. I'd send a text message from my phone, say "Tuesday, 3:00p, Meeting", and it would automagically add the calendar entry.

I know you're listening. Comment on it!

The 'correct' way to write in brainfuck

If you haven't heard about it, Brainfuck is one of those esoteric programming languages. When one is learning a language, it's customary that the first program they write simply outputs "Hello World". They then usually go on to do more complex things. Not so for Brainfuck, in which simple output is an exercise in reading an ASCII table and learning how to multiply with loops and pointers. This usually leads to long strings of things like ++++++[->+++++<]>, which are a pain in the ass to type out.

A wild python script appears.

  1. import sys
  2.  
  3. text = str(sys.argv[1])
  4. for letter in text:
  5.         ascii = ord(letter)
  6.         print "[-]>[-]<","+"*10,"[->","+"*(ascii/10),"<]>","+"*(ascii%10),"."

Something About Firefox

Soon, very soon, the Firefox devs will ship Firefox with a UI that doesn't require tweaking to not look like complete ass. I have great hope for them. Until then, there's always tweaking ~/.mozilla/firefox/[profile]/chrome/userChrome.css:

  1. toolbar{
  2.         height: 32px;
  3.         margin-top: 0px;
  4.         overflow: hidden;
  5. }

I have to use this little tweak on my desktop to keep the Stumbleupon buttons from taking up 48-64 pixels, depending on whether it's Thursday and the SU crew have 'fixed' anything recently. Thankfully, the Mozilla team have a pretty decent documentation of userChrome.css.

Screenshot Scripts

I've been using these for as long as I can remember.

For snapshots of a specific window:

  1. #!/bin/bash
  2.  
  3. picdir='/home/tron/pictures/snapshots'
  4. i=$(ls -1 ${picdir} | grep -o '[0-9]*' | sort -n | tail -n 1)
  5. xwd | convert - ${picdir}/snapshot$(($i+1)).png
  6. convert -thumbnail 100x100 ${picdir}/snapshot$(($i+1)).png \
  7.         ${picdir}/thumbs/snapshot$(($i+1)).thumb.png

For snapshots of the whole screen (everything that X is currently drawing):

  1. #!/bin/bash
  2.  
  3. picdir='/home/tron/pictures/snapshots'
  4. i=$(ls -1 ${picdir} | grep -o '[0-9]*' | sort -n | tail -n 1)
  5. xwd -root | convert - ${picdir}/snapshot$(($i+1)).png
  6. convert -thumbnail 100x100 ${picdir}/snapshot$(($i+1)).png \
  7.         ${picdir}/thumbs/snapshot$(($i+1)).thumb.png

I have them bound to Ctrl+PrtScn and PrtScn, respectively. If you want to also automagically upload the file to a server and put its url into the clipboard (the middle click buffer), stick this at the end of the file:

  1. ftp -n -i <<END
  2. open ftp.example.org
  3. user username password
  4. cd blah/blah/blah
  5. put ${picdir}/snapshot$(($i+1)).png snapshot$(($i+1)).png
  6. close
  7. bye
  8. END
  9. xsel -c
  10. echo "http://example.org/blah/blah/blah$(($i+1)).png" | xsel -b

Should I be doing this?

This could actually be done in one line, but that line would be much longer than my screen is wide.

  1. adjacent = [i for i in self.points if abs(point.x-i.x) < 0.1 and abs(point.y-i.y) < 0.1]
  2. close_vert = [i for i in adjacent if abs(point.z-i.z) < self.thresh]

It just feels like I'm cheating.

I have quantum postfix

Does that mean it's running and not taking up any cycles?

  1. tron@compy:~$ sudo postfix start
  2. postfix/postfix-script: fatal: the Postfix mail system is already running
  3. tron@compy:~$ sudo postfix stop
  4. postfix/postfix-script: fatal: the Postfix mail system is not running