|  | Searching XEmacs
	    
            Quick Links
            
            About XEmacs
            
            Getting XEmacs
            
            Customizing XEmacs
            
            Troubleshooting XEmacs
            
            Developing XEmacs |  |  | Lisp Interface ChangesAbstract
    Owner:  ??? 
    Effort:  ??? 
    Dependencies:  ??? 
    Abstract: This document covers the major Lisp
    interface changes that I am proposing for version 22.  These
    changes include full support for keyword parameters everywhere in
    Elisp, a generalized object property interface, and changes to the
    toolbar and menu API, in such a way that backward compatibility is
    maintained for the most part.  Most of these changes are being
    done for the benefit of the improved user interface facilities
    that I am proposing for version 22 in order to make their
    associated interfaces cleaner and easier to use.  As far as I
    know, all of these changes can be made in such a way that the byte
    code format does not need to be modified. Keyword Parameters
    I would like to make keyword parameters an integral part of Elisp.
    The idea here is that you use the &keyidentifier
    in the parameter list of a function and all of the following
    parameters specified are keyword parameters.  This means that when
    these arguments are specified in a function call, they are
    immediately preceded in the argument list by a keyword,
    which is a symbol beginning with the `:' character.  This allows
    any argument to be specified independently of any other argument
    with no need to place the arguments in any particular order.  This
    is particularly useful for functions that take many optional
    parameters; using keyword parameters makes the code much cleaner
    and easier to understand. 
    The clpackage already provides keyword parameters of
    a sort, but I would like to make this more integrated and useable
    in a standard fashion.  The interface that I am proposing is
    essentially compatible with the keyword interface in Common Lisp,
    but it may be a subset of the Common Lisp functionality,
    especially in the first implementation.  There is one departure
    from the Common Lisp specification that I would like to make in
    order to make it much easier to add keyword parameters to existing
    functions with optional parameters, and in general, to make
    optional and keyword parameters coexist more easily.  The Common
    Lisp specification indicates that if a function has both optional
    and keyword parameters, the optional parameters are always
    processed before the keyword parameters.  This means, for example,
    that if a function has three required parameters, two optional
    parameters, and some number of keyword parameters following, and
    the program attempts to call this function by passing in the three
    required arguments, and then some keyword arguments, the first
    keyword specified and the argument following it get assigned to
    the first and second optional parameters as specified in the
    function definition.  This is certainly not what is intended, and
    means that if a function defines both optional and keyword
    parameters, any calls of this function must specifynilfor all of the optional arguments before using
    any keywords.  If the function definition is later changed to add
    more optional parameters, all existing calls to this function that
    use any keyword arguments will break.  This problem goes away if
    we simply process keyword parameters before the optional
    parameters. 
    The primary changes needed to support the keyword syntax are: 
    
      
        The subr object type needs to be modified to contain
        additional slots for the number and names of any keyword
        parameters.
      
        The implementation of the funcallfunction needs
        to be modified so that it knows how to process keyword
        parameters.  This is the only place that will require very
        much intricate coding, and much of the logic that would need
        to be added can be lifted directly from theclcode.
      
        A new macro, similar to the DEFUNmacro, and
        probably calledDEFUN_WITH_KEYWORDS, needs to be
        defined so that built-in Lisp primitives containing keywords
        can be created.  Now, theDEFUN_WITH_KEYWORDSmacro should take an additional parameter which is a string,
        which consists of the part of the lambda list declaration for
        this primitive that begins with the&keyspecifier.  This string is parsed in theDEFSUBRmacro during XEmacs initialization, and is converted into the
        appropriate structure that needs to be stored into the subr
        object.  In addition, the max_args parameter of theDEFUNmacro needs to be incremented by the number
        of keyword parameters and these parameters are passed to the C
        function simply as extra parameters at the end.  TheDEFSUBRmacro can sort out the actual number of
        required, optional and keyword parameters that the function
        takes, once it has parsed the keyword parameter string.  (An
        alternative that might make the declaration of a primitive a
        little bit easier to understand would involve adding another
        parameter to theDEFUN_WITH_KEYWORDSmacro that
        specifies the number of keyword parameters.  However, this
        would require some additional complexity in the preprocessor
        definition of theDEFUN_WITH_KEYWORDSmacro, and
        probably isn't worth implementing).
      
        The byte compiler would have to be modified slightly so that
        it knows about keyword parameters when it parses the parameter
        declaration of a function.  For example, so that it issues the
        correct warnings concerning calls to that function with
        incorrect arguments.
      
        The make-docfileprogram would have to be
        modified so that it generates the correct parameter lists for
        primitives defined using theDEFUN_WITH_KEYWORDSmacro.
      
        Possibly other aspects of the help system that deal with
        function descriptions might have to be modified.
      
        A helper function might need to be defined to make it easier
        for primitives that use both the &restand&keyspecifiers to parse their argument
        lists. Property Interface Changes
    In my past work on XEmacs, I already expanded the standard
    property functions of get,put, andrempropto work on objects other than symbols and
    defined an additional functionobject-plistfor this
    interface.  I'd like to expand this interface further and
    advertise it as the standard way to make property changes in
    objects, especially the new objects that are going to be defined
    in order to support the added user interface features of version
    22.  My proposed changes are as follows: 
    
      
        A new concept associated with each property called a
        default value is introduced.  (This concept already
        exists, but not in a well-defined way.) The default value is
        the value that the property assumes for certain value
        retrieval functions such as getwhen it is
        unbound, which is to say that its value has not been
        explicitly specified. Note: the way to make a property unbound
        is to callremprop.  Note also that for some
        built-in properties, setting the property to its default value
        is equivalent to making it unbound.
      
        The behavior of the getfunction is modified.  If
        thegetfunction is called on a property that is
        unbound and the third, optional default argument isnil, then the default value of the property is
        returned.  If the default argument is notnil, then whatever was specified as the value of
        this argument is returned.  For the most part, this is
        upwardly compatible with the existing definition ofgetbecause all user-defined properties have an
        initial default value ofnil.  Code that calls
        thegetfunction and specifiesnilfor the default argument, and expects to getnilreturned if the property is unbound, is
        almost certainly wrong anyway.
      
        A new function, get1is defined.  This function
        does not take a default argument like thegetfunction.  Instead, if the property is unbound, an error is
        signaled.  Note:getcan be implemented in terms
        ofget1.
      
        New functions property-default-valueandproperty-bound-pare defined with the obvious
        semantics.
      
        An additional function property-built-in-pis
        defined which takes two arguments, the first one being a
        symbol naming an object type, and the second one specifying a
        property, and indicates whether the property name has a
        built-in meaning for objects of that type.
      
        It is not necessary, or even desirable, for all object types
        to allow user-defined properties.  It is always possible to
        simulate user-defined properties for an object by using a weak
        hash table.  Therefore, whether an object allows a user to
        define properties or not should depend on the meaning of the
        object.  If an object does not allow user-defined properties,
        the putfunction should signal an error, such asundefined-property, when given any property other
        than those that are predefined.
      
        A function called
        user-defined-properties-allowed-pshould be
        defined with the obvious semantics.  (See the previous
        item.)
      
        Three more functions should be defined, called
        built-in-property-name-list,property-name-list, anduser-defined-property-name-list. Toolbar Interface Changes
    I propose changing the way that toolbars are specified to make
    them more flexible. 
    
      
        A new format for the vector that specifies a toolbar item is
        allowed.  In this format, the first three items of the vector
        are required and are, respectively, a caption, a glyph list,
        and a callback.  The glyph list and callback arguments are the
        same as in the current toolbar item specification, and the
        caption is a string specifying the caption text placed below
        the toolbar glyph.  The caption text is required so that
        toolbar items can be identified for the purpose of retrieving
        and changing their property values.  Putting the caption first
        also makes it easy to distinguish between the new and the old
        toolbar item vector formats.  In the old format, the first
        item, the glyph list, is either a list or a symbol.  In the
        new format, the first item is a string.  In the new format,
        following the three required items, are optional keyword items
        specified using keywords in the same format as the menu item
        vector format.  The keywords that should be predefined are:
        :help-echo,:context-menu,:drop-handlers, and:enabled-p.  The:enabled-pand:help-echokeyword
        arguments are the same as the third and fourth items in the
        old toolbar item vector format.  The:context-menukeyword is a list in standard menu
        format that specifies additional items that will appear when
        the context menu for the toolbar item is popped up.
        (Typically, this happens when the right mouse button is
        clicked on the toolbar item).  The:drop-handlerskeyword is for use by the new drag-n-drop interface (see
        Drag-n-Drop Interface Changes
        ), and is not normally specified or modified
        directly.
      
        Conceivably, there could also be keywords that are associated
        with a toolbar itself, rather than with a particular toolbar
        item.  These keyword properties would be specified using
        keywords and arguments that occur before any toolbar item
        vectors, similarly to how things are done in menu
        specifications.  Possible properties could include
        :captioned-p(whether the captions are visible
        under the toolbar),:glyphs-visible-p(whether
        the toolbar glyphs are visible), and:context-menu(additional items that will appear
        on the context menus for all toolbar items and additionally
        will appear on the context menu that is popped up when the
        right mouse button is clicked over a portion of the toolbar
        that does not have any toolbar buttons in it).  The current
        standard practice with regards to such properties seems to be
        to have separate specifiers, such asleft-toolbar-width,right-toolbar-width,left-toolbar-visible-p,right-toolbar-visible-p, etc.  It could easily be
        argued that there should be no such toolbar specifiers and
        that all such properties should be part of the toolbar
        instantiator itself.  In this scheme, the only separate
        specifiers that would exist for individual properties would be
        default values.  There are a lot of reasons why an interface
        change like this makes sense.  For example, currently when VM
        sets its toolbar, it also sets the toolbar width and similar
        properties.  If you change which edge of the frame the VM
        toolbar occurs in, VM will also have to go and modify all of
        the position-specific toolbar specifiers for all of the other
        properties associated with a toolbar.  It doesn't really seem
        to make sense to me for the user to be specifying the width
        and visibility and such of specific toolbars that are attached
        to specific edges because the user should be free to move the
        toolbars around and expect that all of the toolbar properties
        automatically move with the toolbar. (It is also easy to
        imagine, for example, that a toolbar might not be attached to
        the edge of the frame at all, but might be floating somewhere
        on the user's screen).  With an interface where these
        properties are separate specifiers, this has to be done
        manually.  Currently, having the various toolbar properties be
        inside of toolbar instantiators makes them difficult to
        modify, but this will be different with the API that I propose
        below.
      
        I propose an API for modifying toolbar and toolbar item
        properties, as well as making other changes to toolbar
        instantiators, such as inserting or deleting toolbar items.
        This API is based around the concept of a path.  There are two
        kinds of paths here -- toolbar paths and toolbar
        item paths.  Each kind of path is an object (of type
        toolbar-pathandtoolbar-item-path,
        respectively) whose properties specify the location in a
        toolbar instantiator where changes to the instantiator can be
        made.  A toolbar path, for example, would be created using themake-toolbar-pathfunction, which takes a toolbar
        specifier (or optionally, a symbol, such asleft,right,default, ornil,
        which refers to a particular toolbar), and optionally,
        parameters such as the locale and the tag set, which specify
        which actual instantiator inside of the toolbar specifier is
        to be modified.  A toolbar item path is created similarly
        using a function calledmake-toolbar-item-path,
        which takes a toolbar specifier and a string naming the
        caption of the toolbar item to be modified, as well as, of
        course, optionally the locale and tag set parameters and
        such. 
        The usefulness of these path objects is as arguments to
        functions that will use them as pointers to the place in a
        toolbar instantiator where the modification should be made.
        Recall, for example, the generalized property interface
        described above.  If a function such as getorputis called on a toolbar path or toolbar item
        path, it will use the information contained in the path object
        to retrieve or modify a property located at the end of the
        path.  The toolbar path objects can also be passed to new
        functions that I propose defining, such asadd-toolbar-item,delete-toolbar-item, andfind-toolbar-item.  These functions should be
        parallel to the functions for inserting, deleting, finding,
        etc. items in a menu.  The toolbar item path objects can also
        be passed to the drop-handler functions defined in
        Drag-n-Drop Interface Changes
        to retrieve or modify the drop handlers that are associated
        with a toolbar item.  (The idea here is that you can drag an
        object and drop it onto a toolbar item, just as you could onto
        a buffer, an extent, a menu item, or any other graphical
        element).
      
        We should at least think about allowing for separate default
        and buffer-local toolbars.  The user should either be able to
        position these toolbars one above the other, or side by side,
        occupying a single toolbar line.  In the latter case, the
        boundary between the toolbars should be draggable, and if a
        toolbar takes up more room than is allocated for it, there
        should be arrows that appear on one or both sides of the
        toolbar so that the items in the toolbar can be scrolled left
        or right.  (For that matter, this sort of interface should
        exist even when there is only one toolbar that is on a
        particular toolbar line, because the toolbar may very well
        have more items than can be displayed at once, and it's silly
        in such a case if it's impossible to access the items that are
        not currently visible).
      
        The default context menu for toolbars (which should be
        specified using a specifier called
        default-toolbar-context-menuaccording to the
        rules defined above) should contain entries allowing the user
        to modify the appearance of a toolbar.  Entries would include,
        for example, whether the toolbar is captioned, whether the
        glyphs for the toolbar are visible (if the toolbar is
        captioned but its glyphs are not visible, the toolbar appears
        as nothing but text; you can set things up this way, for
        example, in Netscape), an option that brings up a package for
        editing the contents of a toolbar, an option to allow the
        caption face to be dchanged (perhaps thorough janedit-facesorcustominterface),
        etc. Menu API Changes
    
      
        I propose making a specifier for the menubar associated with
        the frame.  The specifier should be called
        default-menubarand should replace the existingcurrent-menubarvariable.  This would increase
        the power of the menubar interface and bring it in line with
        the toolbar interface.  (In order to provide proper backward
        compatibility, we might have to
        complete the symbol value handler
          mechanism)
      
        I propose an API for modifying menu instantiators similar to
        the API composed above for toolbar instantiators.  A new
        object called a menu path (of type
        menu-path) can be created using themake-menu-pathfunction, and specifies a location
        in a particular menu instantiator where changes can be made.
        The first argument tomake-menu-pathspecifies
        which menu to modify and can be a specifier, a value such asnil(which means to modify the default menubar
        associated with the selected frame), or perhaps some other
        kind of specification referring to some other menu, such as
        the context menus invoked by the right mouse button.  The
        second argument tomake-menu-path, also required,
        is a list of zero or more strings that specifies the
        particular menu or menu item in the instantiator that is being
        referred to.  The remaining arguments are optional and would
        be a locale, a tag set, etc.  The menu path object can be
        passed toget,putor other standard
        property functions to access or modify particular properties
        of a menu or a menu item.  It can also be passed to expanded
        versions of the existing functions such asfind-menu-item,delete-menu-item,add-menu-button, etc.  (It is really a shame thatadd-menu-itemis an obsolete function because it
        is a much better name thanadd-menu-button).
        Finally, the menu path object can be passed to the
        drop-handler functions described in
        Drag-n-Drop Interface Changes
        to access or modify the drop handlers that are associated with
        a particular menu item.
      
        New keyword properties should be added to the menu item
        vector.  These include :help-echo,:context-menuand:drop-handlers,
        with similar semantics to the corresponding keywords for
        toolbar items.  (It may seem a bit strange at first to have a
        context menu associated with a particular menu item, but it is
        a user interface concept that exists both in Open Look and in
        Windows, and really makes a lot of sense if you give it a bit
        of thought).  These properties may not actually be implemented
        at first, but at least the keywords for them should be
        defined. Ben Wing
 |