Hi Rob, You write almost as much as I do. Maybe its a common trait in text editor folk. We Love Text!
> Yes, Dusty, welcome to the Text Editor Writers support group! I'm > hopeful that we can all continue to share ideas and code. In writing > peppy, I started off as a pet project where I was writing most of my > own stuff, but as it got bigger, there was more to debug. I started > thinking that it would be a good idea to let the time spent by others > not go to waste. So, I started shamelessly borrowing code. Indeed, I'm considering changing to a GPL license so as to make this more possible... not so much so I can borrow code because I'm a chronic rewriter. I even rewrite my own code. (Pallavi has been rewritten from scratch twice!) However, I would also like people to use my code. I'm not sure if its legit to put MIT licensed code in a GPL app or not, I would think its ok, as it permits sublicensing. I have issues with the GPL, not the least of which being its length (funny considering how long my e-mails are...). > I know we all have different goals with our editors, but were we to > have a big set of code with few external dependencies (i.e. low > coupling), we could all borrow stuff at will. This is similar to what I've had in mind when developing Pallavi. Basically, that different authors could contribute different plugins and mix and match them in many ways. Not that I think everyone should drop their project and start writing Pallavi plugins *grins*. But hopefully, for my part, any code I write that is useful to others will be inherently decoupled. > To kick off some discussion, I was wondering if you'd talk about (or > point to a good description of) the jedit plugin system that you were > emulating. Do you have to define all the messages that get passed > around in advance, i.e. do all plugins have to implement the same > interface? To be honest, I don't recall much about the jEdit system anymore, except that it was more complex than I deemed necessary. It has XML configuration files for menus and docking windows. I'm sure very few Python coders will disagree when I suggest that XML is not the ideal configuration language. ;-) So I'll just talk about how I actually implemented it. The Pallavi plugin architecture is currently a bit too simplistic. A plugin is just a module on the python path with a setup() function, and a few variables are set before this is called. Communication happens on the eventbus and the actionlist. Events are things that have occured. Plugins can issue events to say that something has been done. Actions are things that can be performed. Plugins can provide actions that other plugins can invoke. Any plugin can provide any action, invoke any action, listen to any event, and issue any event. Events are identified by strings and can clobber each other if necessary (or maliciously or by accident, it is true). There is no predefined list of events or actions; typically plugins set these up in their setup() method. I make a habit of documenting every plugin with a docstring that outlines exactly what actions and events it invokes, issues, and listens for. In some ways, it sounds like a bit of a mess, since there's no checking or structure enforced on the available actions. This was, however, a conscious decision; it is actually, in some ways, similar to the "duck typing" that Python coders are so fond of. In my mind, the beauty of this system is that any module on the python path with a setup() method can be a plugin. This means that plugins can be distributed in a variety of ways -- windows installer, eggs, etc, and I don't have to provide or enforce a specific plugin distribution architecture. Pallavi does provide some support for installing plugins and there is an extra folder in the configuration directory that is added to sys.path to allow plugins to be loaded, but it this is not required. > The thing that intrigues me about what I think I understand about the > jedit plugins is the message passing. I wonder if a Trac component > could be a factory for jedit plugins? I'm still struggling with > message passing (wx.lib.pubsub), because with my multiple views I > might want a message to be sent to only one of the views, but there's > no way to do that with vanilla pubsub. I was trying to get away from > the message *passer* having to know the target view: it just sends its > message and the message passing facility would knows where to direct > it. Don't have a good solution -- I could have each message receiver > check if it is the intended target, but it seemed like there should be > a better solution. So you don't want the sender to know the desired target and you also don't want the receiver to be aware of the sender. I'm not sure if that's possible... even IP has a src and dest address. :-) I've definitely implemented something different from what you want. You basically want to emulate a router, in some ways (it wouldn't hurt to look up routing algorithms in a networking text and see if it gives inspiration). My system (and jEdit's) is more like ethernet -- messages are put out on the bus and received by anyone listening for that type of message. I haven't actually had any need to send an identifier of the source with the message. Dusty
