The Shape of Everything
A website mostly about Mac stuff, written by August "Gus" Mueller
» Acorn
» Retrobatch
» Mastodon
» Instagram
» Github
» Maybe Pizza?
» Archives
» Feed
» Micro feed
December 7, 2005
(This post is from my old, old, super old site. My views have changed over the years, hopefully my writing has improved, and there is now more than a handful of folks reading my site. Enjoy.)

Wednesday, December 7th, 2005

Here's the Lua post I alluded to earlier. It's kind of long, because for some reason I always insist on giving a back story... anyway..

When I released VoodooPad 2.0, one of the major new features was a plugin api that developers could use to extend it's capabilities. There are lots of good ideas out there, but I just don't have time to do them all and I figured this would give people an opportunity to sort of help themselves.

Ha! My customers aren't developers. So why the heck would they write plugins for me? Duh. And besides that, you had to know a funny looking language called Objective-C to write the plugins (or python + pyobjc).

So I had been thinking recently, about maybe an easier way to write plugins for VoodooPad 3.0. Here's what my thought/exploratory process was...

• The first thing that came to mind was python of course, since I really like the language. But it also seemed sort of heavy weight for the task (I don't have anything to back that up, it was just my gut feeling and might be wrong). And integrating pyobjc into my app sort of gives me the willies based on some stuff I did years ago (which I'm sure is a lot better now! Please don't hit me pyobjc guys!). Anyway I just sort of passed on that idea, but I'll probably revisit it later on.

• My next thought was Javascript. Since I'm already loading WebKit, I could just use JavaScriptCore which is built in. But there was no easy way to do what I wanted without creating a webview and messing around with that + writing some custom webkit plugins. Bah, that is just too messy.

• I also briefly considered SpiderMonkey from Mozilla for the JavaScript implementation... but I wasn't having a fun time getting it to work in obj-c.

That was a couple of weeks ago and I hadn't thought about it very much since then.

Then this past weekend as I was skimming past some news feeds in NetNewsWire I saw Jens Alfke briefly mention Lua. I had heard of Lua in the past from various folks, and probably from Jens before as well- and always in a positive way. So I decided to check it out and see how it felt.

Wow. I'm really impressed by this little language. It's got this nice little "python lite" thing going, and an interesting take on data structures. And it was fun. Maybe it was just the newness of it, but I really enjoyed using it.

And one of Lua's purposes is to be used inside of other applications as a general purpose scripting language. Hey- that's exactly what I need! And someone has even written a Lua to Objective-C bridge. Perfect.

So I played around with it in a test app, and got things going remarkably fast. You can bring up a Lua interpreter, run a script, and tear it back down in something silly like 7 lines of code.

Hey, that's easy... let's write a VoodooPad plugin that uses this... I'll just expose the window controller to the Lua environment like I do for normal VP plugins and see what happens... cool, it worked! This stack based approach is a bit odd for me... but that's ok. Hey... lets make this a little more general. I know...

How about a VoodooPad plugin, that loads Lua scripts that work as VoodooPad plugins themselves?

Hey- that's a great idea! clickety, clickety, click It works!

windowController:textView():insertText("Hello World")
So there it is, the simplest example I can give you. Install that in "~/Library/Application Support/VoodooPad/Script PlugIns", and it shows up as a VoodooPad plugin. When run, it'll insert the text "Hello World" into the VoodooPad page you are viewing.

Here's another, more useful script that I actually have an objc version of:

textView = windowController:textView() document = windowController:document() pageName ="%Y.%m.%d", os.time()) document:createNewVPDataWithKey(pageName) textView:insertText(pageName)
That script creates a new page in the document with todays date in the format of 2005.12.07, and then inserts it in the current page making a link to it. Neat! Simple! Fast! With a couple more instructions, I can give it a proper name, and a keyboard shortcut.

So here's some links for you to try out this goodness yourself:

The VoodooPad plugin: The programmer's source: luapluginenablersrc.tgz

This requires VoodooPad 2.5+ to use... and probably 10.4+. Just double clicking on the LuaPluginEnabler.vpplugin should have VoodooPad copy it to the plugins directory and you should be good to go. It then also copies a couple of example scripts into the Script PlugIns directory. "Count of words in document, count of words in page, new page with date, select line, and select paragraph."

I should say, that as of right now this plugin isn't officially supported by Flying Meat. But it's so much fun to play with that I just had to let other people have it. That- and I'm still a Lua idiot, so hopefully people can point out silly mistakes I'm doing.

I should also note that I modified the lau-objc bridge a bit, so that values pass in from objc to lua aren't automatically converted to lua types. I had a good reason for doing this... but it's lost on me now. Something about the differences between mutable and immutable classes. I forget :) Anyway, I created some helper functions to convert strings back and forth, and things like ranges, points, and rects.

And I leave you with one more example, a completely useless one that creates a new window and pops it up on screen (please excuse the memory leak):

r = luaToNSRect({x=100,y=10,width=200,height=200})

window = classFromString("NSWindow"):alloc():initWithContentRect_styleMask_backing_defer(r, 14, 2, 1) window:makeKeyAndOrderFront()

It's so easy!

-- posted 11:31 pm

I noticed yesterday as I was putting VP 2.5 up for release on VersionTracker that Unison 1.7 had just been released as well. After I submitted my apps, and got the email from VersionTracker that all was well, I went back to see my apps listed and to make sure everything was cool.

I then noticed that Unison was listed right above my apps as version 1.7.1. I kind of chuckled to myself and said "Heh- I hate it when that happens".

Anyway, VoodooPad 2.5.1 came out late last night if you hadn't noticed already.. but that just means I'm "agile".

-- posted 11:48 am