Could Emacs be rewritten in Python?
Patrick K. O'Brien
pobrien at orbtech.com
Thu Apr 17 12:17:40 EDT 2003
"Greg Ewing (using news.cis.dfn.de)" <ckea25d02 at sneakemail.com> writes:
> Patrick K. O'Brien wrote:
> > I suppose one could bind attributes (current frame, current buffer,
> > point) to a module and then import that module everywhere that needed
> > access to these attributes
>
> That's no better, because they're still global -- there's
> still only *one* of each of them, whereas there really
> needs to be different ones in different contexts.
>
> A function which needs to operate on a frame should be
> passed a frame. Some buffer will be displayed in that
> frame: frame.buffer. That buffer will have a point:
> frame.buffer.point. Etcetera.
That's easy enough for functions/methods/commands that are part of the
base package. What I was thinking about were functions/commands that
were written by users to extend the base package. I haven't figured
out a good way to determine the context they need and be able to pass
that object to them. For example, let's say someone wanted to create
a new command that operated on the current buffer. Assuming I had the
mechanism in place to bind keystrokes to a user-created command, how
would I know what parameters that command expected?
Does anyone know of a Python program of any kind that comes close to
having this ability to be extended by users?
Now that I think about it, my dispatcher module does poke into
handlers/receivers to see what parameters they are expecting (based on
parameter name) and only calls the handler with the parameters it
wants. So I suppose I could do something similar, using a naming
convention for all the objects that are available as parameters, which
should be a reasonably small number.
Here is the relevant code from dispatcher.py:
def _call(receiver, **kwds):
"""Call receiver with only arguments it can accept."""
if hasattr(receiver, '__call__') and \
(hasattr(receiver.__call__, 'im_func') or hasattr(receiver.__call__, 'im_code')):
# receiver is a class instance; assume it is callable.
# Reassign receiver to the actual method that will be called.
receiver = receiver.__call__
if hasattr(receiver, 'im_func'):
# receiver is a method. Drop the first argument, usually 'self'.
fc = receiver.im_func.func_code
acceptable = fc.co_varnames[1:fc.co_argcount]
elif hasattr(receiver, 'func_code'):
# receiver is a function.
fc = receiver.func_code
acceptable = fc.co_varnames[0:fc.co_argcount]
else:
raise DispatcherError, 'Unknown receiver %s of type %s' % (receiver, type(receiver))
if not (fc.co_flags & 8):
# fc does not have a **kwds type parameter, therefore
# remove unacceptable arguments.
for arg in kwds.keys():
if arg not in acceptable:
del kwds[arg]
return receiver(**kwds)
--
Patrick K. O'Brien
Orbtech http://www.orbtech.com/web/pobrien
-----------------------------------------------
"Your source for Python programming expertise."
-----------------------------------------------
More information about the Python-list
mailing list