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 declarations 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.
Python has list comprehensions,
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 comprehension 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 comprehension.
>>> x = []
>>> for
…continue.
Vim has had syntax highlighting since version 5.0 in 1998.
It quickly became indispensable.
It's hard to go back to looking at monochromatic source code
after you've become accustomed to syntax highlighting.
The syntax highlighting is tied into Vim's support for colorschemes,
which define colors for the fundamental syntax groups
like Number, Comment, and String.
The syntax highlighting for a particular language
defines custom syntax groups for specific language features,
such as cppExceptions or htmlEndTag,
The custom syntax groups are linked to the underlying fundamental syntax groups.
Hence, if you change your colorscheme, your syntax highlighting is updated automatically.
The reStructuredText syntax highlighting in Vim 7.2
has some shortcomings, in my opinion.
For example, …continue.
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 successfully demonstrated this
against a number of applications.
Andrew has a good writeup of Hash Algorithm Attacks.
There are various mitigations 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.
I hate composing anything longer than a couple of paragraphs
in an online HTML editor.
Specifically, 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 reStructuredText (reST), an unobtrusive 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 highlighting of code.
Vim has its …continue.
Tomas Restrepo wrote a post about
sharing dotfiles between Windows and Ubuntu,
specifically about sharing .vimrc (Linux) and _vimrc (Windows)
and the .vim (Linux) and vimfiles (Windows) directories.
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 accumulated 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.
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 alternatives 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.
I've been meaning to play around with Greasemonkey for a couple of years.
Greasemonkey 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 comparisons to Amazon
or thumbnail images to Google search results.
UserScripts.org has a large repository of Greasemonkey 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.
I had a NameValueCollection embedded inside a larger object.
I needed to serialize the larger object into XML and back.
Unfortunately, NameValueCollection is not XML serializable.
Why I do not know.
A blog comment from Tim Erwin got me started in the right direction.
Implement IXmlSerializable and do the work by hand in
ReadXml and WriteXml.
Tim's implementation 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 deserialization 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.
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