home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1993 May
/
SIMTEL_0593.ISO
/
msdos
/
eel
/
storey.eel
< prev
next >
Wrap
Text File
|
1988-09-30
|
86KB
|
2,983 lines
31-Oct-86 14:36:26-PST,5558;000000000001
Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 14:35:16 PST
Date: Fri 31 Oct 86 13:00:36-PST
From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
Subject: EEL code for Fortran and Pascal modes
To: info-ibmpc@B.ISI.EDU
Message-ID: <12251267181.17.FAT.STOREY@Sierra.Stanford.EDU>
I am sending a number of files which make up a Fortran and a Pascal mode
for Epsilon (I have V3.01). The files are: FOR_LOAD.E, FOR_MODE.E,
FOR_EXT.E, FOR_MENU, PAS_LOAD.E, PAS_MODE.E, PAS_EXT.E, and PAS_MENU.
I attempted to make them somewhat user friendly,
with some prompts and an on-line menu, but have not had time to document
everything, so the source code is the only complete description of what the
commands do. This should be usable by anyone with a version of Epsilon
that supports EEL code, but will probably be most useful to people with
some familiarity of EEL, who can customize the code to their particular
whims.
Because I often use the process window, and like to have memory available,
I set up the commands to be read in only when a Fortran (or Pascal) program
is being edited, similar to the auto-load stuff on UNIX Emacs. Thus, when
the commands are not used, they are not loaded. The Fortran commands will be
auto-loaded whenever a file with the extension .f or .for is edited, and
the Pascal commands with .p or .pas. In my system, I use a similar auto
loading for the C-mode, bufed, and dired commands, so my basic editor is
leaner than the standard configuration.
To set up the Fortran mode, the following files must be installed. First,
the file FOR_LOAD.E must be compiled and loaded into the basic Epsilon. I
suggest saving the state, rather than loading this file every time. Next,
set up a subdirectory \epsilon\modes, and compile the files FOR_MODE.E and
FOR_EXT.E, with the *.B output in this subdirectory. Also, copy the file
FOR_MENU into this subdirectory. The file FOR_LOAD.E assumes that the
auto-load files are in the subdirectory "C:\EPSILON\MODES". If a different
subdirectory will be used, lines 17 and 18 should be changed. If the menu is
in a different subdirectory, change line 12 of FOR_EXT.E. Similar steps will
set up the Pascal mode, using the PAS files instead of the FOR files.
There are two levels of complexity available. The first takes care of
indenting and several other minor chores. For the Fortran mode, this is in
the file FOR_MODE. The more complex mode is a template system, setting up a
SUBROUTINE outline or a DO loop outline, for example. These commands are in
the file FOR_EXT. If this extension is not desired, the auto-load command
"fort_mode()" should be altered, deleting the line
load_commands(FOR_EXT);
The organization of the Pascal mode is similar. For the extension commands,
a new prefix key CRTL-] is defined. This is intended to be analagous to the
prefix key CTRL-[. The key sequence CTRL-] CTRL-] will call up an on-line
menu of the available completions of the CTRL-].
For those who are not put off by EEL code, I have implemented a command which
prompts for and completes the Fortran or Pascal mode commands. However,
this requires modifying the source code of the file complete.e. I did not
want these modes to be unusable by people who do not want to mess with
the source code, so the files supplied have these commands - fort_named() and
pas_named() - as comments. For the adventureous types, the following
modifications are needed. First, remove the comment characters /* and */
surrounding the commands fsub_match(), get_fsub(), get_fsub_index(), and
fort_named() in FOR_EXT.E (similarly for the Pascal mode). Next, in the
Epsilon source file COMPLETE.E, make the following two changes:
1) Line 29: change
int i = 0, j, num_match = 0;
to
int i = strlen(trystr), j, num_match = 0;
2) Before every call to comp_read(), add the line
res[0]=0;
(8 occurances). The first change allows a partially formed string to be
passed to comp_read, so the command completed will already have the prefix
"fort-" or "pas-". The second change sets this initial string to NULL, so
the existing commands operate the same. Once these changes are made, and
the whole thing is recompiled, the completion is invoked by ALT-]. The
command is similar to the ALT-X command, prompting for fortran or pascal
commands and completing.
I have used both formats for about 9 months now, and I think I have cleaned
up all the major bugs. One minor bug that creeps in now and then is that
the new keytable associated with the prefix key CTRL-] seems to have bindings
which I never asked for. So, when a key which is not defined is pressed,
odd things sometimes happen. These have always been benign, and I have not
had the time to track down what is happening. If anyone does manage to fix
this, I would appreciate it if they would let me know what the problem is.
I grant full right to anyone to use and modify these programs, subject to
to conditions of the modified Lugaru code in the *_LOAD.E files. I would
appreciate hearing about any good extensions any bugs found, especially if
the cure has been found as well. I will be losing this computer account as I
move into the wild world of industry, so if there are any questions or
suggestions, the best way to contact me is by U.S. mail, at
James S. Storey
Teknekron, C.S.D.
2121 Allston Way
Berkeley, CA, 94704
(415) 548-4100
-------
31-Oct-86 13:17:38-PST,18890;000000000001
Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:14:27 PST
Date: Fri 31 Oct 86 13:13:13-PST
From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
Subject: FOR_EXT.E file
To: info-ibmpc@B.ISI.EDU
Message-ID: <12251269478.17.FAT.STOREY@Sierra.Stanford.EDU>
/* Written by James S. Storey */
/* Subroutines and commands in Fortran extension table (C-] table)
These routines insert templates for Fortran statements. */
#include "\epsilon\eel.h"
#define PREINDENT() if (current_column() < 6) move_to_column(6);\
if (current_column() < 6) to_column(6)
#define MENU "c:\\epsilon\\modes\\for_menu"
keytable fort_tab; /* table for basic commands */
keytable fort_ext_tab; /* table for extended commands */
buffer short bell_key;
get_fort_menu() /* make sure Fortran menu file is ready to go */
{
int exists = exist("-fort_menu");
char *oldbuf = bufname;
create("-fort_menu");
bufname = "-fort_menu";
if (!exists) {
sayput("Loading Fortran menu file. . .");
if (file_read(MENU, 1)) {
bufname = oldbuf;
delete_buffer("-fort_menu");
gripe("Can't find Fortran menu file %s", MENU);
say("");
return 0;
}
say("");
point = 0;
bufname = oldbuf;
return 1;
}
else {
if (size()==0) {
bufname = oldbuf;
delete_buffer("-fort_menu");
gripe("No Fortran menu file %s", MENU);
return 0;
}
point = 0;
bufname = oldbuf;
return 1;
}
}
fort_menu() on fort_ext_tab[CTRL(']')], fort_ext_tab['?']
{
sayput("C-] ");
if (get_fort_menu())
view_buffer("-fort_menu");
check_abort();
do {
getkey();
} while ((key == CTRL(']'))||(key == '?'));
say("");
do_again();
}
fort_function() on fort_ext_tab['f']
{
jmp_buf this_level, *old_level = top_level;
short orig_ret = fort_tab[CTRL('J')];
int i;
/* Set up abort trap to unbind keys */
top_level = &this_level;
bell_key = fort_tab[CTRL('G')];
if (setjmp(top_level)) {
major_mode = strsave("Fortran");
make_mode();
say("Aborted.");
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
top_level = old_level;
return;
}
PREINDENT();
bprintf("FUNCTION ()\n\n");
fort_indenter();
stuff("RETURN\n");
fort_indenter();
stuff("END\n");
for (i=1; i++<=4; nl_reverse())
;
move_to_column(6);
re_search(1,"[ \t]*");
insert(' ');
--point;
major_mode = strsave("FUNCTION type (single letter)");
strcpy(mode, major_mode);
maybe_refresh();
/* Get type, completing on a single key */
fort_tab[CTRL('G')] = find_index("f-abort");
reg_tab[CTRL('G')] = find_index("f-abort");
do {
getkey();
check_abort();
if ((key >= 'A') && (key <= 'Z'))
key -= 'A' - 'a';
switch (key) {
case ' ': {
delete(point,point+1);
break;
}
case 'c': {
stuff("CHARACTER");
break;
}
case 'd': {
stuff("DOUBLE PRECISION");
break;
}
case 'i': {
stuff("INTEGER");
break;
}
case 'j': {
stuff("COMPLEX");
break;
}
case 'l': {
stuff("LOGICAL");
break;
}
case 'r': {
stuff("REAL");
break;
}
case BELL: {
ungot_key=BELL;
f_abort();
break;
}
default : {
maybe_ding();
break;
}
}
} while (!index(" cdijlr",key));
/* Input function name in recursive edit mode. */
point += 10;
fort_tab[CTRL('J')] = find_index("exit-level");
fort_tab[(' ')] = find_index("exit-level");
major_mode = strsave("FUNCTION name (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
fort_tab[(' ')] = find_index("normal-character");
check_abort();
/* Input parameters in recursive edit mode. */
++point;
major_mode = strsave("FUNCTION parameters (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
/* Restore keys */
major_mode = strsave("Fortran");
make_mode();
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
nl_forward();
top_level = old_level;
}
fort_program() on fort_ext_tab['p']
{
int i;
PREINDENT();
bprintf("PROGRAM \n\n");
fort_indenter();
stuff("END\n");
for (i=1; i++<=3; nl_reverse())
;
}
fort_subroutine() on fort_ext_tab['s']
{
jmp_buf this_level, *old_level = top_level;
short orig_ret = fort_tab[CTRL('J')];
int i;
/* Set up abort trap to unbind keys */
top_level = &this_level;
bell_key = fort_tab[CTRL('G')];
if (setjmp(top_level)) {
major_mode = strsave("Fortran");
make_mode();
say("Aborted.");
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
top_level = old_level;
return;
}
PREINDENT();
bprintf("SUBROUTINE ()\n\n");
fort_indenter();
stuff("RETURN\n");
fort_indenter();
stuff("END\n");
for (i=1; i++<=3; nl_reverse())
;
point -=3;
/* Input subroutine name in recursive edit mode. */
fort_tab[CTRL('J')] = find_index("exit-level");
fort_tab[(' ')] = find_index("exit-level");
fort_tab[CTRL('G')] = find_index("f-abort");
reg_tab[CTRL('G')] = find_index("f-abort");
major_mode = strsave("SUBROUTINE name (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
fort_tab[(' ')] = find_index("normal-character");
check_abort();
/* Input parameters in recursive edit mode. */
++point;
major_mode = strsave("SUBROUTINE parameters (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
/* Restore keys */
major_mode = strsave("Fortran");
make_mode();
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
top_level = old_level;
nl_forward();
}
fort_character() on fort_ext_tab['a']
{
PREINDENT();
stuff("CHARACTER\t\t");
}
fort_double() on fort_ext_tab['d']
{
PREINDENT();
stuff("DOUBLE PRECISION\t");
}
fort_complex() on fort_ext_tab['j']
{
PREINDENT();
stuff("COMPLEX\t\t");
}
fort_integer() on fort_ext_tab['i']
{
PREINDENT();
stuff("INTEGER\t\t");
}
fort_logical() on fort_ext_tab['l']
{
PREINDENT();
stuff("LOGICAL\t\t");
}
fort_real() on fort_ext_tab['r']
{
PREINDENT();
stuff("REAL\t\t\t");
}
fort_common() on fort_ext_tab[ALT('c')]
{
PREINDENT();
stuff("COMMON / / ");
point-=3;
}
fort_data() on fort_ext_tab[ALT('d')]
{
PREINDENT();
stuff("DATA //");
point-=2;
}
fort_blockif() on fort_ext_tab[CTRL('B')]
{
short orig_ret = fort_tab[CTRL('J')];
bell_key = fort_tab[CTRL('G')];
PREINDENT();
stuff("IF () THEN\n");
fort_indenter();
fort_tabify();
insert('\n');
fort_indenter();
stuff("ENDIF\n");
nl_reverse();
nl_reverse();
nl_reverse();
point -= 6;
/* enter condition in recursive edit mode */
fort_tab[CTRL('G')] = find_index("f-abort");
reg_tab[CTRL('G')] = find_index("f-abort");
fort_tab[CTRL('J')] = find_index("exit-level");
major_mode = strsave("IF condition (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
/* Restore keys */
major_mode = strsave("Fortran");
make_mode();
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
check_abort();
nl_forward();
to_end_line();
}
fort_call() on fort_ext_tab['c']
{
stuff("CALL ()");
point-=2;
}
fort_continue() on fort_ext_tab[CTRL('C')]
{
PREINDENT();
stuff("CONTINUE\n");
fort_indenter();
}
fort_do() on fort_ext_tab[CTRL('D')]
{
jmp_buf this_level, *old_level = top_level;
char line_no[20];
int tag;
short orig_ret = fort_tab[CTRL('J')];
/* Set up abort trap to unbind keys */
top_level = &this_level;
bell_key = fort_tab[CTRL('G')];
if (setjmp(top_level)) {
major_mode = strsave("Fortran");
make_mode();
say("Aborted.");
fort_tab[' '] = find_index("maybe-break-line");
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
top_level = old_level;
return;
}
PREINDENT();
bprintf("DO =,\n");
fort_indenter();
fort_tabify();
nl_reverse();
point -= 3;
/* Input line number in recursive edit mode.
Space or <cr> exits. */
fort_tab[CTRL('J')] = find_index("exit-level");
fort_tab[' '] = find_index("exit-level");
fort_tab[CTRL('G')] = find_index("f-abort");
reg_tab[CTRL('G')] = find_index("f-abort");
major_mode = strsave("DO CONTINUE line number (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
/* Grab the line number if entered */
tag = point;
re_search(-1,"[0123456789]*");
if (point!=tag)
grab(point,tag,line_no);
nl_forward();
to_end_line();
insert('\n');
fort_indenter();
fort_tabify();
stuff("continue\n");
nl_reverse();
nl_reverse();
tag = point++;
bprintf("%5.5s",line_no);
re_search(1,"[ \t]*");
say("Continuation line?");
major_mode = strsave("DO CONTINUE query");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
delete(point,point+8);
if ((key == CTRL('H'))||(toupper(key) == 'N')||(key == GREYBACK)) {
to_end_line();
delete(tag,point);
}
else
stuff("CONTINUE");
say("");
/* Input index in recursive edit mode. <cr> exits */
search(-1,"=,");
major_mode = strsave("DO index (<cr> or Space to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
/* insert range */
++point;
major_mode = strsave("DO start (<cr> or Space to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
++point;
major_mode = strsave("DO end (<cr> or Space to exit)");
strcpy(mode, major_mode);
recursive_edit();
/* Restore keys */
major_mode = strsave("Fortran");
make_mode();
fort_tab[' '] = find_index("maybe-break-line");
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
top_level = old_level;
check_abort();
++point;
nl_forward();
--point;
}
fort_else() on fort_ext_tab[CTRL('E')]
{
PREINDENT();
fort_delete_tab();
stuff("ELSE\n");
fort_indenter();
fort_tabify();
}
fort_elseif() on fort_ext_tab['e']
{
short orig_ret = fort_tab[CTRL('J')];
bell_key = fort_tab[CTRL('G')];
PREINDENT();
fort_delete_tab();
stuff("ELSEIF () THEN\n");
fort_indenter();
fort_tabify();
nl_reverse();
point -= 6;
/* enter condition in recursive edit mode */
fort_tab[CTRL('J')] = find_index("exit-level");
fort_tab[CTRL('G')] = find_index("f-abort");
reg_tab[CTRL('G')] = find_index("f-abort");
major_mode = strsave("ELSE IF condition (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
/* Restore keys */
major_mode = strsave("Fortran");
make_mode();
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
check_abort();
nl_forward();
nl_forward();
--point;
}
fort_goto() on fort_ext_tab['g']
{
PREINDENT();
stuff("GOTO ");
}
fort_if() on fort_ext_tab[CTRL('I')]
{
short orig_ret = fort_tab[CTRL('J')];
bell_key = fort_tab[CTRL('G')];
PREINDENT();
stuff("IF () ");
point -= 2;
/* enter condition in recursive edit mode */
fort_tab[CTRL('J')] = find_index("exit-level");
fort_tab[CTRL('G')] = find_index("f-abort");
reg_tab[CTRL('G')] = find_index("f-abort");
major_mode = strsave("IF condition (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
/* Restore keys */
major_mode = strsave("Fortran");
make_mode();
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
check_abort();
point +=2;
}
fort_format() on fort_ext_tab[CTRL('f')]
{
jmp_buf this_level, *old_level = top_level;
char line_no[20];
short orig_ret = fort_tab[CTRL('J')];
int tag;
/* Set up abort trap to unbind keys */
top_level = &this_level;
bell_key = fort_tab[CTRL('G')];
if (setjmp(top_level)) {
major_mode = strsave("Fortran");
make_mode();
say("Aborted.");
fort_tab[' '] = find_index("maybe-break-line");
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
top_level = old_level;
return;
}
PREINDENT();
bprintf("FORMAT ()");
to_begin_line();
/* Input line number in recursive edit mode.
Space or <cr> exits. */
fort_tab[CTRL('J')] = find_index("exit-level");
fort_tab[' '] = find_index("exit-level");
fort_tab[CTRL('G')] = find_index("f-abort");
reg_tab[CTRL('G')] = find_index("f-abort");
major_mode = strsave("FORMAT line number");
make_mode();
recursive_edit();
check_abort();
/* Grab the line number if entered, and right justify */
tag = point;
re_search(-1,"[0123456789]*");
if (point!=tag) {
grab(point,tag,line_no);
move_to_column(0);
delete(point,tag);
bprintf("%5.5s",line_no);
}
/* Restore keys */
major_mode = strsave("Fortran");
make_mode();
fort_tab[' '] = find_index("maybe-break-line");
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
top_level = old_level;
search(1,"FORMAT (");
}
fort_open() on fort_ext_tab[CTRL('o')]
{
jmp_buf this_level, *old_level = top_level;
char unit_no[20];
int tag;
short orig_ret = fort_tab[CTRL('J')];
/* Set up abort trap to unbind keys */
top_level = &this_level;
bell_key = fort_tab[CTRL('G')];
if (setjmp(top_level)) {
major_mode = strsave("Fortran");
make_mode();
say("Aborted.");
fort_tab[' '] = find_index("maybe-break-line");
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
top_level = old_level;
return;
}
PREINDENT();
bprintf("OPEN (*,FILE='for*.dat',status='new')");
point -= 31;
major_mode = strsave("OPEN unit number (<cr> or Space to exit)");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
check_abort();
ungot_key = key;
delete(point,point+1);
/* Input unit number in recursive edit mode.
Space, or <cr> exits. */
fort_tab[CTRL('J')] = find_index("exit-level");
fort_tab[' '] = find_index("exit-level");
fort_tab[CTRL('G')] = find_index("f-abort");
reg_tab[CTRL('G')] = find_index("f-abort");
recursive_edit();
fort_tab[' '] = find_index("maybe-break-line");
/* Grab the unit number if entered, and right justify */
tag = point;
re_search(-1,"[0123456789]*");
if (point!=tag) {
grab(point,tag,unit_no);
}
else{
unit_no[0] = 0;
}
/* Query standard file name */
if (search(1,"for*")) {
delete(point,point-1);
tag = point-3;
bprintf("%.4s",unit_no);
point = tag;
say("Standard Filename?");
major_mode = strsave("OPEN filename query");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))
||(toupper(key) == 'N')||(key == GREYBACK)) {
if (search(1,"dat")) {
delete(tag,point);
/* Enter filename in recursive edit */
major_mode = strsave(
"OPEN file name (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
}
}
else {
delete(point,point+3);
stuff("FOR");
if (search(1,"dat")) {
delete(point-3,point);
stuff("DAT");
}
}
say("");
}
/* Query status */
if (search(1,"status")) {
point -= 6;
say("Status=New?");
major_mode = strsave("OPEN status query");
strcpy(mode,major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
delete(point,point+12);
if ((key == CTRL('H'))
||(toupper(key) == 'N')||(key == GREYBACK)) {
delete(point-1,point);
}
else
stuff("STATUS='NEW'");
say("");
}
/* Restore keys */
major_mode = strsave("Fortran");
make_mode();
fort_tab[CTRL('J')] = orig_ret;
reg_tab[CTRL('G')] = find_index("abort");
fort_tab[CTRL('G')] = bell_key;
check_abort();
top_level = old_level;
to_end_line();
}
fort_read() on fort_ext_tab[CTRL('r')]
{
PREINDENT();
stuff("READ (*,*) ");
/* Input unit number */
point -= 5;
maybe_refresh();
getkey();
if (isdigit(key)) {
delete(point,point+1);
while (isdigit(key)) {
insert(key);
maybe_refresh();
getkey();
}
}
else {
check_abort();
++point;
}
/* Input format line number */
++point;
maybe_refresh();
getkey();
if (isdigit(key)) {
delete(point,point+1);
while (isdigit(key)) {
insert(key);
maybe_refresh();
getkey();
}
}
else {
check_abort();
++point;
}
point += 2;
}
fort_write() on fort_ext_tab[CTRL('w')]
{
PREINDENT();
stuff("WRITE (*,*) ");
/* Input unit number */
point -= 5;
maybe_refresh();
getkey();
if (isdigit(key)) {
delete(point,point+1);
while (isdigit(key)) {
insert(key);
maybe_refresh();
getkey();
}
}
else {
check_abort();
++point;
}
/* Input format line number */
++point;
maybe_refresh();
getkey();
if (isdigit(key)) {
delete(point,point+1);
while (isdigit(key)) {
insert(key);
maybe_refresh();
getkey();
}
}
else {
check_abort();
++point;
}
point += 2;
}
/* Commands to prompt for and complete names of fort- routines */
/* Requires modified COMPLETE.E file */
/*
/char *fsub_match(s, start)
/char *s;
/{
/int i;
/
/for (; i = name_match(s, start); start = 0)
/ switch (name_type(i)) {
/ case NT_COMMAND: case NT_SUBR:
/ return name_name(i);
/ }
/return 0;
/}
/
/get_fsub(res, pr)
/char *res, *pr;
/{
/strcpy(res,"fort-");
/comp_read(res, pr, fsub_match, 0);
/}
/
/get_fsub_index(pr)
/char *pr;
/{
/char fsub[80];
/int name_index;
/
/get_fsub(fsub, pr);
/name_index = find_index(fsub);
/if (name_index && (name_type(name_index) == NT_SUBR ||
/ name_type(name_index) == NT_COMMAND))
/ return name_index;
/error("There's no Fortran command named '%.50s'.",fsub);
/return 0;
/}
/
/command fort_named() on fort_tab[ALT(']')], fort_tab[FALT(2)]
/{
/char msg[40];
/int index;
/
/if (has_arg)
/ sprintf(msg, "%d Fortran Command: ", iter);
/else
/ sprintf(msg, "Fortran Command: ");
/if (index = get_fsub_index(msg))
/ do_command(index);
/}
*/
when_loading()
{
int i;
fort_tab[CTRL(']')] = find_index("fort-ext-tab");
for (i = 'A'; i <= 'Z'; i++) {
if (fort_ext_tab[ALT(i)] <= 0)
fort_ext_tab[ALT(i)] = find_index("case-indirect");
if (fort_ext_tab[i] <= 0)
fort_ext_tab[i] = find_index("case-indirect");
}
fort_ext_tab[CTRL('H')] = find_index("fort-delete-tab");
}
-------
31-Oct-86 13:17:39-PST,577;000000000001
Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:15:14 PST
Date: Fri 31 Oct 86 13:13:40-PST
From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
Subject: FOR_MENU file
To: info-ibmpc@B.ISI.EDU
Message-ID: <12251269559.17.FAT.STOREY@Sierra.Stanford.EDU>
^B block if d double prec. l logical
c call i integer ^O open
a character ^E else p program
A-c common e elseif ^R read
j complex ^F format r real
^C continue f function s subroutine
A-d data g goto ^W write
^D do ^I if
-------
31-Oct-86 13:17:40-PST,2239;000000000001
Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:15:35 PST
Date: Fri 31 Oct 86 13:14:11-PST
From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
Subject: PAS_LOAD.E file
To: info-ibmpc@B.ISI.EDU
Message-ID: <12251269653.17.FAT.STOREY@Sierra.Stanford.EDU>
/************************************************************************
* "Epsilon", "EEL" and "Lugaru" are trademarks of Lugaru Software, Ltd. *
* *
* Copyright (C) 1985 Lugaru Software Ltd. All rights reserved. *
* *
* Limited permission is hereby granted to reproduce and modify this *
* copyrighted material provided that the resulting code is used only in *
* conjunction with Lugaru products and that this notice is retained in *
* any such reproduction or modification. *
************************************************************************/
/* Developed by James S. Storey */
#include "\epsilon\eel.h"
/* This mode auto-loads from files PAS_MODE and PAS_EXT */
#define PAS_MODE "c:\\epsilon\\modes\\pas_mode"
#define PAS_EXT "c:\\epsilon\\modes\\pas_ext"
/* Format buffer for Pascal programs.
This command puts the current buffer in the Pascal mode,
appropriate for editing programs written in Pascal.
Command names are of the form pas-COMMAND. A series of
statement commands automatically insert a template for most
Pascal statements. These statement commands are bound to keys
prefixed by the C-] key.
By default, the find-file command automatically turns on
Pascal mode for files with the extensions .p or .pas. */
command pas_mode()
{
char *_pas_tab = "pas-tab", *_ind_ptr = "pas-indenter";
short *_pas_ptr;
if (!find_index("pas-tab")) {
sayput("Loading Pascal mode commands. . .");
load_commands(PAS_MODE);
load_commands(PAS_EXT);
say("");
}
_pas_ptr=index_table(find_index(_pas_tab));
mode_keys = _pas_ptr;
major_mode = strsave("Pascal");
make_mode();
(short) indenter = find_index(_ind_ptr);
auto_indent = 1;
}
/* make this the default mode for .p and .pas files */
suffix_p() { pas_mode(); }
suffix_pas() { pas_mode(); }
-------
31-Oct-86 13:17:41-PST,5975;000000000001
Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:15:55 PST
Date: Fri 31 Oct 86 13:14:40-PST
From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
Subject: PAS_MODE.E file
To: info-ibmpc@B.ISI.EDU
Message-ID: <12251269742.17.FAT.STOREY@Sierra.Stanford.EDU>
/* Written by James S. Storey */
/* Subroutines and commands for Pascal mode.
These commands are read in when Pascal mode is invoked for the
first time */
#include "\epsilon\eel.h"
/* define an RE matching Pascal comments or whitespace */
#define P_LSKIP "((%(%*([^*]|%*[^)])*%*%))|{([^}])*}|[ \t\n])*"
/* define an RE matching Pascal comments or whitespace, on same line */
#define P_SKIP "((%(%*([^*\n]|%*[^)\n])*%*%))|{([^}\n])*}|[ \t])*"
int Matchdelim = 1; /* 1 for showing matching ')' */
keytable pas_tab; /* key table for Pascal mode */
buffer short bell_key;
p_abort()
{
pas_tab[BELL] = bell_key;
reg_tab[BELL] = find_index("abort");
if (recursion_level>0)
exit_level();
user_abort = 1;
}
/* backward-kill-spaces(back) Delete up to BACK spaces preceding point */
backward_kill_spaces(back)
int back;
{
int orig = point;
re_search(-1,"( )*");
if (point <= orig-back) {
point = orig;
delete(point-back,point);
}
else {
delete(point,orig);
}
}
/* pas-tabify Indent by half-tabs.
If the point is in the current line's indentation, a half-tab is
added to the indentation. Otherwise, a half-tab is added before
the point.
When adding half-tabs, if the point is preceded by 1/2 a tab or
more spaces, the spaces following the last tab-stop are deleted
and a tab is added. Otherwise, spaces are added up to 1/2 a tab
past the last tab stop. */
#define HALF_TAB tab_size/2
command pas_tabify() on pas_tab[CTRL('I')]
{
int orig = point, excess, lack;
/* skip leading blanks */
to_begin_line();
if (!re_search(1, "[^ \t]") || point > orig) { /* skip blanks */
point = orig;
to_indentation();
}
else /* restore point */
point = orig;
/* Insert half tab */
excess = (current_column()%tab_size);
lack = HALF_TAB-excess;
if (lack > 0) { /* between tab and half-tab stops */
for (; lack-- > 0; insert(' ')) ;
}
else { /* between half-tab and tab stops */
backward_kill_spaces(excess);
insert('\t');
}
}
/* pas-delete-tab Delete a half tab preceding the point, hacking full
tabs. */
pas_delete_tab() /* on pas_ext_tab[CTRL('H')] */
{
int excess, i;
excess = (current_column()%tab_size);
if (excess == 0) { /* at a tab stop */
if (character(point-1) == '\t') {
/* delete previous tab, insert half tab */
delete(point-1,point);
for( i=1 ; i++ <=HALF_TAB ; insert(' ')) ;
}
else /* delete to last non-space or half tab stop */
backward_kill_spaces(HALF_TAB);
}
else {
if (excess <= HALF_TAB) /* Between tab and half tab */
backward_kill_spaces(excess);
else /* Between half tab and tab */
backward_kill_spaces(excess-HALF_TAB);
}
}
/* pas-comment Insert a pascal comment. */
command pas_comment() on pas_tab[ALT(';')]
{
#define L_COMMENT "(*"
#define R_COMMENT "*)"
int com_size;
short orig_alt_ret = pas_tab[CTRL(ALT('j'))];
bell_key = pas_tab[BELL];
com_size = strlen(R_COMMENT);
bprintf("%s %s",L_COMMENT,R_COMMENT);
point -= com_size+1;
major_mode = strsave("COMMENT body (BACKSPACE to delete)");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (((key == CTRL('H'))||(key == GREYBACK))||(key == CTRL('G'))) {
delete(point-com_size-1,point+com_size+1);
major_mode = strsave("Pascal");
strcpy(mode, major_mode);
}
else {
ungot_key = key;
pas_tab[BELL] = find_index("p-abort");
reg_tab[BELL] = find_index("p-abort");
pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
major_mode = strsave("COMMENT body (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
major_mode = strsave("Pascal");
strcpy(mode, major_mode);
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
check_abort();
reg_tab[BELL] = find_index("abort");
pas_tab[BELL] = bell_key;
point += com_size+1;
}
}
/* pas_indenter Like the command indent previous, but gives no indentation
if the previous line is not indented. */
command pas_indenter() on pas_tab[ALT('i')]
{
int orig_column, prev_indent;
int orig = point;
orig_column = current_column(); /* point's column */
to_begin_line();
if (re_search(-1, "[^ \t\n]")) { /* find previous non-blank line */
to_indentation();
prev_indent = current_column();
}
else
prev_indent = 0;
point = orig;
to_indentation(); /* go to current line's indent */
to_column(prev_indent); /* indentation as previous */
}
/* pas-return Insert a ';' if necessary, then return. */
pas_return() on pas_tab[CTRL('J')]
{
int orig = point;
char prev,comm[3];
to_end_line();
if (point == orig) {
re_search(-1,P_SKIP);
if (point>0) {
prev = character(point-1);
if ( (prev!=';') && (prev!='\n') ) {
grab(point-2,point,comm);
if ( (strncmp(comm,"*)",2)) &&
(prev!='}')) {
insert(';');
++orig;
}
}
}
}
point = orig;
insert('\n');
pas_indenter();
}
/* norm-return Normal return. */
norm_return() on pas_tab[CTRL(ALT('j'))],pas_tab[ALT('j')]
{
insert('\n');
pas_indenter();
}
/* pas-equal Inserts " := " */
pas_equal() on pas_tab['=']
{
stuff(" := ");
}
normal_equal() on pas_tab[ALT('=')]
{
insert('=');
}
when_loading()
{
int i;
pas_tab[CTRL('M')] = find_index("newline");
pas_tab[CTRL('H')] = find_index("delete-hacking-tabs");
for (i = 'A'; i <= 'Z'; i++)
if (pas_tab[ALT(i)] <= 0)
pas_tab[ALT(i)] = find_index("case-indirect");
if (Matchdelim)
pas_tab[')'] = pas_tab[']'] =
find_index("show-matching-delimiter");
}
-------
31-Oct-86 13:22:40-PST,28968;000000000001
Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:18:05 PST
Date: Fri 31 Oct 86 13:17:04-PST
From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
Subject: PAS_EXT.E file
To: info-ibmpc@B.ISI.EDU
Message-ID: <12251270179.17.FAT.STOREY@Sierra.Stanford.EDU>
/* Written by James S. Storey */
/* Subroutines and commands in Pascal extension table (C-] table)
These routines insert templates for Pascal statements. */
#include "\epsilon\eel.h"
#define MENU "c:\\epsilon\\modes\\pas_menu"
/* define an RE matching Pascal comments or whitespace, on same line */
#define P_SKIP "((%(%*([^*\n]|%*[^)\n])*%*%))|{([^}\n])*}|[ \t])*"
keytable pas_tab; /* table for basic commands */
keytable pas_ext_tab; /* table for extended commands */
buffer short bell_key;
int end_comments = 1; /* end_comments=1 causes comments to be added to
end statements */
get_pas_menu() /* make sure Pascal menu file is ready to go */
{
int exists = exist("-pas_menu");
char *oldbuf = bufname;
create("-pas_menu");
bufname = "-pas_menu";
if (!exists) {
sayput("Loading Pascal menu file. . .");
if (file_read(MENU, 1)) {
bufname = oldbuf;
delete_buffer("-menu");
gripe("Can't find Pascal menu file %s", MENU);
say("");
return 0;
}
say("");
point = 0;
bufname = oldbuf;
return 1;
}
else {
if (size()==0) {
bufname = oldbuf;
delete_buffer("-pas_menu");
gripe("No Pascal menu file %s", MENU);
return 0;
}
point = 0;
bufname = oldbuf;
return 1;
}
}
pas_menu() on pas_ext_tab[CTRL(']')], pas_ext_tab['?']
{
sayput("C-] ");
if (get_pas_menu())
view_buffer("-pas_menu");
check_abort();
do {
getkey();
} while ((key == CTRL(']'))||(key == '?'));
say("");
do_again();
}
command set_comments() /* Command to toggle end_comments */
{
end_comments = (has_arg? (iter != 0) : !end_comments);
say(end_comments?"End comments":"No end comments");
iter = 1;
}
pas_begin() on pas_ext_tab[CTRL('B')]
{
stuff("BEGIN\n");
pas_tabify();
insert('\n');
pas_indenter();
pas_tabify();
stuff("END;");
if (end_comments)
stuff(" (* BEGIN *)");
search(-1,"\n");
}
pas_end() on pas_ext_tab['e']
{
stuff("END;\n");
pas_indenter();
}
pas_program() on pas_ext_tab['p']
{
jmp_buf this_level, *old_level = top_level;
int i, tag1, tag2, diff1, diff2;
char prog_name[40];
short orig_ret = pas_tab[CTRL('J')],
orig_alt_ret = pas_tab[CTRL(ALT('j'))];
/* Set up abort trap to unbind keys */
top_level = &this_level;
bell_key = pas_tab[CTRL('G')];
if (setjmp(top_level)) {
major_mode = strsave("Pascal");
make_mode();
say("Aborted.");
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
top_level = old_level;
return;
}
/* Insert PROGRAM, BEGIN/END block, label with program name */
bprintf("PROGRAM ();\n\n");
stuff("BEGIN");
if (end_comments)
stuff(" (* *)");
tag1 = point-3;
insert('\n');
pas_tabify();
insert('\n');
stuff("END.");
if (end_comments) {
stuff(" (* *)");
tag2 = point-3;
}
insert('\n');
for (i=1; i++<=5; nl_reverse())
;
point -= 4;
/* tag BEGIN and END comments for inserting program name */
if (end_comments) {
diff1 = tag1-point;
diff2 = tag2-point;
}
/* Input program name in recursive edit mode.
<cr>, A-<cr> and space exit from recursion */
pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
pas_tab[CTRL('J')] = find_index("exit-level");
pas_tab[CTRL('G')] = find_index("p-abort");
reg_tab[CTRL('G')] = find_index("p-abort");
pas_tab[' '] = find_index("exit-level");
major_mode = strsave("PROGRAM name (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
pas_tab[' '] = find_index("normal-character");
pas_tab[CTRL('J')] = orig_ret;
check_abort();
/* Grab the program name and insert it in BEGIN and END comments */
if (end_comments) {
tag1 = point;
backward_word();
grab(point,tag1,prog_name);
point = tag1+diff2;
stuff(prog_name);
point = tag1+diff1;
stuff(prog_name);
point = tag1+2;
}
/* Input parameters in recursive edit mode. A-<cr> exits */
major_mode = strsave("PROGRAM parameters (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
/* Set point to beginning of next block, and tag location */
nl_forward();
nl_forward();
tag1 = point;
/* Insert CONST declaration block, and delete if C-H is input */
insert('\n');
--point;
stuff("CONST\n");
pas_tabify();
stuff(";\n");
point -= 2;
major_mode = strsave("PROGRAM CONST block (BACKSPACE to delete)");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(tag1,point+3);
}
else {
ungot_key = key;
delete(point,point+1);
major_mode = strsave("PROGRAM CONST block (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
nl_forward();
nl_forward();
tag1 = point;
}
/* Insert TYPE declaration block, and delete if C-H is input */
insert('\n');
--point;
stuff("TYPE\n");
pas_tabify();
stuff(";\n");
point -= 2;
major_mode = strsave("PROGRAM TYPE block (BACKSPACE to delete)");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(tag1,point+3);
}
else {
ungot_key = key;
delete(point,point+1);
major_mode = strsave("PROGRAM TYPE block (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
nl_forward();
nl_forward();
tag1 = point;
}
/* Insert VAR declaration block, and delete if C-H is input */
insert('\n');
--point;
stuff("VAR\n");
pas_tabify();
stuff(";\n");
point -= 2;
major_mode = strsave("PROGRAM VAR block (BACKSPACE to delete)");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(tag1,point+3);
}
else {
ungot_key = key;
delete(point,point+1);
major_mode = strsave("PROGRAM VAR block (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
nl_forward();
nl_forward();
tag1 = point;
}
/* Restore keys */
major_mode = strsave("Pascal");
make_mode();
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
top_level = old_level;
/* Move point to beginning of program body */
nl_forward();
to_end_line();
}
pas_var_param()
{
stuff("VAR ");
}
pas_procedure() on pas_ext_tab[CTRL('P')]
{
jmp_buf this_level, *old_level = top_level;
int i, tag1, tag2, diff1, diff2, left = current_column();
char proc_name[40];
short orig_ret = pas_tab[CTRL('J')],
orig_alt_ret = pas_tab[CTRL(ALT('j'))];
/* Set up abort trap to unbind keys */
top_level = &this_level;
bell_key = pas_tab[CTRL('G')];
if (setjmp(top_level)) {
major_mode = strsave("Pascal");
make_mode();
say("Aborted.");
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
top_level = old_level;
return;
}
/* Insert PROCEDURE, BEGIN/END block, label with procedure name */
bprintf("PROCEDURE ();\n\n");
to_column(left);
stuff("BEGIN");
if (end_comments)
stuff(" (* *)");
tag1 = point-3;
insert('\n');
to_column(left);
pas_tabify();
insert('\n');
to_column(left);
stuff("END;");
if (end_comments) {
stuff(" (* *)");
tag2 = point-3;
}
insert('\n');
for (i=1; i++<=5; nl_reverse())
;
point -= 4;
/* tag BEGIN and END comments for inserting procedure name */
if (end_comments) {
diff1 = tag1-point;
diff2 = tag2-point;
}
/* Input procedure name in recursive edit mode.
<cr>, A-<cr> and space exit from recursion */
pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
pas_tab[CTRL('J')] = find_index("exit-level");
pas_tab[' '] = find_index("exit-level");
pas_tab[CTRL('G')] = find_index("p-abort");
reg_tab[CTRL('G')] = find_index("p-abort");
major_mode = strsave("PROCEDURE name (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
pas_tab[' '] = find_index("normal-character");
pas_tab[CTRL('J')] = orig_ret;
check_abort();
/* Grab the procedure name and insert it in BEGIN and END comments */
tag1 = point;
if (end_comments) {
backward_word();
grab(point,tag1,proc_name);
point = tag1+diff2;
stuff(proc_name);
point = tag1+diff1;
stuff(proc_name);
}
point = tag1+2;
/* Input parameters in recursive edit mode. A-<cr> exits,
^V inserts the string "VAR " */
pas_tab[CTRL('V')] = (short) pas_var_param;
major_mode = strsave("PROCEDURE parameters (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
pas_tab[CTRL('V')] = find_index("next-page");
check_abort();
/* Set point to beginning of next block, and tag location */
nl_forward();
nl_forward();
tag1 = point;
/* Insert TYPE declaration block, and delete if C-H is input */
insert('\n');
--point;
to_column(left);
stuff("TYPE\n");
to_column(left);
pas_tabify();
stuff(";\n");
point -= 2;
major_mode = strsave("PROCEDURE TYPE block (BACKSPACE to delete)");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(tag1,point+3);
}
else {
ungot_key = key;
delete(point,point+1);
major_mode = strsave("PROCEDURE TYPE block (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
nl_forward();
nl_forward();
tag1 = point;
}
/* Insert VAR declaration block, and delete if C-H is input */
insert('\n');
--point;
to_column(left);
stuff("VAR\n");
to_column(left);
pas_tabify();
stuff(";\n");
point -= 2;
major_mode = strsave("PROCEDURE VAR block (BACKSPACE to delete)");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(tag1,point+3);
}
else {
ungot_key = key;
delete(point,point+1);
major_mode = strsave("PROCEDURE VAR block (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
nl_forward();
nl_forward();
tag1 = point;
}
/* Restore keys */
major_mode = strsave("Pascal");
make_mode();
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
top_level = old_level;
/* Move point to beginning of procedure body */
nl_forward();
to_end_line();
}
pas_function() on pas_ext_tab['f']
{
jmp_buf this_level, *old_level = top_level;
int i, tag1, tag2, diff1, diff2, left = current_column();
char func_name[40];
short orig_ret = pas_tab[CTRL('J')],
orig_alt_ret = pas_tab[CTRL(ALT('j'))];
/* Set up abort trap to unbind keys */
top_level = &this_level;
bell_key = pas_tab[CTRL('G')];
if (setjmp(top_level)) {
major_mode = strsave("Pascal");
make_mode();
say("Aborted.");
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
top_level = old_level;
return;
}
/* Insert FUNCTION, BEGIN/END block, label with function name */
bprintf("FUNCTION (): ;\n\n");
to_column(left);
stuff("BEGIN");
if (end_comments)
stuff(" (* *)");
tag1 = point-3;
insert('\n');
to_column(left);
pas_tabify();
insert('\n');
to_column(left);
stuff("END;");
if (end_comments) {
stuff(" (* *)");
tag2 = point-3;
}
insert('\n');
for (i=1; i++<=5; nl_reverse())
;
point -= 6;
/* tag BEGIN and END comments for inserting function name */
if (end_comments) {
diff1 = tag1-point;
diff2 = tag2-point;
}
/* Input function name in recursive edit mode.
<cr>, A-<cr> and space exit from recursion */
pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
pas_tab[CTRL('J')] = find_index("exit-level");
pas_tab[' '] = find_index("exit-level");
pas_tab[CTRL('G')] = find_index("p-abort");
reg_tab[CTRL('G')] = find_index("p-abort");
major_mode = strsave("FUNCTION name (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
pas_tab[' '] = find_index("normal-character");
pas_tab[CTRL('J')] = orig_ret;
check_abort();
/* Grab the function name and insert it in BEGIN and END comments */
tag1 = point;
if (end_comments) {
backward_word();
grab(point,tag1,func_name);
point = tag1+diff2;
stuff(func_name);
point = tag1+diff1;
stuff(func_name);
}
point = tag1+2;
/* Input parameters in recursive edit mode. A-<cr> exits,
^V inserts the string "VAR " */
pas_tab[CTRL('V')] = (short) pas_var_param;
major_mode = strsave("FUNCTION parameters (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
pas_tab[CTRL('V')] = find_index("next-page");
check_abort();
/* Input function type in recursive edit mode.
<cr> or A-<cr> exits. */
search(1,":");
++point;
pas_tab[CTRL('J')] = find_index("exit-level");
major_mode = strsave("FUNCTION type (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
pas_tab[CTRL('J')] = orig_ret;
check_abort();
/* Set point to beginning of next block, and tag location */
nl_forward();
nl_forward();
tag1 = point;
/* Insert TYPE declaration block, and delete if C-H is input */
insert('\n');
--point;
to_column(left);
stuff("TYPE\n");
to_column(left);
pas_tabify();
stuff(";\n");
point -= 2;
major_mode = strsave("FUNCTION TYPE block (BACKSPACE to delete)");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(tag1,point+3);
}
else {
ungot_key = key;
delete(point,point+1);
major_mode = strsave("FUNCTION TYPE block (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
nl_forward();
nl_forward();
tag1 = point;
}
/* Insert VAR declaration block, and delete if C-H is input */
insert('\n');
--point;
to_column(left);
stuff("VAR\n");
to_column(left);
pas_tabify();
stuff(";\n");
point -= 2;
major_mode = strsave("FUNCTION VAR block (BACKSPACE to delete)");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(tag1,point+3);
}
else {
ungot_key = key;
delete(point,point+1);
major_mode = strsave("FUNCTION VAR block (A-<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
nl_forward();
nl_forward();
tag1 = point;
}
/* Restore keys */
major_mode = strsave("Pascal");
make_mode();
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
top_level = old_level;
/* Move point to beginning of function body */
nl_forward();
to_end_line();
}
pas_var() on pas_ext_tab[CTRL('V')]
{
stuff("VAR\n");
pas_indenter();
pas_tabify();
}
pas_type() on pas_ext_tab[CTRL('T')]
{
stuff("TYPE\n");
pas_indenter();
pas_tabify();
}
pas_record() on pas_ext_tab['r']
{
int left ,exit;
/* Insert RECORD */
stuff("RECORD\n");
point -= 7;
/* Check for new indentation */
exit = 0;
say("Set indentation (TAB or BACKSPACE)");
do {
refresh();
getkey();
switch (key) {
case CTRL('H') : ;
case GREYBACK : {
pas_delete_tab();
break;
}
case CTRL('I') : ;
case GREYTAB : {
pas_tabify();
break;
}
default : exit = 1;
}
} while (!exit);
say("");
check_abort();
left = current_column();
/* Insert END */
nl_forward();
to_column(left);
pas_tabify();
insert('\n');
to_column(left);
stuff("END;");
if (end_comments)
stuff(" (* RECORD *)");
nl_reverse();
insert(';');
--point;
maybe_refresh();
getkey();
check_abort();
ungot_key = key;
delete(point,point+1);
}
pas_while() on pas_ext_tab[CTRL('W')]
{
int tag1,tag2;
short orig_ret = pas_tab[CTRL('J')],
orig_eq = pas_tab['='],
orig_alt_ret = pas_tab[CTRL(ALT('j'))];
bell_key = pas_tab[CTRL('G')];
/* Insert WHILE DO */
stuff("WHILE DO\n");
point -= 4;
/* Input condition in recursive edit mode. A-<cr> or <cr> exits */
pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
pas_tab['='] = find_index("normal-character");
pas_tab[CTRL('J')] = find_index("exit-level");
pas_tab[CTRL('G')] = find_index("p-abort");
reg_tab[CTRL('G')] = find_index("p-abort");
major_mode = strsave("WHILE condition (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
major_mode = strsave("Pascal");
make_mode();
pas_tab[CTRL('J')] = orig_ret;
pas_tab['='] = orig_eq;
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
check_abort();
/* Insert BEGIN/END pair, delete if CTRL('H') is entered */
to_end_line();
tag1 = point;
stuff(" BEGIN");
nl_forward();
pas_indenter();
pas_tabify();
insert('\n');
pas_indenter();
pas_tabify();
stuff("END;");
if (end_comments)
stuff(" (* WHILE *)");
tag2 = point;
nl_reverse();
insert(';');
--point;
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(point,tag2+1);
delete(tag1,tag1+6);
}
else {
ungot_key = key;
delete(point,point+1);
}
}
pas_for() on pas_ext_tab[CTRL('F')]
{
jmp_buf this_level, *old_level = top_level;
int tag1,tag2;
short orig_ret = pas_tab[CTRL('J')],
orig_alt_ret = pas_tab[CTRL(ALT('j'))];
/* Set up abort trap to unbind keys */
top_level = &this_level;
bell_key = pas_tab[CTRL('G')];
if (setjmp(top_level)) {
major_mode = strsave("Pascal");
make_mode();
say("Aborted.");
pas_tab[CTRL('J')] = orig_ret;
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
top_level = old_level;
return;
}
/* Insert FOR TO DO */
stuff("FOR := TO DO\n");
point -= 12;
/* Input index in recursive edit mode. A-<cr> or <cr> exits */
pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
pas_tab[CTRL('J')] = find_index("exit-level");
pas_tab[CTRL('G')] = find_index("p-abort");
reg_tab[CTRL('G')] = find_index("p-abort");
major_mode = strsave("FOR index (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
/* find ":=" on this line */
to_begin_line();
search(1,":=");
/* Input start in recursive edit mode. A-<cr> or <cr> exits */
++point;
major_mode = strsave("FOR start (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
check_abort();
/* Change TO to DOWNTO on 'd' or 'D' */
re_search(1,"( )*");
stuff("down");
point -= 4;
major_mode = strsave("FOR downTO (d for DOWNTO)");
strcpy(mode, major_mode);
maybe_refresh();
delete(point,point+4);
getkey();
if (key == CTRL('G'))
error("Aborted.");
if (toupper(key) == 'D')
stuff("DOWN");
/* Input end in recursive edit mode. A-<cr> or <cr> exits */
point += 3;
major_mode = strsave("FOR end (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
pas_tab[CTRL('J')] = orig_ret;
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
top_level = old_level;
check_abort();
/* Insert BEGIN/END pair, delete if CTRL('H') is entered */
to_end_line();
tag1 = point;
stuff(" BEGIN");
nl_forward();
pas_indenter();
pas_tabify();
insert('\n');
pas_indenter();
pas_tabify();
stuff("END;");
if (end_comments)
stuff(" (* FOR *)");
tag2 = point;
nl_reverse();
insert(';');
--point;
major_mode = strsave("FOR body (BACKSPACE to delete)");
strcpy(mode, major_mode);
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(point,tag2+1);
delete(tag1,tag1+6);
}
else {
ungot_key = key;
delete(point,point+1);
}
major_mode = strsave("Pascal");
make_mode();
}
pas_with() on pas_ext_tab['w']
{
int tag1,tag2;
short orig_ret = pas_tab[CTRL('J')],
orig_eq = pas_tab['='],
orig_alt_ret = pas_tab[CTRL(ALT('j'))];
bell_key = pas_tab[CTRL('G')];
/* Insert WITH DO */
stuff("WITH DO\n");
point -= 4;
/* Input condition in recursive edit mode. A-<cr> or <cr> exits */
pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
pas_tab['='] = find_index("normal-character");
pas_tab[CTRL('J')] = find_index("exit-level");
pas_tab[CTRL('G')] = find_index("p-abort");
reg_tab[CTRL('G')] = find_index("p-abort");
major_mode = strsave("WHILE condition (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
major_mode = strsave("Pascal");
make_mode();
pas_tab[CTRL('J')] = orig_ret;
pas_tab['='] = orig_eq;
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
check_abort();
/* Insert BEGIN/END pair, delete if CTRL('H') is entered */
to_end_line();
tag1 = point;
stuff(" BEGIN");
nl_forward();
pas_indenter();
pas_tabify();
insert('\n');
pas_indenter();
pas_tabify();
stuff("END;");
if (end_comments)
stuff(" (* WITH *)");
tag2 = point;
nl_reverse();
insert(';');
--point;
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(point,tag2+1);
delete(tag1,tag1+6);
}
else {
ungot_key = key;
delete(point,point+1);
}
}
pas_if() on pas_ext_tab[CTRL('I')]
{
int tag1,tag2;
short orig_ret = pas_tab[CTRL('J')],
orig_eq = pas_tab['='],
orig_alt_ret = pas_tab[CTRL(ALT('j'))];
bell_key = pas_tab[CTRL('G')];
/* Insert IF THEN */
stuff("IF THEN\n");
point -= 6;
/* Input condition in recursive edit mode. A-<cr> or <cr> exits */
pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
pas_tab['='] = find_index("normal-character");
pas_tab[CTRL('J')] = find_index("exit-level");
pas_tab[CTRL('G')] = find_index("p-abort");
reg_tab[CTRL('G')] = find_index("p-abort");
major_mode = strsave("IF condition (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
major_mode = strsave("Pascal");
make_mode();
pas_tab[CTRL('J')] = orig_ret;
pas_tab['='] = orig_eq;
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
check_abort();
/* Insert BEGIN/END pair, delete if CTRL('H') is entered */
to_end_line();
tag1 = point;
stuff(" BEGIN");
nl_forward();
pas_indenter();
pas_tabify();
insert('\n');
pas_indenter();
pas_tabify();
stuff("END;");
if (end_comments)
stuff(" (* THEN *)");
tag2 = point;
nl_reverse();
insert(';');
--point;
maybe_refresh();
getkey();
if (key == CTRL('G'))
error("Aborted.");
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(point,tag2+1);
delete(tag1,tag1+6);
}
else {
ungot_key = key;
delete(point,point+1);
}
}
pas_else() on pas_ext_tab[CTRL('E')]
{
int tag1,tag2;
short exit;
/* delete half-tab */
pas_delete_tab();
/* Insert ELSE */
stuff("ELSE\n");
/* Delete ; on previous line */
--point;
nl_reverse();
re_search(-1,P_SKIP);
if (character(point-1) == ';')
delete(point-1,point);
nl_forward();
nl_forward();
point -= 5;
/* Check for new indentation */
exit = 0;
say("Set indentation (TAB or BACKSPACE)");
do {
refresh();
getkey();
switch (key) {
case CTRL('H') : ;
case GREYBACK : {
pas_delete_tab();
break;
}
case CTRL('I') : ;
case GREYTAB : {
pas_tabify();
break;
}
default : exit = 1;
}
} while (!exit);
say("");
check_abort();
/* Insert BEGIN/END pair, delete if CTRL('H') is entered */
to_end_line();
tag1 = point;
stuff(" BEGIN");
nl_forward();
pas_indenter();
pas_tabify();
insert('\n');
pas_indenter();
pas_tabify();
stuff("END;");
if (end_comments)
stuff(" (* ELSE *)");
tag2 = point;
nl_reverse();
insert(';');
--point;
maybe_refresh();
getkey();
check_abort();
if ((key == CTRL('H'))||(key == GREYBACK)) {
delete(point,tag2+1);
delete(tag1,tag1+6);
}
else {
ungot_key = key;
delete(point,point+1);
}
}
pas_repeat() on pas_ext_tab[CTRL('R')]
{
short exit, orig_ret = pas_tab[CTRL('J')],
orig_eq = pas_tab['='],
orig_alt_ret = pas_tab[CTRL(ALT('j'))];
bell_key = pas_tab[CTRL('G')];
/* Insert REPEAT */
stuff("REPEAT\n");
point -= 7;
/* Check for new indentation */
exit = 0;
say("Set indentation (TAB or BACKSPACE)");
do {
refresh();
getkey();
switch (key) {
case CTRL('H') : ;
case GREYBACK : {
pas_delete_tab();
break;
}
case CTRL('I') : ;
case GREYTAB : {
pas_tabify();
break;
}
default : exit = 1;
}
} while (!exit);
say("");
check_abort();
/* Insert UNTIL */
nl_forward();
insert('\n');
pas_indenter();
stuff("UNTIL ;");
--point;
/* Input condition in recursive edit mode. A-<cr> or <cr> exits */
pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
pas_tab['='] = find_index("normal-character");
pas_tab[CTRL('J')] = find_index("exit-level");
pas_tab[CTRL('G')] = find_index("p-abort");
reg_tab[CTRL('G')] = find_index("p-abort");
major_mode = strsave("UNTIL condition (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
major_mode = strsave("Pascal");
make_mode();
pas_tab[CTRL('J')] = orig_ret;
pas_tab['='] = orig_eq;
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
check_abort();
/* go to indentation of loop body */
nl_reverse();
pas_indenter();
pas_tabify();
}
pas_case() on pas_ext_tab[CTRL('C')]
{
short orig_ret = pas_tab[CTRL('J')],
orig_alt_ret = pas_tab[CTRL(ALT('j'))];
bell_key = pas_tab[CTRL('G')];
/* Insert CASE OF */
stuff("CASE OF\n");
point -= 4;
/* Input case expression in recursive edit mode.
A-<cr> or <cr> exits */
pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
pas_tab[CTRL('J')] = find_index("exit-level");
pas_tab[CTRL('G')] = find_index("p-abort");
reg_tab[CTRL('G')] = find_index("p-abort");
major_mode = strsave("CASE expression (<cr> to exit)");
strcpy(mode, major_mode);
recursive_edit();
major_mode = strsave("Pascal");
make_mode();
reg_tab[CTRL('G')] = find_index("abort");
pas_tab[CTRL('G')] = bell_key;
pas_tab[CTRL('J')] = orig_ret;
pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
check_abort();
/* Insert END */
to_end_line();
nl_forward();
pas_indenter();
pas_tabify();
insert('\n');
pas_indenter();
pas_tabify();
stuff("END;");
if (end_comments)
stuff(" (* CASE *)");
nl_reverse();
insert(' :');
point-=2;
}
/* Commands to prompt for and complete names of pas- routines */
/* Requires modified COMPLETE.E file */
/*
/char *psub_match(s, start)
/char *s;
/{
/int i;
/
/for (; i = name_match(s, start); start = 0)
/ switch (name_type(i)) {
/ case NT_COMMAND: case NT_SUBR:
/ return name_name(i);
/ }
/return 0;
/}
/
/get_psub(res, pr)
/char *res, *pr;
/{
/strcpy(res,"pas-");
/comp_read(res, pr, psub_match, 0);
/}
/
/get_psub_index(pr)
/char *pr;
/{
/char psub[80];
/int name_index;
/
/get_psub(psub, pr);
/name_index = find_index(psub);
/if (name_index && (name_type(name_index) == NT_SUBR ||
/ name_type(name_index) == NT_COMMAND))
/ return name_index;
/error("There's no Pascal command named '%.50s'.",psub);
/return 0;
/}
/
/command pas_named() on pas_tab[ALT(']')], pas_tab[FALT(2)]
/{
/char msg[40];
/int index;
/
/if (has_arg)
/ sprintf(msg, "%d Pascal Command: ", iter);
/else
/ sprintf(msg, "Pascal Command: ");
/if (index = get_psub_index(msg))
/ do_command(index);
/}
*/
when_loading()
{
int i;
pas_tab[CTRL(']')] = find_index("pas-ext-tab");
for (i = 'A'; i <= 'Z'; i++) {
if (pas_ext_tab[ALT(i)] <= 0)
pas_ext_tab[ALT(i)] = find_index("case-indirect");
if (pas_ext_tab[i] <= 0)
pas_ext_tab[i] = find_index("case-indirect");
}
pas_ext_tab[CTRL('H')] = find_index("pas-delete-tab");
}
-------
31-Oct-86 13:22:44-PST,503;000000000001
Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:19:20 PST
Date: Fri 31 Oct 86 13:17:37-PST
From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
Subject: PAS_MENU file
To: info-ibmpc@B.ISI.EDU
Message-ID: <12251270280.17.FAT.STOREY@Sierra.Stanford.EDU>
^B begin ^H del tabs ^T type
^C case ^I if w with
^E else ^P procedure ^W while
e end p program ^V var
^F for r record
f function ^R repeat
-------
31-Oct-86 14:14:03-PST,8796;000000000001
Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 14:12:27 PST
Date: Fri 31 Oct 86 13:05:00-PST
From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
Subject: FOR_MODE.E file
To: info-ibmpc@B.ISI.EDU
Message-ID: <12251267981.17.FAT.STOREY@Sierra.Stanford.EDU>
/* Written by James S. Storey */
/* Subroutines and commands for Fortran mode.
These commands are read in when Fortran mode is invoked for the
first time */
#include "\epsilon\eel.h"
int structured = 1; /* 1 indents to previous line, 0 indents to col 7 */
int Matchdelim = 1; /* 1 for showing matching ')' */
keytable fort_tab; /* key table for Fortran mode */
buffer short bell_key;
f_abort()
{
fort_tab[BELL] = bell_key;
reg_tab[BELL] = find_index("abort");
if (recursion_level>0)
exit_level();
user_abort = 1;
}
/* Routine used by fort-cont and fort-indent to decide how to continue
the line. */
fort_cont_indent()
{
char cont_char;
int eol = point, indent_col;
to_begin_line();
cont_char=curchar();
if (index("*cC",cont_char)) { /* Previous line was a comment */
indent_col = 3;
if (structured) { /* find first darkspace past col 1 */
++point; /* skip comment character */
if ((re_search(1, "[^ \t]")) && (point <= eol)) {
/* set indentation to begn of darkspace */
indent_col = current_column() -1;
}
}
point = eol+1;
bprintf("%c ",cont_char);
to_column(indent_col);
}
else { /* Previous line was a statement */
indent_col = 6;
if (structured) { /* find first darkspace past col 1 */
move_to_column(6);
if ((re_search(1, "[^ \t]")) && (point <= eol)) {
/* set indentation to begn of darkspace */
indent_col = current_column() -1;
}
}
point = eol+1;
bprintf(" +");
to_column(indent_col);
}
}
/* fort-cont Fortran continue current line.
Continues current line on next line. If the current line is
blank, another blank line is inserted. If the current line is
a comment line, the comment character is copied to the next
line and the line is indented to column 4. If the current line
is a program line, the continuation character '+' is inserted
in column 6 */
command fort_cont() on fort_tab[ALT('j')], fort_tab[CTRL(ALT('j'))]
{
insert('\n');
--point;
fort_cont_indent();
}
/* fort-late-cont This command makes an existing line into a
continuation of the previous line. */
command fort_late_cont() /* on A-N-+ */
{
int orig = point;
move_to_column(6);
if (current_column() < 6) {
to_column(5);
insert('+');
}
else {
if (character(point-1) == '\t')
orig += tab_size - 1;
delete_hacking_tabs();
insert('+');
point = orig;
}
}
/* command to toggle structured indentation */
command set_struct()
{
structured = (has_arg? (iter != 0) : !structured);
say(structured?"Structured indentation on" :
"Structured indentation off");
iter = 1;
}
/* fort-indenter Indent newlines in Fortran mode.
Called following a newline character. If the newline is at the
end of a line, the line is indented normally. If the newline
is the middle of a program line, the line is continued as in
"fort-cont", Fortran continue current line.
Bugs: With auto-fill, it continues lines after a newline if the
last character in the previous line is at the fill-column, and
it does not continue lines if more than one space preceded the
character which caused the auto-fill. */
fort_indenter()
{
int orig = point;
/* Check for newline at the end of a line, or followed by blanks */
to_end_line();
if (!re_search(-1, "[^ \t]") || point < orig) {
/* Check for auto-return */
point = orig-1;
if ((current_column() < margin_right-1) || !(fill_mode)) {
++point;
if (structured) {
indent_previous();
if (current_column() < 6)
to_column(6);
}
else
to_column(6); /* indent to column 7 */
}
else
/* Auto-return, continue previous line */
fort_cont_indent();
}
else {
point = orig-1;
fort_cont_indent();
}
}
/* backward-kill-spaces(back) Delete up to BACK spaces preceding point */
backward_kill_spaces(back)
int back;
{
int orig = point;
re_search(-1,"( )*");
if (point <= orig-back) {
point = orig;
delete(point-back,point);
}
else {
delete(point,orig);
}
}
/* fort-tabify Indent by half-tabs.
If the point is in the current line's indentation, a half-tab is
added to the indentation. Otherwise, if the point is in columns
1 to 6, whitespace is added out to column 6, or if the point is
past column 6, a half-tab is added before the point.
When adding half-tabs, if the point is preceded by 1/2 a tab or
more spaces, the spaces following the last tab-stop are deleted
and a tab is added. Otherwise, spaces are added up to 1/2 a tab
past the last tab stop. */
#define HALF_TAB tab_size/2
command fort_tabify() on fort_tab[CTRL('I')]
{
int orig = point, excess, lack;
/* skip leading blanks */
to_begin_line();
if (!re_search(1, "[^ \t]") || point > orig) { /* skip blanks */
point = orig;
to_indentation();
}
else /* restore point */
point = orig;
/* Tabify line */
if (current_column() < 5 ) /* insert tab */
to_column(6);
else { /* insert half-tab */
excess = (current_column()%tab_size);
lack = HALF_TAB-excess;
if (lack > 0) { /* between tab and half-tab stops */
for (; lack-- > 0; insert(' ')) ;
}
else { /* between half-tab and tab stops */
backward_kill_spaces(excess);
insert('\t');
}
}
}
/* fort-delete-tab If at column 7, delete the label field. Otherwise,
Delete a half tab preceding the point, hacking full tabs. */
fort_delete_tab() /* on fort_ext_tab[CTRL('H')] */
{
int excess, i;
if (current_column() == tab_size) {
if (character(point-1) == '\t')
delete(point-1,point);
else
backward_kill_spaces(tab_size);
return;
}
/* Else */
excess = (current_column()%tab_size);
if (excess == 0) { /* at a tab stop */
if (character(point-1) == '\t') {
/* delete previous tab, insert half tab */
delete(point-1,point);
for( i=1 ; i++ <=HALF_TAB ; insert(' ')) ;
}
else /* delete to last non-space or half tab stop */
backward_kill_spaces(HALF_TAB);
}
else {
if (excess <= HALF_TAB) /* Between tab and half tab */
backward_kill_spaces(excess);
else /* Between half tab and tab */
backward_kill_spaces(excess-HALF_TAB);
}
}
/* fort-merge Fortran merge continuation with previous.
Merges the current line with the previous, removing line numbers
and continuation characters (if necessary) for statement lines,
and removing the comment character for comment lines. An error
message is given if the command would merge a comment character
onto the end of a statement character. */
command fort_merge() on fort_tab[ALT('^')]
{
int orig = point, bol;
to_begin_line();
bol = point;
if (index("*cC",curchar())) { /* Merge continuation line */
--point;
to_begin_line();
if (!index("*cC",curchar())) {
/* Error: Attempt to Merge with statement */
say("Error: cannot merge continuation line with statement line");
point = orig;
return;
}
else {
if (orig = bol)
orig = bol-1;
else
orig -= 2;
delete(bol-1,bol+1);
}
}
else {
if (!search(1, "\t") || (point > bol+6)) {
/* No tabs in Col 1-6 */
if (orig < bol+6)
orig = bol-1; /* end of previous line */
else
orig -= 7; /* orig minus amount deleted */
delete(bol-1,bol+6);
}
else {
if (orig < point)
orig = bol-1; /* end of previous line */
else
orig -= point-bol+1;
/* orig minus amount deleted */
delete(bol-1,point);
}
}
point = orig;
}
/* fort-comment Pad the current line with blanks out to column 80.
This command allows end of line comments that will wrap to the
next screen line. */
command fort_comment() on fort_tab[ALT(';')]
{
int orig=point, col7;
move_to_column(6);
col7 = point;
for (point = orig; point <= col7+72; insert(' '))
;
}
when_loading()
{
int i;
for (i = 'A'; i <= 'Z'; i++)
if (fort_tab[ALT(i)] <= 0)
fort_tab[ALT(i)] = find_index("case-indirect");
if (Matchdelim)
fort_tab[')'] = find_index("show-matching-delimiter");
fort_tab[ALT('i')] = find_index("indent-under");
fort_tab[CTRL('M')] = find_index("newline");
fort_tab[CTRL('H')] = find_index("delete-hacking-tabs");
keytran[NUMALT(GREYPLUS)] = NUMALT(GREYPLUS);
fort_tab[NUMALT(GREYPLUS)] = (short) fort_late_cont;
}
-------
31-Oct-86 14:36:29-PST,2275;000000000001
Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 14:35:36 PST
Date: Fri 31 Oct 86 13:01:12-PST
From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
Subject: FOR_LOAD.E files
To: info-ibmpc@B.ISI.EDU
Message-ID: <12251267290.17.FAT.STOREY@Sierra.Stanford.EDU>
/************************************************************************
* "Epsilon", "EEL" and "Lugaru" are trademarks of Lugaru Software, Ltd. *
* *
* Copyright (C) 1985 Lugaru Software Ltd. All rights reserved. *
* *
* Limited permission is hereby granted to reproduce and modify this *
* copyrighted material provided that the resulting code is used only in *
* conjunction with Lugaru products and that this notice is retained in *
* any such reproduction or modification. *
************************************************************************/
/* Developed by James S. Storey */
#include "\epsilon\eel.h"
/* This mode auto-loads from files FOR_MODE and FOR_EXT */
#define FOR_MODE "c:\\epsilon\\modes\\for_mode"
#define FOR_EXT "c:\\epsilon\\modes\\for_ext"
/* Format buffer for FORTRAN programs.
This command puts the current buffer in the Fortran mode,
appropriate for editing programs written in Fortran.
Command names are of the form fort-COMMAND. A series of
statement commands automatically insert a template for most
Fortran statements. These statement commands are bound to keys
prefixed by the C-] key.
By default, the find-file command automatically turns on
Fortran mode for files with the extensions .f or .for. */
command fort_mode()
{
char *_fort_tab = "fort-tab", *_ind_ptr = "fort-indenter";
short *_fort_ptr;
if (!find_index("fort-tab")) {
sayput("Loading Fortran mode commands. . .");
load_commands(FOR_MODE);
load_commands(FOR_EXT);
say("");
}
_fort_ptr=index_table(find_index(_fort_tab));
mode_keys = _fort_ptr;
major_mode = strsave("Fortran");
make_mode();
(short) indenter = find_index(_ind_ptr);
auto_indent = 1;
tab_size = 6;
}
/* make this the default mode for .f and .for files */
suffix_f() { fort_mode(); }
suffix_for() { fort_mode(); }
-------
-------