File: PL1LIB Node: TOP Next: USER Up: (DIR) The EMACS library PL1LIB contains macros to help edit PL1 code. Since PL1 indentation styles vary a lot, the PL1LIB macros are structured into an extensible scheme that allows the user control over the kinds of indenting done. Load these macros into an EMACS, by MM Load Library$PL1LIB$$. Then MM PL1 Mode$$ will set things up for editing PL1 code, such as setting comment delimiters, and putting the statement indenter into TAB. If you want to set things up differently, you can provide a macro named Init PL1 Mode. The main macro is ^R Indent PL1 Statement. This macro is the "driver" which implements the indentation scheme, calling special indentation subroutines to do the actual work of indenting, based on the kind of previous statement, if the macro is called to indent a new statement. If called to indent a new line of an unfinished statement the indentation subroutine is chosen based on the current kind of statement. There are indentation subrs provided for different kinds of PL1 statement types, and you can provide your own to taylor indenting style. BEWARE! Pl1 mode is not as smart as you or I. (Well... half right at least...) Avoid using statment keywords that drive indenting as variables at the beginning of a statement, e.g. don't do: DO = ...; Don't even do: DO = END; Everyone should acquaint themselves with ^R Indent PL1 Statement (do "M User Calls" or just "N" to read about it). After that, you can read about various indentation subrs to handle common PL1 statements that are provided in the basic PL1LIB library (by doing "M Finished" or "M Unfinished" from here, or just "N" from Indent Stmt). Those interested in writing their own indentation subrs can read through other parts of this info file. To insert a full description of the PL1 commands, ^R macros, and subrs you can do: MM Load Library$ABSTR$ MM Abstract File$ $ $PL1LIB$ Also, to keep up with changes or make suggestions, you can put yourself on the INFO-PL1-MODE mailing list on MC. * Menu: Read at least User Calls, Related. * User Calls: USER Commands and ^R macros. * Related: USEFUL Useful, related macros in EMACS. * Finished: FIN Indentation subrs called when previous stmt was finished. * Unfinished: UNFIN Indentation subrs called when previous stmt was unfinished, i.e. really beginning of this one. * Subroutines: SUBRS PL1LIB provides several subroutines for moving around PL1 code, for use by indentation subrs.  File: PL1LIB Node: USER Next: USEFUL Up: TOP ^R Indent PL1 Stmt: The statement indenter is the main macro in the PL1LIB library. It indents a statement by an amount that depends on the previous statement's type, and whether it was finished (i.e. had a semi-colon at its end -- you can call ^R Indent PL1 Stmt to indent a part of a statement that was started on a previous line). Any existing indentation is removed before indenting. After determining the previous statement's type (e.g. DO or IF, based on the first non-label, non-comment token found in the statement), ^R Indent PL1 Stmt will make up a name of an indentation subr to handle indenting statements that follow that type: & PL1 Indent After . If the previous statement was unfinished, the indentation subr name is of the form & PL1 Indent Unfin . If there is no such subr, a default is called: & PL1 Indent After Stmt, or & Indent Unfin PL1 Stmt. These subrs indent based on the type and indentation of the previous statement. If an ARG is specified (e.g. ^U TAB), if there are tokens to the left in the line, or if indentation is beyond the desired column (e.g. TAB TAB), then ^R PL1 Indent Relative is called. ^R PL1 Indent Relative: Successive calls indent under successive words of last line. ^R Global Comment, and ^R End Global Comment: Call ^R for a large comment. Comment column is set to 10 and auto fill is turned on. End comment returns from this ^R. This macro may someday put the resulting text in a comment-box. ^R Slurp PL1 to Char: A fix for auto-fill indenting over too far, this macro pulls non-comment text from previous line (back to CHAR typed) and inserts it at point, calling the statement indenter again so you can see if things look better now. ^R Print Last PL1 Indenter: Prints name of indentation subroutine that was called by the statement indenter -- i.e. this will tell you what kind of previous statement the indenter thought it was working with. (IF, DO, ...) This macro is useful if you're not sure just what happened w Indent PL1 Region: Calls the statement indenter for each line from here to MARK. I suggest that you use this carefully, e.g. indenting small, screen-sized regions. To protect against horrible mistakes, the old text is put on the kill stack, and point and MARK surround the new.  File: PL1LIB Node: USEFUL Next: FIN Previous: USER Up: TOP Some related EMACS ^R macros that you may find useful, ordered by how useful I find them, are: ^R Indent for Comment ^R End Comment ^R Indent New Comment Line (both comments and non-comments) ^R Delete Horizontal Space ^R Indent Nested ^R Indent Under (TMACS library version combines this and nested) ^R Back to Indentation ^R Delete Indentation ^R Indent Rigidly ^R Up Indented Line ^R Down Indent Line If you want more you can always MM Apropos$Indent$, or MM Apropos$Comment$...  File: PL1LIB Node: FIN Next: UNFIN Previous: USEFUL Up: Top This section documents the indentation subroutines called to handle new statements, i.e. there is nothing between here and the previous statement end (;) except labels and comments. Such indentation subrs have names of the form & PL1 Indent After . The PL1LIB library provides indentation subrs for finished previous statements of type: IF, ON, ELSE, (the compound statement types) DO, BEGIN, (block beginners) PROC, ENTRY END, (block ender) and the default (previous statement had no specific subr for it) The default for random previous statements, & PL1 Indent After Stmt, just indents the same amount as the previous statement. (If this is the first pl1 statement in the buffer, indentation is given by the variable $1st Stmt Indentation$, which has default 10.) * Menu: More details on PL1LIB's indentation subrs. * Compound: COMP Compound statements, IF, ELSE and ON, look at the last sub-statement, e.g. IF ... THEN DO; vs IF ... THEN CALL FOO;. * Block: BLOCK Statements that start blocks, DO and BEGIN. * Procedure: PROC Proc and entry. * End: END The END statement looks back for matching DO etc.  File: PL1LIB Node: COMP Next: BLOCK Up: FIN The compound statements IF, ELSE, and ON contain sub-statements, and indenting after these depends on the last sub-statement: if this last sub-statement is a DO or BEGIN, the next statement is indented past the DO/BEGIN by a user-specified amount, in variable $COMP BLOCK INDENTATION$. I.e., & PL1 Indent After Compound will indent the next line to align with the DO or BEGIN, and then indent $COMP...$ more. The default for $...$ is 0, in which case some examples are: IF ... THEN IF ... THEN DO WHILE I>0; here or IF ... THEN BEGIN; here If there is no DO or BEGIN, indentation is kept the same: IF ... THEN CALL FOO; here or IF ... THEN IF ... THEN CALL FOO; here For $COMP BLOCK Indentation$ = 5: IF ... THEN BEGIN; here  File: PL1LIB Node: BLOCK Next: PROC Previous: COMP Up: FIN DO and BEGIN statements start blocks which are indented to align with the first non-whitespace following the DO or BEGIN, e.g. DO WHILE I > 0; here or BEGIN; here or DO I = 1 TO 50; here  File: PL1LIB Node: PROC Next: END Previous: BLOCK Up: FIN Indent a constant amount, specified by $1st Proc Stmt Indentation$. If not exist, defaults to 10.  File: PL1LIB Node: END Previous: PROC Up: FIN END statements are the trickiest: they search back over preceeding statements until a matching DO, BEGIN, or PROC is found. The indentation for the statement following the END is the same as that of the statement containing the matching DO/BEGIN/PROC. For example: DO WHILE TRUE; A = B; IF THIS THEN THAT; END; here or IF THIS THEN DO; A = B; DO WHILE FOO; B = C; END; CALL GAGGLE(GEESE); END; here  File: PL1LIB Node: UNFIN Next: SUBRS Previous: FIN Up: TOP The unfinished-IF indents the same amount as the IF, if the THEN hasn't occurred yet. If it has, calls the default unfin-indenter. The unfinished compound for ON and ELSE indents the same amount as the last sub-statement so far. The default is fairly hairy and has several mutually exclusive cases: Case 1: If there is an open paren, align with next non-whitespace. Case 2: If $Unfin Stmt Indentation$ exists, indent that more than start of statement. Case 3: If prev line contains start of stmt, aligns with 1st word after beginning of stmt token (note: tokens may be several words, e.g. var_name is one token, two words). Case 4: Calls ^R PL1 Indent Relative if the above cases don't hold.  File: PL1LIB Node: SUBRS Previous: UNFIN Up: TOP There are several subroutines available for use by indentation subroutines, to help move to tokens past labels and comments, move to previous statement ends, find the last sub-statement in a compound (IF or ON) statement, etc. These subroutines generally take arguments telling where to start their searches from, and/or an iteration count. Subroutines that find tokens return two values, surrounding the token. Subroutines finding ends of statements return a pointer to the semi-colon. For failed searches, generally either b or z is returned for values. For more info on these subrs, you can abstract PL1LIB as mentioned earlier, or while it is loaded, you can MM List Subroutines$$ and MM Describe$$ whatever looks interesting.