From:	CRDGW2::CRDGW2::MRGATE::"SMTP::PREP.AI.MIT.EDU::INFO-GNU-EMACS-REQUEST"  5-JUL-1989 22:04
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Re: Looking for Pascal mode (part 2 of 2)

Received: by life.ai.mit.edu (4.0/AI-4.10) id AA02354; Wed, 5 Jul 89 18:03:33 EDT
Return-Path: <info-gnu-emacs-request@prep.ai.mit.edu>
Received: from tut.cis.ohio-state.edu by life.ai.mit.edu (4.0/AI-4.10) id AA02308; Wed, 5 Jul 89 18:01:10 EDT
Received: by tut.cis.ohio-state.edu (5.59/4.890612)
	id AA26711; Wed, 5 Jul 89 17:51:09 EDT
Received: from USENET by tut.cis.ohio-state.edu with netnews
	for info-gnu-emacs@prep.ai.mit.edu (info-gnu-emacs@prep.ai.mit.edu)
	(contact usenet@tut.cis.ohio-state.edu if you have questions)
Date: 5 Jul 89 15:44:28 GMT
From: watmath!watmsg!gjditchfield@uunet.uu.net  (Glen Ditchfield)
Organization: U. of Waterloo, Ontario
Subject: Re: Looking for Pascal mode (part 2 of 2)
Message-Id: <27520@watmath.waterloo.edu>
References: <349@node13.mecazh.UUCP>
Sender: info-gnu-emacs-request@prep.ai.mit.edu
To: info-gnu-emacs@prep.ai.mit.edu


This is a texinfo file describing a (separately posted) Pascal mode.

    Glen Ditchfield  gjditchfield@violet.uwaterloo.ca  Office: DC 2517
Dept. of Computer Science, U of Waterloo, Waterloo, Ontario, Canada, N2L 3G1
	"... and the rest, we will spend foolishly!" -- _Svengali_
-------------------------------------------------------------------------------
@setfilename Pascal

@node Pascal, Commands, (dir), (dir)
@section Pascal Mode

Pascal mode is a collection of functions which make the task of typing
Pascal source easier by automating indentation and by inserting `noise'
words for you.

Complex Pascal structures are handled by template insertion.  Skeletons
of Pascal structures are inserted, and the typist fills in the missing
parts.  Template insertion is invoked by Emacs' abbreviation expansion
mechanism, to minimize the number of key sequences used.  In most cases,
the abbreviations chosen are Pascal reserved words.  Different
indentation styles can be accommodated by changing the templates used.

To use pascal mode, you should make sure that @code{pascal-mode.elc} is
in one of the directories in your load path, and you should put these
lines in your Emacs initialization file:@refill
@example
(autoload 'pascal-mode "pascal-mode" t)
(setq auto-mode-alist (cons (cons "\\.p$" 'pascal-mode) auto-mode-alist))
@end example

@menu
* Commands::		Commands defined by pascal-mode.
* Abbreviations::	Abbreviation expansion; default abbreviations.
* Variables::		Variables that control Pascal mode behavior.
* Customization::	How to adjust Pascal mode behavior.
* Elision::		Support for selective hiding of Pascal text.
@end menu

Pascal mode and it's documentation is distributed under the terms of the
GNU Emacs General Public License (type @key{C-h} @key{C-c}) and the
statement of no warranty (type @key{C-h} @key{C-w}).@refill

I am sure that Pascal mode has bugs.  Please send bug reports, bug fixes,
and suggestions to me.  I don't promise to fix them, but you never
know@dots{}.  At the time of writing, my addresses are
@quotation
Glen Ditchfield
Department of Computer Science,
University of Waterloo,
Waterloo, Ontario

gjditchfield@violet.uwaterloo.ca
@end quotation

@node Commands, Abbreviations, Pascal, Pascal
@subsection Commands

The following commands are defined by, or particularly useful in, Pascal mode.

@table @kbd
@item M-x pascal-mode
Switch to Pascal mode in the current buffer.  
@item @key{RET}
Create a new line, and leave point at the left margin on the new line.
(@code{newline})
@item @key{LFD}
Create a new line, and indent the line. (@code{newline-check-and-indent})
@item @key{TAB}
Reindent the current line.  (@code{pascal-indent-line})
@item M-@key{TAB}
``Outdent'' the current line.  (@code{pascal-outdent-line}).
@item C-c C-b
Wrap a @code{begin @dots{} end} statement around the region.
(@code{pascal-beginnify-region}).
@item M-C-f
@itemx M-C-b
Skip forward and backward, respectively, over matching parentheses,
@code{record} declarations, and @code{begin}, @code{case}, and @code{repeat} statements.
(Skipping backwards doesn't handle variant records properly.)
(@code{pascal-forward-sexp}, @code{pascal-backward-sexp})
@item @key{DEL}
Delete the previous character.  Tabs are converted to spaces as the
cursor moves backwards. (@code{backward-delete-char-untabify})
@item C-x '
Expand the abbreviation before point, even if Abbrev mode is turned
off.  (@code{expand-abbrev})
@item M-x list-abbrevs
List all defined abbreviations, including those used by Pascal mode.
@end table

@code{pascal-mode} sets up data structures used by Pascal mode, and calls
the value of @code{pascal-mode-hook} if that variable is non-nil.  You may
have to run this function to edit Pascal .h files, since Emacs assumes that
.h files contain C code. (To avoid this, put the line `{-*-Pascal-*-}' at
the start of all of your Pascal .h files.)@refill

@key{LFD} is bound to @code{newline-check-and-indent}, which creates a new,
properly indented line (see below).  If the previous line contains an
un-closed string, or if it contains an unclosed comment and you have
defined `comment-multi-line' to be NIL, a warning message is printed in the
minibuffer.@refill

@key{TAB} reindents the current line.  For both @key{TAB} and @key{LFD},
the indentation of the nearest previous line that is not flush with the
left margin is used as an initial guess.  If the previous line was not a
complete statement, the indentation is increased by the value of
`pascal-indent-level'.  The heuristics used here are crude, so the
indentation level may be increased unnecessarily.@refill

@kbd{M-@key{TAB}} Reduces the current line's indentation.  It does this by
looking backwards for a line that is less indented than the current line,
and using that indentation.  This fixes most mistakes made by @key{TAB}.@refill

@node Abbreviations, Variables, Commands, Pascal
@subsection Abbreviations

When Abbrev mode is on (as it normally will be), typing an abbreviation
followed by a punctuation character or blank causes the abbreviation to be
expanded.  If the abbreviation stands for a Pascal template, Pascal mode
will generally check to see if the abbreviation was typed in a comment or
string.  If it was, the abbreviation is not expanded.  If it was typed in
program text, the proper template is inserted.

It is hard to decide whether the abbreviation is inside a comment or
string, especially since there is no guarantee that the source code is
syntactically correct.  The scheme used will expand abbreviations that
occur inside comments, but after nested comments. (This may not be a bad
thing, since a typist in that situation is probably editing source code
that has been ``commented out''.)

A final problem: if the cursor just happens to be positioned at the end
of a word that just happens to be an abbreviation, and you type a space,
linefeed or punctuation character, the abbreviation gets expanded.  If all
this starts annoying you, you can turn off Abbrev-mode and use @kbd{C-x '}
(`expand-abbrev') to explicitly insert templates.

The default abbreviations and the Pascal structures that they insert are:

@table @kbd
@item ie
If-then-else statement.
@item if
If-then statement.
@item else
Else clause.  If the previous statement ended with a `;', that `;' is
removed.
@item ei
Else-if-then clause.  This is useful for building code sequences that
look like
@example
if a then
   s1
else if b then
   s2
else if c then
   @dots{}
@end example
Again, any previous `;' is removed.
@item while
While-do statement.
@item for
For-to-do statement.
@item with
With statement.
@item repeat
Repeat-until statement.
@item begin
Begin statement.
@item const
Const declaration section.
@item type
Type declaration section.
@item record
Record type template.
@item var
Variable declaration section.  Which template is inserted depends on
whether the abbreviation occurs in a routine's formal parameter list or a
declaration section.
@item fun
Function declaration.  This abbreviation is also treated differently in
parameter lists.
@item proc
Procedure declaration.  This abbreviation is also treated differently in
parameter lists.
@item prog
Program template.
@item int
Abbreviation for `integer'. (This makes life easier for C programmers).
@end table

This set of abbreviations will be installed the first time you use Pascal
mode.  When you leave Emacs, you will be given the option of saving them in
a file called `.abbrev_defs'.  Say yes, and it won't bother you again.

Lots of documentation on abbreviations is stored in the Info tree; use
C-h i if you are curious.

@node Variables, Customization, Abbreviations, Pascal
@subsection Variables

You can re-define these values in your init file to adjust certain features
to taste.

@table @kbd
@item comment-multi-line
The default value, @code{nil}, means that comments should not span line
boundaries.  Set it to @code{t} if you let comments cross line boundaries.

If it is @code{nil}, Pascal mode is more efficient, and newline-check-
and-indent will warn you about unclosed comments.  If you are typing a
comment and use @kbd{M-@key{LFD}} to continue the comment on a new line, or
if Fill mode is on and it starts a new line for you, comment delimiters
will be inserted if comment-multi-line is nil.  See the Info section on
comments for a better explanation.
@item pascal-comment-start
The string you like comments to start with (default @kbd{"@{ "}).
@item pascal-comment-end
The string you like comments to end with (default @kbd{"\t@}"}).
@item pascal-indent-level
The number of columns that continued statements should be indented
(default 3).
@item pascal-mode-hook
This variable's value should be @code{nil} or a function with no arguments.
The function will be called whenever a pascal file is opened.  You might
use this function to turn on Fill mode, or to turn off Abbrev mode.
(default @code{nil})
@item pascal-auto-newline
If this variable is non-nil, typing ``;'' at the end of a line causes
a new line to be started.  (Default @code{nil})
@item pascal-if-else-str	        pascal-begin-str
@itemx pascal-if-str			pascal-program-str
@itemx pascal-else-str		pascal-procedure-str
@itemx pascal-else-if-str		pascal-procedure-parm-str
@itemx pascal-while-str		pascal-function-str
@itemx pascal-for-str			pascal-function-parm-str
@itemx pascal-repeat-str		pascal-const-str
@itemx pascal-with-str		pascal-type-str
@itemx pascal-case-str		pascal-var-str
@itemx pascal-record-str		pascal-var-parm-str
These strings contain the templates for the associated abbreviation.  See
below for instructions on how to modify them.
@end table

@node Customization, Elision, Variables, Pascal
@subsection Customization

You probably hate the way everyone else indents Pascal code.  Fortunately
for you, Pascal mode can be adjusted.

Each template is stored in a defined constant.  For instance, the
if-then-else template is stored in @code{pascal-if-else-str}, which looks like
@example
   "if! then begin\n   \n   end\nelse begin\n   \n   end;"
@end example
If the typist enters
@example
   ie<@key{SPC}>
@end example
into a Pascal mode buffer, then the result is
@example
   if *then begin		(`*' marks the location of point)

      end
   else begin

      end;
@end example

Notes:
@itemize @bullet
@item
Formatting is controlled by putting spaces, tabs, and \n in the string.
Each ``line'' in the string is inserted with the same indentation that the
line containing the abbreviation had.
@item
The ``!'' in the string marks the approximate final location of point.  When
the abbreviation is expanded, the character that caused the expansion (in
this case, @key{SPC}) replaces the ``!'', and point is left there.  If the
string contains no ``!'', point is left at the end of the inserted text.
@item
The @code{begin}s and @code{end}s are not necessary, but there is no good reason to
leave them out of the template, since the typist won't have to type them.
Blank lines with 3 ``extra'' spaces are provided to make it easy to
enter correctly indented statements.  Typing C-n C-e with point in
the indicated spot moves point to the point immediately above the
`e' in the first @code{end}.
@end itemize

Now, let's assume that Fred likes his if-then-else statements arranged
like this:
@example
if condition then begin
      statement;
end else begin
      statement;
end;
@end example
In that case, Fred's init file should contain the lines
@example
      (defconst pascal-if-else-str
         "if! then begin\n        \nend else begin\n        \nend;")
@end example

You can also define new templates.  If you want an abbreviation to expand
into a string that contains no newlines, use the normal Abbrev-mode
functions as described in the Info sections on abbreviation.  This is the
way Pascal mode expands `int' into `integer'.

If you want a multi-line template, you will have to write an abbreviation
hook.  The hook for `ie' looks like this:
@example
	     (defun pascal-if-else-hook ()
	       (if (= 4 (pascal-point-state))
	           (insert-indented-string pascal-if-else-str)
		 (insert-string last-abbrev-text))
	       )
@end example
The function works like this:
@itemize @bullet
@item
pascal-point-state returns 1 if point is in a comment, 2 if it is in
a string, and 4 if it is in program text.
@item
If point is in program text, @code{insert-indented-string} inserts the
template string with proper indentation.  Otherwise, expansion shouldn't
be done, so the abbreviation that invoked the hook is restored.
@end itemize

Other useful functions are @code{pascal-in-parm}, which returns @code{t} if
the cursor is in a formal parameter list, and @code{no-prev-semi}, which
deletes the non-whitespace character before the cursor if it is `;'.

Once you have written your hook, you can install it by putting a line
similar to
@example
   ("ie" "" pascal-if-else-hook 0)
@end example
in the @code{pascal-mode-abbrev-table} section of your @code{.abbrev_defs}
file.

@node Elision, , Customization, Pascal    
@subsection Elision
The Elide minor mode provides support for selective hiding of text; see
the Info section on Elide for further details.  Elision can be tuned for
Pascal text with the @file{pascal-elide} library.  To use this library,
you should make sure that @file{pascal-elide.elc} is in one of the
directories in your load path.  (This will normally be true, since
@file{pascal-elide} and @file{pascal-mode} should be in the same
directory.)  You should put the line@refill
@example
(autoload 'pascal-elide-setup "pascal-elide" t);
@end example
in your Emacs initialization file, and the lines
@example
(pascal-elide-setup)
(elide-mode 1)
@end example
in your Pascal mode-hook function.

@code{pascal-elide-setup} causes functions and procedures to be treated
as sections, regardless of their indentation.  Hence, typing @kbd{C-c
C-h} when point is in the header of a function causes the declaration
and statement sections of the function to disappear.

@bye
