XEROX PROFILER 2 4 1 PROFILER 1 4 By: Jeff Shrager (Shrager@Xerox.com) INTRODUCTION The profiler simulates proplist operations (put/get) but keeps the values in a permanent file so that they are automatically saved across sessions. This is a way to save information across sessions that the user would normally have to store in the lisp initialization file . APPLICATIONS I use the profiler in two ways. First, I have a TEdit hack that looks up the preceding word in a profile property and inserts a replacement word when I type ^N. I use this to enter netmail aliases. For instance, I type: "Matthew^N" and it is replaced by "Lewis@a.psy.cmu.edu". These aliases are permanently saved in an external profile. All I have to do to add a new one is call a NEW-ALIAS function and tell it the keyword and the replacement word. My other application for the Profiler is to permanently store default window positions. Sometimes I decide that I like to have a certain type of window in a different place on my screen. In order to permanently move it (for now and forever) I simply reshape that window and then button "Fix Shape", an item I've added to the window menu. Fix Shape simply calls the profiler to permanently save the new region information in a window-shapes profile file so that the next time I open one of these windows (even in a new session) it gets the right shape. USAGE (USER::PRO-SET system id property value) [Function] This is like a putprop (or, rather, like a setf/get in commonlisp). It puts the indicated value on the property name of the identifier. The system is another level of specification. This is used to figure out what profile external file to use for saving the id/prop/value triples. Generally the system is a major application area like LAFITE or WINDOWS. You can think of it as analogous to a package. (USER::PRO-GET system id property) [Function] This is the complementary function, analogous to GET in lisp. EXAMPLES Here are the definitions of my ^N and NEW-ALIAS hacks mentioned above: (defun TEDIT.SHRAGER.ALIAS (STREAM OBJ) (replace-word stream (USER::PRO-GET 'LAFITE (U-CASE (MKATOM (get-last-word stream obj))) 'NETMAIL-ADDRESS))) (defun NEW-ALIAS (OLD-WORD-AS-AN-ATOM NEW-WORD-AS-A-STRING) (USER::PRO-SET 'LAFITE OLD-WORD-AS-AN-ATOM 'NETMAIL-ADDRESS NEW-WORD-AS-A-STRING)) The file {CF}PROFILES>LAFITE.PRO will be used as the profile file for this application. This is computed from the system name and the value of the variable: USER::*PROFILE-LOCATION* [Variable] which is set to "PROFILES>" for me. (Obviously, this particular setting, and the loading of the profiler, must be done in the user's init.) "PROFILES>" is the default for this variable. HOW PROFILING WORKS The external profile files are text files that are held open for both input and output during your session. Each time you do a PRO-SET operation the file is reopened, if necessary, and the new information is written to the end of it. When you first do a PRO-GET for a particular system, that system's profile contents is read into the internal list: USER::*PROFILE-DATUM* [Variable] (I know, it should be DATA -- don't hassle me!) Most future PRO-GET operations will be done from this structure instead of from the file. PRO-SET updates both the *PROFILE-DATUM* and the profile external file. The external profile ({CF}PROFILES>LAFITE.PRO) for my alias application looks like this: ("MATTHEW" "NETMAIL-ADDRESS" "Lewi@A.Psy.CMU.Edu") ("CHAPMAN" "NETMAIL-ADDRESS" "Zvona@ai.ai.mit.edu") ("ZVONA" "NETMAIL-ADDRESS" "Zvona@ai.ai.mit.edu") ("AGRE" "NETMAIL-ADDRESS" "Agre@ai.ai.mit.edu") ("MATTHEW" "NETMAIL-ADDRESS" "Lewis@A.Psy.CMU.Edu") There are two important features shown here. First, the file contains repeated entries for Matthew's alias. Updates are always added to the end, and old information isn't garbage collected. I don't expect these files to get too big, but some day I'll write a GC for them. In the mean time, if you are adding lots of stuff to a profile, feel free to hand edit it. The other important thing to notice here is that all of the datum are strings. Actually, the values (third datum in each list) are strings just because I put them there specifically as strings. The value is left in whatever form is was given to PRO-SET. However, the identifier and property keywords are forced to strings by the profiler. This resolves package conflicts, so that no matter what package you were in when you entered the information, you'll get it when you ask for it. However, since the values themselves are stored as atoms, or what-have-you, those will come back into the appropriate packages. You need to be a little mindful of this in some cases. (LIST ((PAGE NIL (PAPERSIZE LETTER STARTINGPAGE# 213) (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)))))(È(È(ŠŠ8(ŠŠ8DÈÈ PAGEHEADING RUNNINGHEADTERMINAL MODERN MODERN MODERN MODERNLOGO TIMESROMAN   HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN   HRULE.GETFNMODERN  HRULE.GETFNMODERN &  È,4–.> G) *       §$¼`!0l4b !! !o+ bß®zº