The One and the Many

Tcl scripting module for Irssi

I have written a module for the Irssi IRC client that allows it to run Tcl scripts. Though I am aware that Irssi already supports scripting with Perl, I have already written many scripts in Tcl for Eggdrop, so I am fairly invested in the language. I also am quite fond of Tcl.

Then there is also the challenge involved in figuring out how to get this module to work in the first place. It was far simpler to access Tcl from C and access C from Tcl than I had imagined it would be. The language is designed this way I suppose and so it made this much easier. But it was interesting to figure out nonetheless.

Primarily my desire to be able to run scripts that I had written for Eggdrop on my Irssi client stemmed from the multi-network nature of Irssi as opposed to Eggdrop's single server only (though there are probably ways to run Eggdrop multi-server too...). On my Irssi client I am on 9 networks and sometimes even more than that, and I often found myself wishing I had access to scripts in some channels on various networks where I didn't run an Eggdrop. In order to get these scripts running on channels on those networks I would have had to configure and run another Eggdrop bot just for that network. A big hassle and a waste of resources, especially when I am already running a client on that network which could handle the need easily.

Perl also did not satisfy me on Irssi in some of the scripts I wrote. Or rather one of the scripts I wrote: It would block on HTTP requests and lock up the Irssi UI, whereas the version of urltitle that I wrote for the Tcl module uses Tcl's event system to avoid much of the blocking. Though it is still not perfect and I occasionally notice a bit of blocking with the Tcl version of the script, it is much better than the Perl version. I am aware there are ways around the blocking in Perl scripting for Irssi, one in a lastfm script, but these seem a bit hacky.

Despite what I have said about being able to run Eggdrop Tcl scripts in Irssi, making an already existing Eggdrop script run through this module requires making significant alterations to it. I have documented some of these needed alterations in text files accompanying the source, but actually converting a script is a bit of a headache. Many features and commands are not present in my module; essentially I only added exactly what I needed rather than trying to expose all of Irssi's internals or attempting to replicate what Eggdrop exposes to Tcl.

Though the features are lacking there is still a lot that can be done with the module. Mostly what I do with my Eggdrop bot is work with public triggers, so obviously this is present. And these public triggers can trigger from your own messages so there is no need to run a second Irssi client, though perhaps if one was paranoid this would be a good idea regardless.

It also provides a /tcl command which gives access to a Tcl interpreter. This is the same interpreter in which the scripts are run so scripts can be debugged and worked on in this way.

As to the actual implementation quality I think it is a bit questionable. The module doesn't expose Irssi's hooks and scripting the same way that Perl scripts do. Mostly each part is exposed manually by me writing functions to access Irssi functions and giving these to Tcl rather than whatever the Perl scripting does. But it works.

There is also the way that I do event handling which I think is the cause of the blocking that I mentioned: I handle events by checking Tcl's events with an undocumented Irssi signal which triggers every second. Once this signal triggers events will continue to be handled recursively if there are further events in the queue after this initial trigger. This not only can cause some blocking and is not true event handling, but also obviously has a latency issue as new events are only handled at the beginning of every second rather than right when they are available. I believe this could be handled by hooking into whatever glib event system that Irssi uses internally but I haven't looked further into this either! Essentially I feel how it is right now is a hack, but it works acceptably.

I have written a bunch of scripts that are packaged with the module and by default will automatically load (via scripts.conf). There are also a couple scripts that are not packaged with it as they are a bit more complex.

The included scripts are:

There are also utility/library scripts idna.tcl & irssi.tcl. idna.tcl is for working with international domain names and is not written by me, and irssi.tcl is for core module behaviour.

The only script that is external to the package right now that I've put up is fish-tcl @ I'll probably post about this one later rather than describing it in detail here.

The source for the module can be found on my github:

Tags: eggdrop, irc, tcl, irssi