pymacs! :-)

François Pinard pinard at iro.umontreal.ca
Sat Sep 8 19:04:26 EDT 2001


[Paul Winkler]

> > [item] is a Python list, which yields a LISP vector.  `lisp.f7' merely
> > translates to the LISP symbol `f7'.  So, Python `[lisp.f7]' is LISP
> > `[f7]'.

> How does that happen? Will you have definitions in lisp.py for every
> possible key or key combination?

Oh!  God no! :-)

`lisp' is not a module, it is a special object having some Python magic
built in it.  I may explain how it works if you are curious, but one should
be able to use it a bit blindly, or at least, I hope so. :-)

`lisp' is an instance of the `pymacs.Lisp' class.  Whenever you write
`lisp.SYMBOL', you are calling the `__getattr__' method of that class.
That metho checks if the wanted symbol has already been created, in which
case it returns it, otherwise, it creates a new one and returns it.  A symbol
is an instance of the `pymacs.Symbol' class (which also has its own magic!).
Whenever such a symbol gets transmitted to the Emacs side, the communication
protocol takes care that it produces the proper corresponding LISP symbol.

> I have not seen your code

If you feel audacious, it is available on request.  I started integrating
some of Brian McErlean's good ideas (he really gave me wonderful clues),
and plan to start using it in production for myself in a few hours.
There is not much left to do now.  Until users complain, of course! :-)

> Instead of the first argument being [lisp.f7], it would be ['f7'].

There is a deep difference between a symbol and a string, in Emacs, like
in Python, but you know this. :-) Python `lisp.f7' corresponds to the LISP
symbol `f7', Python `"f7"' corresponds to the LISP string `"f7"'.

> So to take a real example from my .emacs file:
>    (global-set-key [M-f2] 'redo)
> ... might become something like, on the python side,
>    lisp.global_set_key(['M-f2'], lisp.redo)

I'm not utterly familiar with how `[SYMBOL]' works on the Emacs side to
represent key-bindings, but I would guess Emacs developers made a few
stunts for it to look good.  For what I guess these stunts are, I would
write on the Python side:

    lisp.global_set_key([lisp['M-f2']], lisp.redo)

or even more tricky:

    lisp.global_set_key([lisp.M_f2], lisp.redo)

> >   (global-set-key "\C-xw" manglers-break-on-whitespace)
> > [to become]
> >   lisp.global_set_key('\x18w', lisp.manglers_break_on_whitespace)

> IMHO this is a heavy burden to place on the person trying to write
> python functions.

Really?  We'll have to do something about it, then.

> I have no idea how I would find out that C-x is equivalent to chr(0x18).

Oh!  `C-x' stands for Control-X.  In an ASCII table, there are control
characters from 0x00 to 0x20 (excluded).  0x01 is Control-A, 0x02 is
Control-B, etc.  Knowing this, Control-X is: chr(ord('X') - ord('A') + 1).
Give the above to an interactive Python session, you will get: '\x18'.

> Furthermore, there must be many combinations of control, meta, and
> other keys that have no single-character equivalent [...]

Control is the equivalent of subtracting 0x40 from the upper case letter.
Meta is the equivalent of adding 0x80 to the rest.  However, so people can
use non-ASCII charsets, Meta is given another representation in key maps,
and this is to prefix the character to "meta" in the string with `ESC',
which is 0x1b.  That's all, I think, for when users specify strings.
For the rest, Emacs uses the vector notation, with no strings.

> >Maybe it could be useful to have a service function to help writing more
> >LISP-looking strings in Python?

> Yes, that's exactly what I'm suggesting.

Then this routine -- let's tentatively call it `pymacs.key()' -- and the
convention for writing its argument, should be precisely documented.

-- 
François Pinard   http://www.iro.umontreal.ca/~pinard




More information about the Python-list mailing list