Wednesday, September 4, 2013

Batch Processing Alive And Kicking

I'm a busy nerd. I don't have the time to cook every night. I do a week's worth in one batch. I thought I'd share this week's beef stew with you. Enjoy.

 Big Bertha!
 1kg beef mince
 6 big, ripe, juicy, squishy tomatoes.
 4 carrots.
 2 large green capsicums.
 2 small heads of broccoli.
 2 or 3 sticks of celery.
 2 Big onions.
 Ready to go! Mincer on the right.
 Minced vegetables in, ready to puree tomatoes.
 Pureed tomato.
 Beef stock, Worcestershire sauce, pepper, chilli, soy sauce.
 Beans distributed first to ensure equal shares.
 Stew over the beans, ready for the freezer. Yum!
 Clean kitchen, ready for next week.

Makes 12 serves, which feeds the two of us dinners for all but one night of the week. That night we treat as a treat. :-)

Tuesday, September 3, 2013

Roll Your Own

This old dude was hand rolling his own cigars at 8am this morning. He grew the leaves himself, he said. He smokes four of these a day, and rolls himself a bunch every morning, if we understood each other. He asked me where I was from but after frowning his face up and looking off in the distance for a bit, he shook his head and said, 不知道 ("No idea, mate."). Fair enough. Australia is just a minor player in the international scene after all.

I had to trundle off to work and had forgotten all about the morning's encounter until the smell of the fragrant tobacco smoke outside the subway entrance on my way home reminded me. Mr sweeper had a  butt in his mouth as he pottered around downstairs. Ordinarily, I'd be fairly incensed at someone smoking inside, but these home-made cigars actually smelled quite fragrant. What crap the cigarette companies must add to their product?! Go healthy; roll your own.

Egg & Bean Breakfast

One of my favourite breakfasts: Poached eggs with pressure-cooked kidney & lima beans, topped with freshly chopped tomato, onion and parsley. Add a sprinkle of fresh chopped garlic if that's your thing, and a dash of soy sauce or a pinch of salt. Yum!

Lady Autumn is a Dancer

Autumn has come and she's here to dance for me! :-)
The last few days have been so crisp and cool and breezy. It's a very welcome change. I was running out of patience with Summer; if she had a face, I would slap it. But lady Autumn is welcome in my house at any time. I wish she could stay forever. She's my favourite of the weird sisters.

When I was young, Summer was like a playful cousin, full of fun and freedom and warm embraces. Now she's grown tiresome and hateful, punishing us with her hot tongue and ferocious temper.

Winter was a stranger to me in my youth; she never visited us as kids. I didn't meet her until well into my late twenties, and it was not a pleasant acquaintance then. I had heard the rumours of her bitter indifference and icy wickedness, but I wanted to believe she'd been maligned. Alas, they were all true; she struck me down and shrugged and left me to die alone in the cold. I survived that first encounter by luck and fortune and the kindness of strangers. And I'm wiser for it. I have a caged respect for her now and cautious approach. Frequently, when I hear she's coming, I find reasons to be elsewhere and excuse myself from her company.

The songs of Spring are a delight for all; a warming embrace of life and love. While I should be grateful to her for seeing Winter off, I must admit that I find Spring's dusty composure quite irritating. She rarely showers and when she dances her pungent fumes and scratchy pollens stab and scratch at me incessantly. I am quite glad to see the back of her. Or at least I would were it not for Summer thumping at the door.

But there will always be a seat at my table for Lady Autumn, the dancer.

-- for Inga

Tuesday, August 27, 2013

Not Classy, VimLPOO!

Rise, fellow VimLers and cease sobbing onto your consoles about the stink of VimLPOO (VimL Programming Object Orientedly). Vim keeps an open mind and so should you.

tl;dr : VimL OOP can haz class-reopening like Ruby

Okay, maybe not exactly like Ruby, but check it:

VimL’s OOP is more like javascript’s than Ruby’s. It doesn’t have explicit classes. It uses dictionaries to store data and methods that operate on it.

Here is one way in VimL to create an object factory:

function! Kid(name)                  <1>
  let k = {}                         <2>
  let = a:name                <3>
  func k.say(blah) dict              <4>
    echo . ': ' . a:blah
  return k                           <5>

let boy = Kid('Jack')                <6>
let girl = Kid('Jill')
call boy.say('wassup?')              <7>
call girl.say('chillin'' at the hill. u?')
echo boy                             <8>
Jack: wassup?
Jill: chillin' at the hill. u?
{'name': 'Jack', 'say': function('69')}
  1. I like to use the full command form function when creating object factories (classes?).
  2. The object container is a dictionary (hash).
  3. You can explicitly set attributes outside of methods if desired.
  4. I like to use the short command form func for methods. The dict argument tells Vim that this is an instance method, providing us the self. accessor.
    Note You don’t need the ! on method declarations as you do for the outer-level.
  5. The factory must return the newly created object.
  6. Create an instance using the factory.
  7. Call methods using dot notation.
  8. The object in its native format is just a dictionary (hash).
Typically, after creating the object factory, the VimLPOO developer can’t re-open it to augment its behaviour although you can derive a new factory type from an existing one (inheritance without paternity):

function! RudeKid(name)
  let rk = Kid(a:name)               <1>
  func! rk.say(blah) dict            <2>
    echo . ': Yo, biatch! ' . a:blah
  return rk

let boy = RudeKid('Jack')
let girl = Kid('Jill')
call boy.say('wassup?')
call girl.say('wtf?')
echo boy
Jack: Yo, biatch! wassup?
Jill: wtf?
{'name': 'Jack', 'say': function('72')}
  1. Base this object on the parent factory.
  2. Override methods as desired.
    Note The use of ! is now required because the method already exists in the base object.
But I’m not here today to talk about weak inheritance. I wanna play with class re-opening, Vim style.

As a quick recap, a Vim object is a dictionary with data and methods that can use the self. modifier internally to refer to its data and other methods. It turns out that Vim is not too particular about who gets to claim dict access on your objects. You’re free to create external functions, adorned with the dict modifier, and have them manipulate your objects as if they were created with the class originally:

function! s:slapped() dict
  echo . " just got slapped!"

This happens to be a script-local (s:) function; global scope would work too, but why pollute unnecessarily? Now, if you tried to do a naive direct call of this, you’d be sorely disappointed:

call boy.slapped()
Error detected while processing jack_and_jill.vim:
Line   42:
E716: Key not present in Dictionary: slapped

That makes sense… We created slapped() as a script-local function, not a method on the boy instance.
Note Adding the method to the Kid() factory after having created the boy instance would be just as useless.

Happiness is just a call away:

call call('s:slapped', [], boy)

" Jack just got slapped!

:-D How cool is that?!

I have a little project in the works that uses this to allow clients of the engine to inject their own solutions to various parts of the workflow. It’s almost done, so I should be able to show something a bit more real-worldy soon. For now, what mischief can you concoct with this shiny new toy? I look forward to finding out. :-)

Vim on!

Wait, Lost!

85 today; 92 a month ago. Sweet!

... ooh! that caramel macchiato sounds just the ticket! ...

Dieter: In your face, diet! 8-D
Scales: On your waist, dieter.
Dieter: :-/

Monday, August 26, 2013

MPG 1, laowai 0

Mobile Phone Guy: Hey, guy, buy net for phone!
Me: hmm... I dunno... sounds expensive...
MPG: Nah, guy, not expensive. Only 10 RMB!
Me: 10 RMB per...? Month?
MPG: ...sure. Why not? Plenty net. You buy?
Me: hmmm... ok... I'll try it.

... clickety-click ...

MPG: There you go. All done. Door that way. Bye.

... days later, laowai remembers phone net and decides to try it ...

Me: ooh! W00t! I can haz net! Fast too. Like.

... three minutes later ...

Me: oh, a message; let's see... hmm? 10086... I wonder what he wants to tell me...? WTF?! 65 kuai used?! My phone is out of money?! Mobile net, you greedy, lying cheater! Unlike!


Mobile net has since been banished from my phone... good riddance!
Should've trusted my instincts. Foolish laowai. :-/

Sunday, August 25, 2013

Time Out!

So far, nearly every class I've faced in the new job has had at least one 'naughty' kid who makes the whole lesson go painfully slow and frustrating. These are not slow kids - their level of English is usually reasonable. They're not obstinate participants either, in the sense that when called upon to do an activity or contribute to class, they usually begin to do so quickly and competently - they want to participate. The problem is that they lack self-control and deliberately pervert the intent of the lesson by getting out of their seats, running around, fidgeting, disturbing or constantly talking to classmates (in Chinese) and everything else you could imagine a nasty little urchin reaching for on such a disruptive mission.

On the face of it, you could assume that these are merely bright children being insufficiently stimulated in classes that are pitching below their level and so they are misbehaving out of boredom. There might indeed be a degree of that going on too, and that is something I have to consider in my regular reflection sessions. However, the core of the problem, as I see it, is that the children have not been raised (academically speaking) to be courteous and responsible classmates. They have not cultivated the Right Mind of a civil and conscientious student. Okay, granted, they are only ten years old and it might be a bit much for me to expect such grown-up behaviour from little kids, but put another way, that means they've been exposed to five years of inadequate (one might even say abusive) classroom environments resulting in deficient study habits. No doubt a decent portion of blame rests with their parents too, of course. We have some parents who dump their unmanageable child off at a campus as soon as it opens and picks it up as late as possible to buy themselves a day of freedom from the monster they've created. Even if the child has only a few hours of classes at that campus, it is left there all day to terrorize and disrupt. Where's the War On [classroom] Terror squad when you need them?

It's not all of the kids, by a long shot. Most of them are adorable, conscientious, diligent and a delight to teach. The problem lies with a tiny minority (a single child or usually not more than two per room) who are deliberately bent on disrupting the lesson and the teacher as much as possible. This ruins the fun & learning for the other children and darkens the mood of the teacher. If left unchecked, the blackened teacher will devour his next class, angels and all. When we've approached campus management about this problem, we've been given the same response each time: "There's nothing we can do about naughty children. Deal with it. It will be better in the future. Trust me. <Big Smile Saying Get Lost Now>"

This is a depressing situation to walk in on; to be handed classes that were not cultivated with adequate discipline, right etiquette, good morals and diligent study habits. It makes me appreciate even more my prior colleagues' persistent indoctrination of these traits into the minds of our pupils. Thanks, guys! :-*

And I take my hat off to any such professional and conscientious colleagues in my new job.

I've spoken to several of my new colleagues (Chinese staff) about this problem now. Some dismiss the possibility, thinking in their hearts that the fault must lie with me because they don't see such behavioural problems when they take the class. While I may still indeed have much to learn about child psychology and classroom discipline that my ten years as an English teacher has not yet taught me, I consider this response to be naive at best and insulting and malicious at worst.

Instead of pretending that there is no fault, try instead sitting in on a few lessons to observe what behavioural problems the foreign teacher is talking about. In this way, you can give appropriate suggestions to the foreign teacher and admonish blatant misbehaviour in errant children as it happens. I'm not asking for presence in every class, but currently there is a disconnect in the minds of the children between our classes and those of the Chinese English teaches. The kids see our classes as game time only, treating them as a circus.

I have sat in on several Chinese lessons in my short few weeks in this new job and the same kids were much better behaved in their classes than they were in mine. One reason I believe for this is the use of the Chinese language spoken by the Chinese English teacher. When an admonishment is sharply barked at a kid in his native language (L1), he can't help but understand it and instinctively comply with it. Additionally, he knows that if he doesn't curb his behaviour then the teacher can inform his parents, or at least threaten to. The kids know we foreign teachers do not have this power, so they take this as license to misbehave with impunity.

Kids merely laugh at a foreign teacher who tries to threaten in English - picture The Simpson's "Santa's Little Helper" watching Homer screaming at Bart. Not understanding the words involved, he's left with Homer's oafish arm waving, reddened face and incomprehensible gibberish. Comical. And that's the problem. Instead of receiving a cautionary message for the child to calm down and pull his head in, he bursts out laughing and steps up the comedy act with increased hooliganism. It takes a patient teacher to respond to that with less than exasperation.

Of course, the take-away here is: Don't raise your voice and wave your arms around. Doing so merely makes you look just like the clown you're trying to distance yourself from in the first place. Instead, address the kid with silence and a closed body posture (arms down, square-facing, plain or stern face, and hold eye contact) and use corrective gestures to cease his current behaviour and lead him toward your desired behaviour. Silence is a much more devastating weapon than shouting. There are myriad other behavioural correction tools in the trade too, like tracking smilies and frownies on the board per kid, and rewarding participation & good behaviour with points (e.g. stars on the board) that have some real-world value somehow (e.g. 50 stars buys you a pencil sharpener, etc). And I do all that and more. But the abhorrent little delinquents I bemoan here today merely shrug their shoulders and smirk in indifference when I remove a star from their name for committing a transgression. They understand there is a rewards and punishment system, but they don't care to be a part of that system. It's very much like these kids have been placed outside of the system or have worked their way out themselves over the years and, looking in on it from the outside, they feel no connection to or love for it at all. Lost pupils.

I have successfully rebuked bad behaviour with short commands in Chinese. I think this will be a part of my effective strategy in future, but it would be sad if this were my only tool; sadder still if the need for it were to persist. Such a situation would indicate a failure to properly address the source of problematic behaviour, relying instead on this poor, blunt-force treatment of the symptom only.

Officially, of course, the foreign teachers are forbidden to use Chinese in class, which would take even this recourse from us. I choose to believe that after ten years of doing this job, I know well the difference between effective & irresponsible uses of L1 in the classroom. I'll use the right language for the right situation and the students' needs.

So, I am left now with how to better handle the problem of deliberately disruptive children in class. I am looking for advice and support for this problem.

Then again, I'm in two minds about this. First, it's a weekend job and if management, parents & colleagues don't care to address the problem, then our efforts in this direction will not be rewarded (indeed, may be punished) and instead we will be resented by all players, leaving us drained and depressed. On the other hand, if I truly see myself as an educator then a big part of my job is to address the morals, behaviour & study habits of my students. To be told by management that we can't do anything about naughty kids is insulting because they are putting profits ahead of education at the cost of our sanity and the customers' true benefit.

Tolerance of bad classroom behaviour is academic negligence.

Friday, August 23, 2013

It's Not What It Is; It's What We Say It Is

Swim to the shore...

The lessons were advertised as being forty-five minutes. They failed to mention, even in the fine print, that two such lessons are run back-to-back. When asked if that wasn't really just a single ninety minute lesson instead, they merely doped upon me the now very familiar look reserved for someone who's just made the socially unacceptable blunder of pointing out a reality contrary to the pre-established delusion.

Swim, like a mofo.

Monday, August 19, 2013

Geez, I Love Mondays

For the first time in many years, the customarily despised Monday has become a time of relief, recuperation and even rejoice. This absurd affair owes to working weekends, an arrangement furnishing me with a visa to stay here legally and the dollars to do so comfortably. Sadly, the Conservation of Misery principle demands recompense for this surplus of weekly joy, duly evidenced by the mess of Friday de'Night, Mostof Saturday and Allday Sunday lying beaten and bloody in the gutter.

Requiescant in pace dies felices.

Friday, August 16, 2013

Killer Artwork


Q: When is a zebra crossing not a zebra crossing?
A: In China!


They have zebra crossings here, but rather than act as traffic ordinance, they're merely pieces of artwork, carelessly disregarded by pedestrian and driver alike. For foreigners new to China, these pavement paintings are very dangerous indeed; wrongly assuming that they carry familiar authority is a sure way to end up under a bus (or truck, car or e-bike), adding your own crimson hue to the hapless drawings underfoot. Traffic lights have some following here, but many remain unbelievers and are yet to be converted to the faith. There is a strong adherence to the traditional belief models of "I was here first, so I get to go first" and "I'm bigger than you, so I get to go first". While these two schools of thought may at first appear to share common ideology, clashes between their respective proponents can often be observed at intersections all over the country. For new arrivals to the wilds of China's urban roads, my advice is to ignore any street signs, traffic lights and doodles on the bitumen and just follow the crowds. Don't follow the lone maverick straying across three lanes of flowing metallic indifference but rather clump with the herds crossing en masse at bewilderingly unpredictable moments in the chaotic gush and sputter (nothing ever truly stops) of torrential traffic.

Good luck.

Saturday, August 10, 2013

Rimming Vim

Vimmer, Luke Gruber, has released Riml, a ``Coffeescript for VimL``.

It looks pretty interesting at a distance.
I started dabbling with the beginnings of this idea a few years back, but Vigoriously never got past the Interesting Idea and Handful of Test Scripts stage. Kudos to Gruber for reaching the finish line.

I wish I had the time to play with it.

Tuesday, August 6, 2013

Wishing Birthday Happiness to a Vimmer

Ah, Raimondi!^[O, happy days^[D0wellmaiBro^[bai^[toayouth^[FoXxx,xJvex0xx

Friday, July 26, 2013

I Do Not Love Uranus

I Do Not Love Uranus

(C) Barry Arthur, 2013

It waters my eyes and stings my nose;
Chokes my throat and curls my toes.
I turn my head and close my mouth,
But it's too late! I've a lungful now.

Oh, I love,
Mercury, Venus, Earth and Mars;
The moon above and all the stars.
Any planet you could name us;
But I do not... Love your anus.

You blame it on the neighbour's cat
But he stopped visiting ages back.
It's like I'm living with a bloated cow -
There must be something wrong with that bowel!

Oh, I love,
Anything fast and loud and hot;
Ridden or driven or flown or shot.
Planes and trains and bikes and cars;
But I don't love your stinky arse!

You blame it on the prunes and beans.
And it's not your fault; And I'm being mean.
That it's the microbes in your gut
That give you such a manky butt.

Oh, I love,
Mercury, Venus, Earth and Mars;
The moon above and all the stars.
Any planet you could name us;
But I do not... Love your anus.
Oh I do not... Love your anus.
No I do, do not... Love your anus!


(condolences to the flatulent)

Friday, July 12, 2013

Vimmers Don't Die


(apologies to Cat)
Remember the days of the old #vim?
We used to chat a lot.
Oh, don’t you remember the days of the old #vim?
When we had free time to flirt and we solved all kinds of hurt.
And we lol’d and offered :help
Yes, I do. Oh, and I remember you!

Remember the days of the old #vim?
We used to laugh a lot.
Oh, don’t you remember the days of the old #vim?
When we had seven point three and regex simplicity.
And we lol’d and offered :help
Yes, I do. Oh, and I remember you!
<3, #vimmers. Feed vimgor for me, and remember to take him for a walk now and then. :-*
I was always in favour of kicking cats:

Saturday, May 11, 2013

Vim Fairy Godmother, The Mug

The Vim Fairy Godmother

Vimmers know their magical editing prowess is bestowed upon them by the Vim Fairy Godmother. Celebrate her awesomeness with your very own decorative mug!
Vim Fairy Godmother
Vim Fairy Godmother by VimAndVigor
Create one-of-a-kind personalized cups from

Monday, April 22, 2013

Sort Me A Column

Need to sort a column within your table without messing with the other columns?
Vim has your back with blockwise visual selections and a bit of gymnastics.

Sample table:
1 this 1 apple    is 1
2 this 4 durian   is 2
3 this 3 carrot   is 3
4 this 2 banana   is 4
5 this 5 eggplant is 5

Desired result:
1 this 1 apple    is 1
2 this 2 banana   is 2
3 this 3 carrot   is 3
4 this 4 durian   is 4
5 this 5 eggplant is 5

[wrong] Result of naive :sort command:
1 this 1 apple    is 1
2 this 4 durian   is 2
3 this 3 carrot   is 3
4 this 2 banana   is 4
5 this 5 eggplant is 5

[wrong] Result of :sort /^. / command (to skip leading numbers):
1 this 1 apple    is 1
4 this 2 banana   is 4
3 this 3 carrot   is 3
2 this 4 durian   is 2
5 this 5 eggplant is 5

A Solution

  1. Visually select the column of interest with ctrl-v
  2. Cut it with x
  3. Open a temporary scratch buffer with :enew
  4. Paste with p
  5. Sort with :sort
  6. If you need to, ensure your cursor is line 1, col 1 with gg0
  7. Visually select and yank everything, blockwisely with ctrl-vG$y
  8. Switch back to where you came from with ctrl-6 (ctrl-^)
  9. Jump to the start of your original cut with `[
  10. Paste with P

Sunday, April 21, 2013

Sohi Vila

Clearly, I use Blogger. That I use asciidoc to write my blog posts might be less obvious. For the most part, it works fine. There is, however, one little thing that has been annoying me all this time…

The blogger backend for asciidoc uses the html4 stylesheets which don’t seem to be compatible with pygments (my preferred syntax highlighting solution). I guess I could have tried to bash the blogger backend into using html5 or xhtml11 to get pygments, but there were too many unknowns there to make that worthwhile investigating. The other alternative was to get asciidoc’s default highlighter to love Vim.

Asciidoc’s default syntax highlighter is GNU source-highlight. For the most part, it does a reasonable job. Why it doesn’t support Vim files out of the box is beyond me. SohiVila fixes that problem.

Here’s some VimL lovingly rendered with it:

" PrintWithHighlighting()
" Original Code by Jürgen Krämer on vim-dev
" Modified by Barry Arthur, 2013-03-21
" Usage:
" * As a subcommand to the :g// command
" :g/something/P
" * As a standalone command
" :1,10 P
" :%P
" :P

function! PrintWithHighlighting() range
  for line in getline(a:firstline, a:lastline)
    let ms = match(line, @/)
    let me = matchend(line, @/)

    while ms != -1
      echohl none
      echon strpart(line, 0, ms)
      echohl Search
      echon strpart(line, ms, me - ms)
      echohl none
      let line = strpart(line, me)
      let ms = match(line, @/)
      let me = matchend(line, @/)
    echon line . "\n"

command! -range P <line1>,<line2>call PrintWithHighlighting()

Saturday, April 20, 2013

Partial Explosion

Vim has a powerful regex spell, :help /\%[] . While it might look like the emoticon of a lunging crocodile, this little piece of regex lets vimmers match words in either their full form or any partial reduction thereof. That’s a messy explanation. A showing will help:

The pattern:


Will match: r, re, rea, and read

Unicorns, I know!

This actually gets a lot of love in Vim’s syntax highlighting file for its own language, VimL. I wish it didn’t to be honest. I actually deplore the availability of partial keyword forms like fu instead of the full form function. But that’s not why we’re here today, so let’s move on.

Not all regex engines support this awesome atom. In fact… I don’t know of any other that does.

I am in the process of creating a vim.lang file for source-highlighter. As you would expect, it has a regex based DSL for specifying syntax items. One such item is for keywords. Easy!, I thought, I’ll just grab the keywords from Vim’s syntax files and… oh, crap… It’s infested with \%[]

So… Let’s explode them.

With a quick regex, I got the Vim keywords split out onto separate lines, like this:


And then we can explode out the partial variations with this little regex:

:%s/^\(.\{-}\)\[\(.\{-}\)\]/\=join(map(range(len(submatch(2))+1),  'submatch(1).strpart(submatch(2), 0, v:val)'), ' ')/


arga argad argadd
ar arg args
bn bne bnex bnext
breaka breakad breakadd

And just in time for dinner, too.

I'd Tap That

The Ruby world and many others have a tap() method on a class way up in the hierarchy near God that lets the bug hunting developer peek inside of objects during execution to see what the gnomes are getting up to under the covers. I needed just such a tool for my latest dabblings in Vim, so I built one and thought I’d share it here:

function! Tap(thing)
  echom string(a:thing)
  return a:thing

It’s not very intimidating, I know, but thats a little gem of a function. I used it to debug the setting of the includeexpr option in Vim, as shown here:

set includeexpr=Tap(substitute(Tap(v:fname),'\\${\\?\\(\\w\\+\\)}\\?','\\=expand(\"$\".submatch(1))','g'))

I was suspicious that the v:fname variable was not being set properly before includeexpr was being evaluated by Vim. Tap() proved that to be the case which allowed me to focus my debug efforts on the real cause, instead of continuing to waste time fretting over the search and replace patterns in the substitute and whether I’d escaped them correctly or not. I only wish the Tap() inspiration had come to me sooner than it really did. Oh well… with Tap() as a permanent fixture in my ~/.vimrc, hopefully it won’t take me as long to think of it the next time I need its services.

Tuesday, April 16, 2013

The Bodhi Distro

Waving, Not Drowning

#bodhilinux (freenode):

11:37:07           pug | anyone awak?
11:37:10           pug | awake..
12:05:42       sceptic | nah pug nobody is ever here anymore
12:06:39       sceptic | it's pretty much a dead distro
12:18:50    faithless1 | sceptic more like dead channel
12:20:18           <-- | faithless1 (~faithless1@ has quit (Quit: Abandonando)

Our distro is the Bodhi, right?
Yet our channel burns not bright.
Carefully chat you by and by
And let no scpetic ill imply.

Neither is there Bodhi distro;
Nor yet a channel dead.
Snce in reality all is Void,
What you miss is in your head.

Apologies to Hui-neng.

I have recently switched to the Bodhi distro after Ubuntu 12.x made an utter mess of the i915 Intel video drivers. I tried Bodhi a few versions and many months ago. I liked it then and I was reminded why upon my return now. It is a very pretty distro and yet has the stability of the Ubuntu repositories behind it. Hopefully this time I get to sit for longer under the Bodhi tree.

Saturday, April 6, 2013



We've all been there before; all too often, in fact. There you are in the middle of a serious edit when all of a sudden some vile little gremlin spits at you from deep within Vim. "Argh!" You instantly seethe with indignant rage, vowing to righteously lance that festering pustule...! when the terrifying realisation strikes you - you don't know where this bug is coming from. "Gack." You say as you think to yourself: "It must be one of the plugins... surely? Ok... it could be in my ~/.vimrc... But no! I watered it only yesterday and there were hardly any weeds there. So, it's a plugin... But... which one? How am I supposed to find the menacing little urchin among all those other well behaving citizens in my plugin pool?" Historically the Vimmer faced with this situation has had very little option but to manually move plugins aside until the faulty one is found. This is a laborious, boring and very frustrating task. Even if you knew well enough to use binary search to speed up the process, it's still not something anyone wants to do. Thankfully now, you don't have to. Now, you can do it with Bisectly.

Bisectly is a plugin-manager agnostic fault localisation tool for finding which plugin is causing you nose-bleeds.

Bisectly uses BSFL (Binary Search Fault Localisation) to quickly whittle down the set of loaded plugins in search of the one causing you pain. It uses a cutesy command interface to identify which sessions the user considers fault-free (:Unicorns) or faulty (:Zombies). This process continues until a single plugin remains, which Bisectly considers to be the guilty party.

Plugin Manager Agnostic

Bisectly interrogates your normal Vim for its final set of &runtime paths before juggling those in the BSFL algorithm. As such, it should be completely independent of any plugin manager. I have tested it with pathogen only, but I don't foresee any issues with Vam or Vundle. Feedback appreciated on this.

Possible Futures

My original idea for the Zombies Vs Unicorns theme was actually in regard to using BSFL on locating faults within a user's ~/.vimrc file. I have a plugin that is all-but-finished for this purpose but it has been delayed until a better vimscript parser can be completed. Work on that is currently in progress.

I have dabbled with various solutions to this problem over the last year or so. Most of the other solutions were tied to pathogen or were broader, more generic endeavours (stretching beyond the realm of Vim). All of those solutions, though, utilised an automated testing framework to very rapidly locate the faulty component - in a matter of seconds. I had the idea for this incarnation of Bisectly today and rushed out the simpler manual code while it was fresh in my mind. However, I do intend to revisit this plugin to add support for an automated test framework.

Saturday, March 16, 2013

The Path of a Master VimLer

An apprentice approached a Master and said,
“Show me your best Vim.”
to which the Master responded,
“Everything in my Vim is best.
You cannot find here any piece of Vim that is not the best.”
At these words, the apprentice became enlightened.

What might the path to VimL mastery look like?
Here's what Raimondi & I think at the moment:

Trainee → Novice → Worker → Professional → Expert
  1. Trainee
    • Read the following parts of :help cmdline.txt
      • 3. Ex command-lines :help cmdline-lines
      • 4. Ex command-line ranges :help cmdline-ranges
      • 6. Ex special characters :help cmdline-special
    • Read the following parts of :help options.txt
      • 1. Setting options :help set-option
      • The following specific options:
        • :help 'debug'
        • :help 'eventignore'
        • :help 'ignorecase'
        • :help 'magic'
        • :help 'maxfuncdepth'
        • :help 'runtimepath'
        • :help 'verbose'
    • Read all of :help pattern.txt
    • Read the following parts of :help eval.txt
      • 1. Variables :help variables
      • 2. Expression syntax (skim) :help expression-syntax
      • 3. Internal variable :help internal-variables
      • 5. Defining functions :help user-functions
      • 7. Commands :help expression-commands
      • 9. Examples :help eval-examples
    • Read sections 41.1 - 41.8 in :help usr_41.txt
    • Read :help function-list (Vim’s built-in VimL library)
    • Read
    • Read
    • Pass the Trainee assessments
  2. Novice
    • Contribute bug fixes and small enhancements to existing plugins.
    • Read :help map.txt
      • Read :help 'timeout' option
      • Read :help 'maxmapdepth' option
    • Read :help usr_40.txt
    • Read :help autocmd.txt
    • Read :help filetype.txt
    • Read :help various.txt
      • In regard to :normal, read :help motion.txt
    • Pass the Novice assessments
  3. Worker
    • Read :help eval.txt
    • Read :help usr_41.txt
    • Create three or more plugins under the supervision of a Professional or Expert
    • Assist Novices
  4. Professional
    • Actively support five or more peer-reviewed, fully usr_41 compliant plugins
    • Thoroughly document all supported plugins
    • Supervise Workers
    • Assist in the development of reference & resource materials
    • Participate in discussions about best practice for VimL development
  5. Expert
    • Create new tools and libraries for VimL development
    • Create new/interesting/engaging/fun reference material or tutorials for an aspect of Vim/VimL
    • Mentor, guide and train other VimLers
    • Maintain a regular presence on Stack Overflow, the vim-dev mailing lists, #vim or #viml as an authority and guide on advanced Vim and VimL topics

A Plan for Assessing VimL Skills

A central registry of available assessments:
A master github repo called that contains a list of VimLAss_<level_name>_<assessment_number> github repos in the various skill levels that act as assessments.
  1. Trainee:

  1. Novice:
    • VimLAss_Novice_010 — usr_41 compliance: use <Plug> maps

Creating New VimLAss Assessment Repositories

To create a new VimLAss assessment piece, just copy the VimLAss_Skeleton repository which has the following layout:
  • — an overview of the assessment and a detailed set of tasks to be completed
  • test/<task>.vim — one or more test files per task as listed in the
  • plugin directories with files as necessary. e.g.:
    • autoload/
    • doc/
    • colors/
    • compiler/
    • ftdetect/
    • ftplugin/
    • indent/
    • plugin/
    • syntax/
All VimLAss repositories are to use the unit testing framework. The repositories should contain tests for expected behaviour that initially fail. Corresponding tasks in the file detail the necessary fixes and enhancements that the vimmler is supposed to implement to get the tests to pass. Successful completion of the assessment begins with having all tests pass. The vimmler should then apply to a Professional/Expert vimmler to have his work reviewed, gain feedback and get his assessment signed off. Actual signoff could involve digital signatures, if that path was ever deemed necessary, which is unlikely.

Even though I have provided some links to various pieces mentioned above, all of this is still very much in thought space at the moment.

I am sure we haven’t covered all bases yet. Do you have anything to contribute?

Saturday, February 9, 2013

Crackers, Car Alarms And Gunpowder

Ah... the sweet sounds and smells of New Year celebrations in China.

And now we have fifteen days of fireworks to thump the new year in properly.

Happy CNY 2013, everyone. Beware the sneaky snake.

SinTax Overdue

Syntax highlighting in Vim sucks.

I know. I haven't done as much of it as you have, but I've heard your cries from my cubicle, your desperate pleas for compassion whispered over and again at your desk to an uncaring Vim, your brave face masking knots of terror while chatting at the water cooler, and your wails of despair in the toilet stall when you thought everyone else had gone. It's been hard watching you go through this and for long now I've wished there was something I could do to ease your burden, to still your trembling hand, wipe the tears from your keyboard and tell you that "It's going to be okay." Of course, I couldn't do that. Nobody could. I'd be lying and you know it. My words would come across as naive, empty platitudes at best or, at worst, taken for cruel taunts to mock your effort, halt your progress and rob you of your due standing among the Nerds of Vim.

That was how we all lived. That is... before THEY came!

SinTax is a Vim plugin that provides a DSL for crafting syntax highlighting files.

It takes this:

" Vim syntax plugin for filetype name.
" Maintainer: Barry Arthur <>
" Israel Chauca F. <>
" Version: 0.1
" Description: Long description.
" Last Change: 2013-02-01
" License: Vim License (see :help license)
" Location: syntax/vrs.vim
" Website:

name    vrs
case    ignore
spell   default

keyword vrsTodo    .Todo : TODO FIXME XXX

partial token \S\+\s\+

partial separator
      \\}          # an_escaped_\}
    \|             # or
      [^}]         # anything_but_a_}

match vrsNameErr   .Error      contained : ^\%{token}

match vrsName      .Identifier contained : ^\w\+\s\+

match vrsFlavorErr .Error      contained
    ^\%{token}     # if_the_line_starts_with_a_token
  \)\@<=           #   before
  \%{token}        # a_token

match vrsFlavor    .Type       contained
    ^\%{token}     # if_the_line_starts_with_a_token
  \)\@<=           #   before
  \%{vrsName}      # a_vrsName

match vrsCompItem  .Normal     contained
    \w\+           # a_word
  \|               # or
    \d\+           # a_number
  \|               # or
    ,\@<=          # a_separator_if_proceeded_by_a_comma

" match a composition atom: \%{pattern-name,count,separator}
match vrsCompose   .PreProc    contained contains=vrsCompItem
  \\%{             # a_literal_\{
    \S\+           # a_word_(pattern-name)
    ,              # a_comma
    \d\+           # a_number_(count)
    ,              # a_comma
    \%{separator}* # an_optional_separator
  }                # and_a_literal_}

match vrsRegExp    .String     contains=vrsCompose contained
    ^\%{token,2}   # if_the_line_starts_with_two_tokens
  \)\@<=           #   before
  .*               # anything

match vrsCommand              contains=vrsName,vrsFlavor,vrsNameErr,vrsFlavorErr,vrsRegExp,vrsComment
  ^\%{token,2}\S.* # a_line_with_three_'tokens'_minimum

match vrsContinued .String     contains=vrsComment
  ^\s\+\S.*        # a_line_with_leading_whitespace_and_a_'token'

match vrsComment   .Comment    containedin=ALL contains=vrsTodo
  \%(              # as_long_as
      \\ \\        #   (ignoring_any_number_of_double_backslashes_(\\))
    \\             #   a_backslash
  \)\@<!           # doesn't_precede
  #.*$             # a_literal_#_followed_by_anything

match vrsError     .Error
  ^                # any_line_starting_with
  [^a-zA-Z0-9_#\ ] # anything_that's_not_alphanumeric,_underscore,_hash_or_a_space
  .*               # and_anything_afterwards

And generates this:

" Vim syntax plugin for filetype name.
" Maintainer: Barry Arthur <>
" Israel Chauca F. <>
" Version: 0.1
" Description: Long description.
" Last Change: 2013-02-01
" License: Vim License (see :help license)
" Location: syntax/vrs.vim
" Website:

" Quit when a (custom) syntax file was already loaded
if exists("b:current_syntax")

" Allow use of line continuation.
let s:save_cpo = &cpo
set cpo&vim

syntax case ignore
syntax spell default
syntax keyword vrsTodo  TODO FIXME XXX 
syntax match vrsNameErr /^\S\+\s\+/ contained 
syntax match vrsName /^\w\+\s\+/ contained 
syntax match vrsFlavorErr /\%(^\S\+\s\+\)\@<=\S\+\s\+/ contained
syntax match vrsFlavor /\%(^\S\+\s\+\)\@<=^\w\+\s\+/ contained
" match a composition atom: \%{pattern-name,count,separator}
syntax match vrsCompItem /\w\+\|\d\+\|,\@<=\%(\\}\|[^}]\)\+/ contained
syntax match vrsCompose /\\%{\S\+,\d\+,\%(\\}\|[^}]\)*}/ contained contains=vrsCompItem
syntax match vrsRegExp /\%(^\S\+\s\+\S\+\s\+\)\@<=.*/ contains=vrsCompose contained
syntax match vrsCommand /^\S\+\s\+\S\+\s\+\S.*/ contains=vrsName,vrsFlavor,vrsNameErr,vrsFlavorErr,vrsRegExp,vrsComment
syntax match vrsContinued /^\s\+\S.*/ contains=vrsComment
syntax match vrsComment /\%(\%(\\\\\)*\\\)\@<!#.*$/ containedin=ALL contains=vrsTodo
syntax match vrsError /^[^a-zA-Z0-9_#\ ].*/ 
syntax match vrsError /foo/ 

hi def link vrsTodo Todo
hi def link vrsNameErr Error
hi def link vrsName Identifier
hi def link vrsFlavorErr Error
hi def link vrsFlavor Type
hi def link vrsCompItem Normal
hi def link vrsCompose PreProc
hi def link vrsRegExp String
hi def link vrsContinued String
hi def link vrsComment Comment
hi def link vrsError Error
hi def link vrsError Error

let b:current_syntax = "vrs"

let &cpo = s:save_cpo
unlet s:save_cpo

" vim: set sw=2 sts=2 et fdm=marker:

Now I feel more equipped to take your hand and say, "there, there."

Depends On: Raimondi's VimRegStyle
Coming Soon! SinTax is still in development but is ready for user testing. Feedback welcome.