On Wednesday 05 September 2007 18:54:17 Rob McMullen wrote: > 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. > > What I'd love to see with pyxides is a lot of code that we could mix > and match among applications. Stani's Fold Explorer comes to mind, if > I'd ever get back to working on the text editing part of peppy rather > than the framework. > > 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. For example, the > overarching goal of peppy is to have multiple top level windows with > multiple ways to view the same file. That may be too much overhead > for some people to consider using peppy for a framework, and that's > cool. But, if I can make some of my stuff independent enough, maybe > it will be useful for others. I've been trying to pull stuff out of > classes where I can and putting them into mixins or standalone files > in the peppy.lib module. > > 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? > > For peppy, I rolled my own plugins for a while until I ran across the > Trac component architecture > (http://trac.edgewall.org/wiki/TracDev/ComponentArchitecture). > Basically a Trac component (aka plugin) is a singleton that registers > entry points that other Trac plugins can add themselves to. You > define interfaces, and one plugin can implement one or many of the > interfaces. I have found that useful. > > The implication of this architecture is that you can't have multiple > instances of the same Trac plugin -- you've got to treat the Trac > plugin as a factory to generate other objects. That's its drawback, I > suppose, and though I've found that limiting at times there were > always ways to work around it. As a bonus, they integrate well with > the setuptools plugins. > > 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. > > Rob
Hi, Well, firstly, I should say that we are not all text-editor developers here. I personally feel that writing a new text editor is fairly much a waste of time, and hence PIDA's philosophy of using external mature and well-featured editors. Secondly, I should say that we are not all wxPython developers. With those two asides, I would guess that we all have come across the problem of writing a fully-featured plugin architecture. Trac plugin architecture is a nice starting point, as you describe. I have no idea about JEdit plugins, but I did have a good look at Eclipse plugins before writing the current (3rd) version of the PIDA plugin architecture. PIDA has two levels of "plugin". The first is a very low-level thing, akin to the Trac architecture but more featured. The second level is the level at which this architecture is used to create actual plugins that do real things. The low level plugin is essentially a registry where other components can register things. The three kind of things that a component can register with the registry are "Singletons", "Features", and "Extension Points". I won't bore you with the details, you can check the docstring at http://pida.co.uk/trac/browser/trunk/pida/core/plugins.py. An "Extension Point" is somewhat like a Trac extension point, but in practise we have found these things quite useless. A "Feature" is a similar thing, except that the keys, or interfaces that are expected to be provided are not predetermined, and can be registered at runtime, which allows for a real modification in behaviour without changing the core code. So, using this low-level architecture, we have built real plugins. These plugins define the following: Configuration - options Commands - the external interface for the plugin Events - events that the plugin will fire to any interested observers Features - As features described above Actions - UI Actions which loosely map 1:1 with menu items or toolbar buttons Views - UI components which display as views Using this, a plugin can modify the behaviour of PIDA in any way via a controlled interface. As an example, recently we added a code completion framework. The problem was that code completion should be able to use the same backend for any editor, and any plugin should be able to provide a completion function that can be used. The results sent back to the editor should be a combination of all the individual results from the plugins that implement this feature. So, without changing any core code: Write a plugin which has a feature for completing. Call it ICompletionResults. Allow any plugin to register with this feature. Done. I find myself going on and on and on about this, so excuse me. Ali
