jpayne@68: Writing an IDLE extension jpayne@68: ========================= jpayne@68: jpayne@68: An IDLE extension can define new key bindings and menu entries for IDLE jpayne@68: edit windows. There is a simple mechanism to load extensions when IDLE jpayne@68: starts up and to attach them to each edit window. (It is also possible jpayne@68: to make other changes to IDLE, but this must be done by editing the IDLE jpayne@68: source code.) jpayne@68: jpayne@68: The list of extensions loaded at startup time is configured by editing jpayne@68: the file config-extensions.def. See below for details. jpayne@68: jpayne@68: An IDLE extension is defined by a class. Methods of the class define jpayne@68: actions that are invoked by event bindings or menu entries. Class (or jpayne@68: instance) variables define the bindings and menu additions; these are jpayne@68: automatically applied by IDLE when the extension is linked to an edit jpayne@68: window. jpayne@68: jpayne@68: An IDLE extension class is instantiated with a single argument, jpayne@68: `editwin', an EditorWindow instance. The extension cannot assume much jpayne@68: about this argument, but it is guaranteed to have the following instance jpayne@68: variables: jpayne@68: jpayne@68: text a Text instance (a widget) jpayne@68: io an IOBinding instance (more about this later) jpayne@68: flist the FileList instance (shared by all edit windows) jpayne@68: jpayne@68: (There are a few more, but they are rarely useful.) jpayne@68: jpayne@68: The extension class must not directly bind Window Manager (e.g. X) events. jpayne@68: Rather, it must define one or more virtual events, e.g. <>, and jpayne@68: corresponding methods, e.g. zoom_height_event(). The virtual events will be jpayne@68: bound to the corresponding methods, and Window Manager events can then be bound jpayne@68: to the virtual events. (This indirection is done so that the key bindings can jpayne@68: easily be changed, and so that other sources of virtual events can exist, such jpayne@68: as menu entries.) jpayne@68: jpayne@68: An extension can define menu entries. This is done with a class or instance jpayne@68: variable named menudefs; it should be a list of pairs, where each pair is a jpayne@68: menu name (lowercase) and a list of menu entries. Each menu entry is either jpayne@68: None (to insert a separator entry) or a pair of strings (menu_label, jpayne@68: virtual_event). Here, menu_label is the label of the menu entry, and jpayne@68: virtual_event is the virtual event to be generated when the entry is selected. jpayne@68: An underscore in the menu label is removed; the character following the jpayne@68: underscore is displayed underlined, to indicate the shortcut character (for jpayne@68: Windows). jpayne@68: jpayne@68: At the moment, extensions cannot define whole new menus; they must define jpayne@68: entries in existing menus. Some menus are not present on some windows; such jpayne@68: entry definitions are then ignored, but key bindings are still applied. (This jpayne@68: should probably be refined in the future.) jpayne@68: jpayne@68: Extensions are not required to define menu entries for all the events they jpayne@68: implement. (They are also not required to create keybindings, but in that jpayne@68: case there must be empty bindings in cofig-extensions.def) jpayne@68: jpayne@68: Here is a complete example: jpayne@68: jpayne@68: class ZoomHeight: jpayne@68: jpayne@68: menudefs = [ jpayne@68: ('edit', [ jpayne@68: None, # Separator jpayne@68: ('_Zoom Height', '<>'), jpayne@68: ]) jpayne@68: ] jpayne@68: jpayne@68: def __init__(self, editwin): jpayne@68: self.editwin = editwin jpayne@68: jpayne@68: def zoom_height_event(self, event): jpayne@68: "...Do what you want here..." jpayne@68: jpayne@68: The final piece of the puzzle is the file "config-extensions.def", which is jpayne@68: used to configure the loading of extensions and to establish key (or, more jpayne@68: generally, event) bindings to the virtual events defined in the extensions. jpayne@68: jpayne@68: See the comments at the top of config-extensions.def for information. It's jpayne@68: currently necessary to manually modify that file to change IDLE's extension jpayne@68: loading or extension key bindings. jpayne@68: jpayne@68: For further information on binding refer to the Tkinter Resources web page at jpayne@68: python.org and to the Tk Command "bind" man page.