XEROX ADD-SEDIT-COMMANDS 2 4 1 ADD-SEDIT-COMMANDS 1 4 By: Matt Heffron (BEC.HEFFRON@ECLA.USC.EDU) INTRODUCTION This package allows you to attach commands to keys in SEdit (globally and locally). BACKGROUND INFORMATION The information about the bindings of keys to commands is kept in a HASHARRAY in the CommandTable field of the EditENV datatype which is pointed to by the context (type EditContext) in which each SEdit process keeps all the information about the current edit. The HASHARRAY is keyed by CHARCODEs, and the corresponding values are incomplete function calls to the functions for implementing the specific command. (The function calls are incomplete in that the first 2 arguments to them (the context and the charcode) are automatically supplied when the function is invoked, by a mechanism approximately equivalent to: (LET ((COMMAND-FUNCT-FORM (GETHASH ))) (APPLY (CAR COMMAND-FUNCT-FORM) (LIST* (CDR COMMAND-FUNCT-FORM)))) The environment that SEdit uses by default is kept in the GLOBALVAR: \\lisp.edit.environment (yes, 2 leading backslash characters, in an XCL exec it would be IL:|\\\\lisp.edit.environment| ). THE FUNCTIONS (ADD-COMMAND TheENV CHARCODE COMMANDFN &REST EXTRA-COMMANDFN-ARGS) [Function] This function adds a command to the CommandTable HASHARRAY in the EditENV TheENV. CHARCODE is either an actual (SMALLP) character-code, or a symbol (LITATOM) or string of the name of a character as you would pass to the CHARCODE function. COMMANDFN is the name of the function to be called when the CHARCODE key is pressed. (I suppose it could also be a LAMBDA form or a closure, anything that could be APPLYed, I just have never tried it.) The EXTRA-COMMANDFN-ARGS arguments are any additional arguments you wish passed to the COMMANDFN when it is called. They will be evaluated by the regular calling mechanism when you invoke ADD-COMMAND, but those values will not be re-evaluated when the COMMANDFN is actually called (see the calling mechanism above). (COPY-EditENV SOURCE-ENV) [Function] This function creates a new EditENV object which is a copy of the SOURCE-ENV. The created EditEnv will have a copy of the SOURCE-ENV 's CommandTable HASHARRAY also. (GET-SEDIT-ROOT-STRUCTURE context) [Function] This function returns the root-structure of an edit given its context (i.e. the actual Lisp s-expression that SEdit is editing). This is handy when writing command functions which must operate on the whole structure, independent of the current selection. It also returns the EditNode for the root-structure as the second value (using CL:VALUES). (GET-SEDIT-SELECTION-STRUCTURE context) [Function] This function returns the structure of the current selection of an edit given its context (i.e. the actual Lisp s-expression that the current selection represents). It also returns the EditNode for that structure as the second value (using CL:VALUES). EXAMPLE-NEW-SEDIT-COMMANDFN and EXAMPLE2-NEW-SEDIT-COMMANDFN are examples of COMMANDFNs to attach to keys. EXAMPLE-NEW-SEDIT-COMMANDFN does a RPLACD of the root-structure with the value of a symbol which is read in (from the promptwindow). It uses GET-SEDIT-ROOT-STRUCTURE. EXAMPLE2-NEW-SEDIT-COMMANDFN is similar in that it does a RPLACD of the current selection. It uses the SEdit \\do.mutation function which does the work behind the Mutate (M$Z) command. This is probably the easiest way to write a command which operates on the current selection. These also show how to prompt and read from the attached promptwindow. GLOBAL & LOCAL COMMAND KEY BINDINGS To add a command to all SEdits Globally, just call ADD-COMMAND specifying \\lisp.edit.environment as the The-ENV argument. This will add the command to the HASHARRAY which all SEdits use by default. To add a command to SEdit so that it is available only to a (some) specific SEdit(s), first make a copy of the default environment, and save it in a variable (I'll use the variable NEW-ENV here). (SETQ NEW-ENV (COPY-EditENV \\lisp.edit.environment)) Then, when you invoke ED (or DF, DP, etc.) wrap the call inside a RESETVAR (RESETVAR \\lisp.edit.environment NEW-ENV (ED '... )) Another way that is a bit messy is to call SEDIT directly, passing the NEW-ENV as the ENVIRONMENT property to SEDIT. E.g. (SETPROPLIST X (GET-SEDIT-ROOT-STRUCTURE (SEDIT (GETPROPLIST X) `(NAME ,X TYPE PROPLST ENVIRONMENT ,MP-EDITRULE-ENVIRONMENT) '(PROPERTY-LIST)))) Appears to be approximately equivalent to:(ED X 'PROPERTY-LIST). (LIST ((PAGE NIL (PAPERSIZE LETTER STARTINGPAGE# 1) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO NIL) (174 36 288 36) NIL) (HEADING NIL (HEADINGTYPE RUNNINGHEAD) (84 744 528 36) NIL) (TEXT NIL NIL (84 96 456 600) NIL))) (PAGE NIL (PAPERSIZE NIL . LETTER) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO NIL) (174 36 288 36) NIL) (HEADING NIL (HEADINGTYPE RUNNINGHEAD) (84 744 528 36) NIL) (TEXT NIL NIL (84 96 456 600) NIL))) (PAGE NIL (PAPERSIZE NIL . LETTER) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO NIL) (174 36 288 36) NIL) (HEADING NIL (HEADINGTYPE RUNNINGHEAD) (84 744 528 36) NIL) (TEXT NIL NIL (84 96 456 600) NIL))))) 1(((( ((8(8D PAGEHEADING RUNNINGHEADTERMINAL  HELVETICA MODERN MODERN MODERN MODERN MODERNLOGO   HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN - UL I#A J 3?  7  B / ! >5R$iX;K;|,0CA4*z