sontek ( John M. Anderson )

May 11, 2008

Python with a modular IDE (Vim)

Filed under: Programming, python, vim — Tags: , , — sontek @ 3:18 pm

On Thursday, May 9th, 2008 the Utah Python User Group decided to settle the debate that has plagued us developers since the beginning of time: If you were a programming language, what editor would you use?

I was tasked with showing Eclipse with the PyDev plugin in all its glory–but we all know–real men / developers don’t use IDE’s, so we are going to talk about using Python and Vim together, reaching a state of Zen that the Dalai LLama would be jealous of and establishing more Feng Shui than Martha Stewart’s Kitchen.

Freely jump between your code and python class libraries

There are 2 ways to add your ability to jump between python class libraries, the first is to setup vim to know where the Python libs are so you can use ‘gf’ to get to them (gf is goto file). You can do this by adding this snippet to your .vimrc:

python << EOF
import os
import sys
import vim
for p in sys.path:
    if os.path.isdir(p):
        vim.command(r"set path+=%s" % (p.replace(" ", r"\ ")))
EOF

With that snippet you will be able to go to your import statements and hit ‘gf’ on one of them and it’ll jump you to that file.

Continuing accessibility of the Python class libraries we are going to want to use ctags to generate an index of all the code for vim to reference:

$ ctags -R -f ~/.vim/tags/python.ctags /usr/lib/python2.5/

and then in your .vimrc

set tags+=$HOME/.vim/tags/python.ctags

This will give you the ability to use CTRL+] to jump to the method/property under your cursor in the system libraries and CTRL+T to jump back to your source code.

I also have 2 tweaks in my .vimrc so you can use CTRL+LeftArrow and CTRL+RightArrow to move between the files with more natural key bindings.

map <silent><C-Left> <C-T>
map <silent><C-Right> <C-]>

You can also see all the tags you’ve been to with “:tags”

Code Completion

To enable code completion support for Python in Vim you should be able to add the following line to your .vimrc:

autocmd FileType python set omnifunc=pythoncomplete#Complete

but this relies on the fact that your distro compiled python support into vim (which they should!).

Then all you have to do to use your code completion is hit the unnatural, wrist breaking, keystrokes CTRL+X, CTRL+O. I’ve re-bound the code completion to CTRL+Space since we are making vim an IDE! Add this command to your .vimrc to get the better keybinding:

inoremap <Nul> <C-x><C-o>

Along with code completion, you will also have call tip support. Here is a screenshot:

Vim with Code Completion
Documentation

No IDE is complete without the ability to access the class libraries documentation! You’ll need to grab this vim plugin. This gives you the ability to type :Pydoc os.path or use the keystrokes <Leader>pw and <Leader>pW to search for the item under the cursor. (Vim’s default <Leader> is “\”). Here is a screenshot:

Vim with PyDoc integration

Syntax Checking

Vim already has built in syntax highlighting for python but I have a small tweak to vim to give you notifications of small syntax errors like forgetting a colon after a for loop. Create a file called ~/.vim/syntax/python.vim and add the following into it:

syn match pythonError "^\s*def\s\+\w\+(.*)\s*$" display
syn match pythonError "^\s*class\s\+\w\+(.*)\s*$" display
syn match pythonError "^\s*for\s.*[^:]$” display
syn match pythonError “^\s*except\s*$” display
syn match pythonError “^\s*finally\s*$” display
syn match pythonError “^\s*try\s*$” display
syn match pythonError “^\s*else\s*$” display
syn match pythonError “^\s*else\s*[^:].*” display
syn match pythonError “^\s*if\s.*[^\:]$” display
syn match pythonError “^\s*except\s.*[^\:]$” display
syn match pythonError “[;]$” display
syn keyword pythonError         do

Now that you have the basics covered, lets get more complicated checking added. Add these 2 lines to your .vimrc so you can type :make and get a list of syntax errors:

autocmd BufRead *.py set makeprg=python\ -c\ \"import\ py_compile,sys;\ sys.stderr=sys.stdout;\ py_compile.compile(r'%')\"
autocmd BufRead *.py set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m

You will have the ability to to type :cn and :cp to move around the error list. You can also type :clist to see all the errors, and finally, sometimes you will want to check the syntax of small chunks of code, so we’ll add the ability to execute visually selected lines of code, add this snippet to your .vimrc:

python << EOL
import vim
def EvaluateCurrentRange():
eval(compile('\n'.join(vim.current.range),'','exec'),globals())
EOL
map <C-h> :py EvaluateCurrentRange()

Now you will be able to visually select a method/class and execute it by hitting “Ctrl+h”.

Browsing the source

Moving around the source code is an important feature in most IDE’s with their project explorers, so to get that type of functionality in vim we grab the Tag List plugin. This will give you the ability to view all opened buffers easily and jump to certain method calls in those buffers. Here is a screenshot of it in action:

Vim TagList Plugin

The other must-have feature of an IDE when browsing code is being able to open up multiple files in tabs. To do this you type :tabnew to open up a file in a new tab and than :tabn and :tabp to move around the tabs. Add these to lines to your .vimrc to be able to move between the tabs with ALT+LeftArrow and ALT+RightArrow:


map <silent><A-Right> :tabnext<CR>
map <silent><A-Left> :tabprevious<CR>

Debugging

To add debugging support into vim, we use the pdb module. Add this to your ~/.vim/ftplugin/python.vim to have the ability to quickly add break points and clear them out when you are done debugging:

python << EOF
def SetBreakpoint():
    import re
    nLine = int( vim.eval( 'line(".")'))

    strLine = vim.current.line
    strWhite = re.search( '^(\s*)', strLine).group(1)

    vim.current.buffer.append(
       "%(space)spdb.set_trace() %(mark)s Breakpoint %(mark)s" %
         {'space':strWhite, 'mark': '#' * 30}, nLine - 1)

    for strLine in vim.current.buffer:
        if strLine == "import pdb":
            break
    else:
        vim.current.buffer.append( 'import pdb', 0)
        vim.command( 'normal j1')

vim.command( 'map <f7> :py SetBreakpoint()<cr>')

def RemoveBreakpoints():
    import re

    nCurrentLine = int( vim.eval( 'line(".")'))

    nLines = []
    nLine = 1
    for strLine in vim.current.buffer:
        if strLine == ‘import pdb’ or strLine.lstrip()[:15] == ‘pdb.set_trace()’:
            nLines.append( nLine)
        nLine += 1

    nLines.reverse()

    for nLine in nLines:
        vim.command( ‘normal %dG’ % nLine)
        vim.command( ‘normal dd’)
        if nLine < nCurrentLine:
            nCurrentLine -= 1

    vim.command( ‘normal %dG’ % nCurrentLine)

vim.command( ‘map <s-f7> :py RemoveBreakpoints()<cr>’)
EOF

With that code you can now hit F7 and Shift-F7 to add/remove breakpoints. Then you just launch your application with !python % (percent being the current file, you can declare your main file here if its different).

Another tweak I use is to have my vim inside screen with a horizontal split, that way I can see the python interpreter and debug while still having vim there so I can easily fix my code. Here is a screenshot of that in action:

Vim with Screen

Snippets

A great time saver with stanard IDE’s is code snippets, so you can type a few key strokes and get a lot of code out of it. An example of this would be a django model, instead of typing out the complete declaration you could type ‘mmo<tab><tab>’ and have a skeleton of your model done for you. To do this in vim we grab the Snippets EMU plugin.

Check out a great screencast of snippetsEmu in action here

You can get my full setup here

Emacs

Here is a great post on how to do the same with Emacs.

May 6, 2008

Utah openSUSE User Group meeting tonight!

Filed under: Linux, SUSE — Tags: , , — sontek @ 9:18 am

Tonight we are having our first openSUSE User Group meeting, we’ll be discussing 11.0 Beta 2.

* Date/Time: Tuesday, May 6, 2008 @ 7:00pm.
* Location: Applebees, 105 E 12300 S, Draper, UT
* Google Maps: Click Here

You can get more information on the group here.

April 16, 2008

Printing in GTK#

Filed under: .NET, Databases, Mono, Postgresql, Programming, Xorg, irssi — Tags: , , , , , — sontek @ 11:58 pm

I just finished porting Tomboy’s print code to GTK so that we would be more portable and I thought other Mono apps looking to move from libgnomeprint or wanting to add printing support might find a code example helpful.

First, To start printing you do something like:

private void PrintButtonClicked (object sender, EventArgs args)
{
Gtk.PrintOperation op = new PrintOperation ();
op.BeginPrint += new BeginPrintHandler (OnBeginPrint);
op.DrawPage += new DrawPageHandler(OnDrawPage);

op.Run (Gtk.PrintOperationAction.PrintDialog, this.Window);
}

after the PrintOperation is set off you need to handle the BeginPrint event. The main things that need to be done are finding out how many lines will fit on a page and how many lines you have:

public void OnBeginPrint(object sender, Gtk.BeginPrintArgs args)
{
PrintOperation op = (PrintOperation)sender;
lines_per_page = (int)Math.Floor ((double)args.Context.Height / (double)font_size);
Gtk.TextIter start_iter, end_iter;
this.Buffer.GetBounds (out start_iter, out end_iter);
lines = this.Buffer.GetText (start_iter, end_iter, false).Split ('\n');
op.NPages = (int)Math.Ceiling ((double)lines.Length / (double)lines_per_page);
}

Finally, now that you have the printing setup, you need to actually render the data to be printed:

public void OnDrawPage(object sender, Gtk.DrawPageArgs args)
{
PrintOperation op = (PrintOperation)sender;
Cairo.Context cr = args.Context.CairoContext;

int line = args.PageNr * lines_per_page;
int num_lines = 0;
if (args.PageNr+1 != op.NPages)
num_lines = line + lines_per_page;
else
num_lines = lines.Length;

cr.MoveTo (0, 0);

for (int i = 0; i < lines_per_page && line < num_lines; i++)
{
Pango.Layout layout = args.Context.CreatePangoLayout ();
Pango.FontDescription desc = Pango.FontDescription.FromString (”sans ” + font_size);
desc.Size = (int)(font_size * Pango.Scale.PangoScale);
layout.FontDescription = desc;

layout.SetText (lines[line]);
Pango.CairoHelper.ShowLayout (cr, layout);
cr.RelMoveTo (0, font_size);
line++;
}
}

This does not take into account styles but will give you the basic idea of what needs to be done.

March 20, 2008

My top 15 commands

Filed under: Bash, Linux — Tags: , — sontek @ 5:49 pm

My friend Sam posted a blog on his top 15 commands used from the commandline, so here are mine:

sontek@inspidell:~> history | awk ‘{print $2}’ | awk ‘BEGIN {FS=”|”} {print $1}’|sort|uniq -c | sort -n | tail -n 15 | sort -nr
143 ls
135 cd
84 vim
69 exit
57 ssh
56 su
35 svn
25 man
24 rm
24 python
22 sudo
22 jhbuild
18 make
17 grep
16 xrandr

You can tell a lot about a person by their top 15 commands and as you can see with mine, the majority of mine are used for coding!

You can see a break down of the command I used to list these here: http://czarism.com/my-top-ten-linux-comments-history

What are your top 15 commands?

Debugging with strace

Filed under: Bash, Linux, Programming — Tags: , , , — sontek @ 5:16 pm

I was helping a friend debug a problem with gksu (gnomesu alternative) today and we chose to use strace which allows you trace system calls an application makes.

To monitor all system calls an application makes you can redirect the output to a file like so:

strace <command> 2> <file name>
or
strace <command> -o <file name>

These commands return the exact same results, the first command redirects stderr (standard error, which has the file descriptor 2) to the file, strace sends all output to stderr by default, the second command uses the built in -o argument which is much cleaner.

One of the first things I like to do with strace is to check if it is having trouble accessing a file, which I see a lot because the file doesn’t exist or the user executing the command does not have permission to access it, you can do that with these commands:

strace <command> 2>&1 |grep open
or
strace <command> -e open

Again, these commands will return similar results. The first command redirects stderr to stdout so you can use grep to filter the output. The second command is the preferred method because it actually uses the built in -e argument which will trace only the named system call (this is a comma separated list so you can do strace -e open,read).

The only other arguments that I’ve found really helpful are -ff which when used with -o will append the pid (process id) to the file name and -F which will also trace children.

Upgrading wordpress

Filed under: Bash, Linux — Tags: , , — sontek @ 4:44 pm

I’m lazy, so I just have this basic script I run that upgrades my wordpress:

#!/bin/bash
blog_directory=
update_url=

wget http://wordpress.org/latest.tar.gz
tar -xzvf latest.tar.gz
tar -zcvf blog-backup-$(date +’%F’).tar.gz $blog_directory
cp -rv wordpress/* $blog_directory
links $update_url
rm latest.tar.gz

How do you upgrade your wordpress?

March 12, 2008

Update Twitter from irssi

Filed under: Linux, Perl, Programming, Twitter, irssi — Tags: , , — sontek @ 11:10 pm

I wrote a quick little perl script/irssi plugin that allows you to update twitter from irssi. It also has autocompletion for names from your friends and follower list. You can get it here: http://devtoo.net/svn/twitter/twitter.pl

To use this script place it in ~/.irssi/scripts and then type /load twitter.pl in irssi

Usage:
/twitter u I’m updating twitter from irssi
/twitter d sontek I’m direct messasging sontek from irssi

DISCLAIMER: First perl script I’ve ever written, i’m sure I’ve done things wrong.

February 20, 2008

Whats in your PS1?

Filed under: Bash, Linux — Tags: , — sontek @ 1:01 am

Theres a discussion going on at reddit about PS1 ( here ).

Mine is:

PS1='\d \t\n\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \n\$\[\033[00m\] ‘

and it looks like:


Wed Feb 20 01:09:15
sontek@inspidell ~
$

Thanks to Chris Crummer for pointing out the reddit post.

February 18, 2008

We are hiring a .NET Developer

Filed under: .NET, C# — Tags: , — sontek @ 3:55 pm

We are looking for a C#/.NET developer and Javascript hacker that thrives in a start-up environment and loves learning and using the latest technologies. We are heavily leveraging the ASP.NET AJAX client library so experience with Javascript and XML/XSLT is a plus.

In addition to designing/developing our main ASP.NET application we will be developing an API for companies to integrate and extend it, so the ability to architect and design extensible software will be a very important aspect of your daily tasks. But, outside of our own API, we will also be integrating with a lot of other company’s data infrastructures, so knowledge of web services/SOAP and the ability to work with remote developers is required.

As an agile team we work closely with our clients on a daily basis so social skills and appearance are important. Being a small team requires that everyone wear multiple hats, so the ability to manage a server or two and a decent understanding of network routing won’t hurt either!

Did I mention we do a *lot* of Javascript? ;)

Some travel will be required.

DISCLAIMER: Its not all super happy fun times in the bleeding edge of technology, we do have our fair share of legacy code that still needs to be tinkered with until this new application graces the world with its presence.

If you think you’d fit in with our team, send us an e-mail with your resume! admin [at] orchidesolutions [dot] com

Salary range is between $45,000 and $65,000.
// About us

Orchid Event Solutions provides registration and housing technologies for managing events and conferences. We maintain an assortment of web and windows applications that serve customers all over the country. Our flagship product—an event management application—is being used for international events as a result of our prominent multilingual support

   
   

January 25, 2008

Progress bar with cp

Filed under: Bash, Linux — Tags: , — sontek @ 9:42 am

Today I found a very informative post on how to get a progress bar with the cp command in Linux.

You can find that blog post here. But I’ll repost the information here in case his blog ever disappears.

With the following bash script:

#!/bin/sh
cp_p()
{
   set -e
   strace -q -ewrite cp -- "${1}" "${2}" 2>&1 \
      | awk '{
	    count += $NF
            if (count % 10 == 0) {
               percent = count / total_size * 100
               printf "%3d%% [", percent
               for (i=0;i<=percent;i++)
                  printf "="
               printf ">"
               for (i=percent;i<100;i++)
                  printf " "
               printf "]\r”
            }
         }
         END { print “” }’ total_size=$(stat -c ‘%s’ “${1}”) count=0
}



You will get a progress bar like this:


% cp_p /mnt/raid/pub/iso/debian/debian-2.2r4potato-i386-netinst.iso /dev/null
76% [===========================================> ]

Newer Posts »

Powered by WordPress