George V. Reilly

Exuberant Ctags and JavaScript

Exuberant Ctags is an essential complement to Vim: it generates an index of symbol names (tags) for a set of source files. In Vim, just place the cursor on a function name and type C-] to go to its definition.

Ctags works well for most of the languages that I deal with, but falls down badly on modern JavaScript. Its built-in parser simply doesn't handle de­c­la­ra­tions like these:

Sizzle.selectors.filters.animated = function(elem) { // ...
ajaxSetup: function( settings ) {

I came across Unbad's workaround earlier tonight. His code didn't work for me, so I hacked on it until it did:

--langdef=js
--langmap=js:.js
--regex-js=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\{/\1/,object/
--regex-js=/([A-Za-z0-9._$()]+)[ \t]*[:=][ \t]*function[ \t]*\(/\1/,function/
--regex-js=/function[ \t]+([A-Za-z0-9._$]+)[ \t]*\(([^)])\)/\1/,function/
--regex-js=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\[/\1/,array/
--regex-js=/([^= ]+)[ 
continue.

Flattening List Comprehensions in Python

Python has list com­pre­hen­sions, syntactic sugar for building lists from an expression.

>>> [2 * i for i in (2, 3, 5, 7, 11)]
[4, 6, 10, 14, 22]

This doesn't work so well when the com­pre­hen­sion expression is itself a list: you end up with a list of lists.

>>> def gen():
...     for l in [['a', 'b'], ['c'], ['d', 'e', 'f']]:
...         yield l
...
>>> [l for l in gen()]
[['a', 'b'], ['c'], ['d', 'e', 'f']]

This is ugly. Here's one way to build a flattened list, but it's less elegant than the com­pre­hen­sion.

>>> x = []
>>> for 
continue.

reStructuredText syntax highlighting

Vim has had syntax high­light­ing since version 5.0 in 1998. It quickly became in­dis­pens­able. It's hard to go back to looking at mono­chro­mat­ic source code after you've become accustomed to syntax high­light­ing.

The syntax high­light­ing is tied into Vim's support for col­orschemes, which define colors for the fun­da­men­tal syntax groups like Number, Comment, and String. The syntax high­light­ing for a particular language defines custom syntax groups for specific language features, such as cppEx­cep­tions or htmlEndTag,

The custom syntax groups are linked to the underlying fun­da­men­tal syntax groups. Hence, if you change your col­orscheme, your syntax high­light­ing is updated au­to­mat­i­cal­ly.

The re­Struc­tured­Text syntax high­light­ing in Vim 7.2 has some short­com­ings, in my opinion. For example, continue.

Hash Table Attacks

At lunch today, I told Eric about Hash Attacks: for many hash functions, it's possible to construct a large set of keys that collide. This can be used to cause a Denial of Service as hashtable operations can be induced to take O(n) time instead of O(1).

Crosby and Wallach suc­cess­ful­ly demon­strat­ed this against a number of ap­pli­ca­tions.

Andrew has a good writeup of Hash Algorithm Attacks.

There are various mit­i­ga­tions suggested. The one that I used when I first became aware of this problem is to use a salt to the hash function.

In other words, change:

unsigned hash(const char* s)
{
    unsigned h = 0;
    while 
continue.

reStructuredText

I hate composing anything longer than a couple of paragraphs in an online HTML editor. Specif­i­cal­ly, I hate writing posts for this blog online. I'd much rather write in Vim and upload HTML. But I don't want to compose in raw HTML either.

I use re­Struc­tured­Text (reST), an un­ob­tru­sive plaintext markup language popular in the Python world. reST can generate HTML, LaTeX, native PDF, ODF, and other formats. The picture at right shows a draft of this document in MacVim; reST is, as you can see, quite readable (though I work with a larger font). I use restview to preview the HTML locally and Pygments for syntax high­light­ing of code. Vim has its continue.

Sharing Dotfiles between Windows and \*nix

Tomas Restrepo wrote a post about sharing dotfiles between Windows and Ubuntu, specif­i­cal­ly about sharing .vimrc (Linux) and _vimrc (Windows) and the .vim (Linux) and vimfiles (Windows) di­rec­to­ries.

I have a different solution. On Windows, my C:\AutoExec.bat includes:

set HOME=C:\gvr
set VIM=C:\Vim
set VIMDIR=%VIM%\vim71
set EDITOR=%VIMDIR%\gvim.exe
set PATH=%PATH%;C:\Win32app;C:\GnuWin32\bin;C:\UnxUtils;C:\SysInternals;C:\Python25\Scripts

%HOME% (C:\gvr) contains _vimrc, vimfiles, and other stuff ac­cu­mu­lat­ed over many years. This directory is stored in a personal Subversion repository at DevjaVu. All my Vim files are stored with Unix LF endings, not Windows CR-LFs, so that they'll work on my Mac OS X and Linux boxen. I play some games with if has("win32") and if has('gui_­macvim') to ensure that my _vimrc works cross-platform.

On my *nix boxes, the gvr continue.

Er, er

I've grown fond of the JavaScript || idiom:

function FrobImage(img) {
    var width  = img.width  || 400;
    var height = img.height || 300;
    // ...
}

FrobImage({height: 100, name: "example.png"});

If img.width exists and it's truthy, then width = img.width; otherwise, width = 400. Here, it will be 400 since the img hash has no width property. More than two al­ter­na­tives may be used: x = a || b || c || ... || q;

A few weeks ago, while cleaning up the error handling in some batch files, I came across a similar idiom:

foo.exe bar 123 "some stuff"  
continue.

Greasemonkey for demos and mockups

I've been meaning to play around with Grease­mon­key for a couple of years. Grease­mon­key is a Firefox extension that allows users to install scripts that make on-the-fly changes to the look and feel of third-party websites. For example, adding price com­par­isons to Amazon or thumbnail images to Google search results. User­Scripts.org has a large repository of Grease­mon­key scripts.

I finally built my first script the other day. We're putting together a new feature at Cozi that integrates partner websites with our site. Since the feature is not yet announced, I'll just say that partners will add a link to Cozi on many of their database-driven pages. That link has a complex, continue.

Serializing a NameValueCollection

I had a NameVal­ueCol­lec­tion embedded inside a larger object. I needed to serialize the larger object into XML and back. Un­for­tu­nate­ly, NameVal­ueCol­lec­tion is not XML se­ri­al­iz­able. Why I do not know.

A blog comment from Tim Erwin got me started in the right direction. Implement IXmlSe­ri­al­iz­able and do the work by hand in ReadXml and WriteXml.

Tim's im­ple­men­ta­tion turned out to be overly simple. It didn't handle an empty collection well, nor did it leave the XmlReader in a good state.

I used SGen to examine the de­se­ri­al­iza­tion of a List<String> to figure out what else needed to be done.

The following ReadXml seems to work. If I expected to receive XML from continue.

NUnit calling CppUnit

Over the last few days, I've been adapting an existing native C++ library so that it can be called from managed code. I had written a large number of unit tests with CppUnit and I wanted to be able to call the tests from NUnit.

I suppose that I could have written a new CppUnit TestRunner so that I could call it from NUnit. Instead, I took the cheap-n-dirty route, playing with #define and include paths. It took less time to get working than it did to write this blog post.

Here's the original native CppUnit test code

//-------------------------------
// native\FooTest.h
//-------------------------------

#include <cppunit/extensions/HelperMacros.h>

class FooTest : public CppUnit::TestFixture
{
    CPPUNIT_TEST_SUITE( FooTest 
continue.
Previous » « Next