Code and Hacks

Stuff I've stumbled on or figured out... mostly Perl, Linux, Mac and Cygwin.

My Photo
Location: CA, United States

Perl hacker, investor and entrepreneur.

Saturday, June 27, 2009

More theft from Padre

I was pleasantly surprise at the positive response to my last post on Stealing from Padre for Vim--particularly from the Padre developers! Seems they had hoped/planned on separating some of the tools out of the Padre core from the beginning (and many seem to be vimmers).

With their blessing and encouragement, I have pulled the editor independent parts of their PPI::Task tools into its own distribution--PPIx::EditorTools--available now on CPAN. I also adapted the current version of Padre to work wit the external package and released App::EditorTools to provide a command line interface for those editors that need it (i.e., vim). I'll post another screencast and the Vim scripts needed to integrate it shortly.

As a result, I'm depreciating App::LexVarRepl--which was only ever available on github.

Sorry for the short post which is light on links and code, but we are in the process of moving so I'm dedicating the few moments I have to coding this rather than blogging about it...for now at least!

Labels: ,

Tuesday, June 16, 2009

Stealing from Padre for Vim

I'm sure the Padre developers weren't hoping to have their code absconded for those of us addicted to vim, but tsee's recent blog post on refactoring with Padre's lexical variable replace made me jealous--I want that for vim! So hack, hack, hack and voila:

This really is just leveraging the Padre code. At this point I actually use Padre::PPI but that has the downside of requiring Wx (which I personally like but it is quite a requirement). I only added a bit of code to make this into its own package and included some hints on vim scripting. The idea is to show how this could be abstracted into a standalone module then Padre, vim and any other reasonably powerful editor could use it. For now, I have packaged it as App::LexVarReplace with App::LexVarReplace::Vim pod. I would appreciate suggestions on the package layout and name, and any feedback from the Padre guys would be great. The git repository is available for your perusal. I must say that Padre seems very cool. I continue to check it out every once in a while, but I just can't seem to give up vim, gnu screen and a good old xterm. The developers have really done a great job leveraging modern Perl tools. You should check it out! I am only publishing this on github for now. I would like to speak with tsee or one of the Padre developers before this makes it debut on CPAN, but I'm a bit short on time at the moment.

Labels: ,

Thursday, June 11, 2009

Web testing

I have been stuck doing a lot of front-end web work lately and haven't had a chance to do much perl coding (I am planning on releasing an Mason based renderer for Email::MIME::Kit soon though). I'm very impressed with the power of CSS in modern browsers. The last time I looked at it, browser incompatibilities really made it difficult to use. It is much better still, I find most of the work to be trial and error, so I have a couple of tips that have saved me some time going back and forth...

Quick Browser Refresh

I do all of my coding in vim and have ton of mappings (maybe I'll share some in future). One I really like right now it ,u which saves the current file then runs my xrefresh perl script which finds my Firefox window and refreshes the current page. It is a simple script that is based on X11::GUITest. It works particularly well when I am using two monitors and can have the browser on in one of them. Here is the mapping, along with the ,U mapping which saves all files:

nmap <silent> ,u :w<cr>:! xrefresh 'Gran Paradiso'<cr>
nmap <silent> ,U :wa<cr>:! xrefresh 'Gran Paradiso'<cr>

It would probably be easy to extend this script to do things like refresh multiple browsers, refresh without using the cache, etc.

IE Testing with VBox

Next up is some fun with IE. (Oh, the hours wasted on you. Damn you IE!) Microsoft has actually been very helpful and provided disk images that you can use to test web pages in a virtual machine on different versions of their browser. They expire periodically and they are designed for Microsoft Virtual PC so it take a bit of work to set them up on linux using VirtualBox, so I created a bash script (create-ie-vbox) to do the heavy lifting.

Once you download the images run create-ie-vbox <path-to-image-.exe> and wait a while. The script uses perl and File::Spec to find the absolute path to the .exe file

exe_file=`echo $exe_file | perl -MFile::Spec -e'print File::Spec->rel2abs(<>)'`
then the unrar command (and perl) to find the .vhd file and unpack it
vhd_file=`unrar l $exe_file | perl -ne'/(\w[\s\w-]*\.vhd)/ && print $1'`
nice unrar e "$exe_file" "$vhd_file" >> $log 2>&1 \
   || die "Couldn't extract $vhd_file from $exe_file"
Then the big trick is to convert the .vhd file to a .vdi file. While VBox can work with .vhd files, Microsoft uses the same UUID for all of these disk images which VBox doesn't like. There is a command in VBoxManage to change the UUID(VBoxManage internalcommands setvdiuuid "$vhd") but there is an acknowledged bug that prevents it from being useful here. Instead we have to use qemu to convert it to a raw disk and then VBoxManage to convert that to a .vdi:
nice qemu-img convert -O raw -f vpc "$vhd" "$raw" || die "Error converting to raw"
nice VBoxManage convertdd "$raw" "$vdi" || die "Error converting to vdi"
Finally there are a number of VBoxManage commands to create and register the image and disk.

Once this is done, there is a bit more work that needs to be done within the vm to deal with some bugs and annoyances. The script prints out the remaining steps. Much thanks to George Ornbo who pointed the way on his blog. Note that this script only works on the XP disks at this point; I haven't bothered to test the Vista versions yet.

BTW, most of my bash scripts use the die() function (stolen from perl) which is very simple but handy:

function die() {
 echo $@
 exit 1

Browser Resize

Lastly, I like to check my pages in browsers at various widths. Most importantly (or is that annoyingly) 800px. Rather than change my screen resolution, I use this simple bash script to resize Firefox to the desire width (defaulting to 800 if nothing is supplied on the command line):


echo Resize to $SIZE width
wmctrl -r "Firefox" -e 0,-1,-1,$SIZE,-1
Simple, but gets the job done quickly!

Hope these are helpful.

Labels: , , ,

Friday, June 5, 2009

Get Lazy, Use Data::Pageset::Render

I have been using the very nice Data::Pageset module for a while now. It makes separating you data into multiple pages very simple, and for very large datasets it has the slide mode which helps keep your pager small (rather than have links to 100 pages, you get links to the first and last page and the five pages around your current page).

Eventually, I got tired of recreating the same html code for each new pager. I first put together a simple Mason component, but found myself copying it between projects and starting to write one for TT. Eventually, I wrote Data::Pageset::Render. The module (which is on CPAN) subclasses Data::Pageset and adds the html method, which returns the html code, complete with links, to create your pager.

Just create your pager object as you would with Data::Pageset adding link_format => '<a href="">%a</a>' to the constructor, the html method then eliminates all that redundant paging html.

 my $pager_html = $pager->html();
 # $pager_html is html "<< 1 ... 3 4 5 6 7 ... 10 >>" with appropriate links

 # A bit more control over the appearence of the current page:
 my $pager_html = $pager->html( '<a href="">%a</a>', '[%a]' );
 # $pager_html is html "<< 1 ... 3 4 [5] 6 7 ... 10 >>" with appropriate links

This works great within a larger framework like TT or Mason:

 # In a TT template all the paging html is reduced to just:
 [% pager.html() %]

 # or in a Mason template:
 <% $pager->html() %>

There aren't very many configuration options now. If there is interest I might make some of the controls customizable (ie, the >> to move forward). Any suggestions are more than welcome.

Labels: ,