Code and Hacks

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

My Photo
Name:
Location: CA, United States

Perl hacker, investor and entrepreneur.

Saturday, July 4, 2009

Stealing from Padre for Vim part 3

As promised in my last post, I have released a new version of App::EditorTools and have a number of screenshots of the new functionality. This version includes App::EditorTools::Vim, which provides an easy way to add the vim scripts to integrate the package into Vim.

perl -MApp::EditorTools::Vim -e run > ~/.vim/ftplugin/perl/editortools.vim

And now you should have the following mappings:

  • ,pp - Show a menu of the functions availabe from App::EditorTools
  • ,pL - Lexically rename the variable under the cursor (make sure the cursor is at the start of the variable for now
  • ,pP - Rename the package based on the path of the current buffer
  • ,pI - Introduce a temporary variable

Here are a few screenshots of these actions:

Lexically Rename Variables:
vim-renamevar
Rename Package based on the current file's path:
vim-renamepackage
Introduce Temporary Variable
vim-introtempvar

I'd love to hear feedback and any suggestions for future PPI based tools that Vim, Padre and other editors could leverage.

I also have to note that the editortools-vim script from App::EditorTools was very easy to put together (although it still needs a fair amount of clean-up work and documentation) since is was based on Ricardo's App::Cmd--very easy to use and feature rich.

** Updated 7/5/09 10:37am: moved the screencasts to an external server and fixed some spelling

Labels: ,

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:

screenshot
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):

#!/bin/bash

SIZE=${1:-800}
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: , , ,

Wednesday, May 20, 2009

Recovering After Vim Terminates

When vim is shutdowns abnormally it leaves a bunch of .swp files around.1 Given the way I program (very iterative and test focused) those backups are rarely more current than the saved file. A great time saver to help with recovery is the vim DiffOrig command. After learning about it on StackOverflow, I put together the following bash script to find any swap files under the current directory, open each in vim, run DiffOrig and prompt to delete after you close vim.

#!/bin/bash

swap_files=`find . -name "*.swp"`

for s in $swap_files ; do
     orig_file=`echo $s | perl -pe 's!/\.([^/]*).swp$!/$1!' `
     echo "Editing $orig_file"
     sleep 1
     vim -r $orig_file -c "DiffOrig"
     echo -n "  Ok to delete swap file? [y/n] "
     read resp
     if [ "$resp" == "y" ] ; then
             echo "  Deleting $s"
             rm $s
     fi
done

I was planning on converting this to a vim function, but for now the extra step of exiting vim and answering a prompt works fine. Also, my vim already loads DiffOrig. ArchLinux includes it in /etc/vimrc. If your vim doesn't, I believe the following command will do it:

if !exists(":DiffOrig")
command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
               \ | wincmd p | diffthis
endif

BTW Iron Men, I realize this post isn't really Perl focused, but it is usually Perl files that I'm recovering!

Footnotes:
1. Which is almost never vim's fault. More likely an ssh connection was terminated or something along those lines.

Labels: