home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / eel / storey.zip / STOREY.EEL
Text File  |  1988-09-30  |  86KB  |  2,983 lines

  1.      
  2. 31-Oct-86 14:36:26-PST,5558;000000000001
  3. Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
  4. Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 14:35:16 PST
  5. Date: Fri 31 Oct 86 13:00:36-PST
  6. From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
  7. Subject: EEL code for Fortran and Pascal modes
  8. To: info-ibmpc@B.ISI.EDU
  9. Message-ID: <12251267181.17.FAT.STOREY@Sierra.Stanford.EDU>
  10.      
  11.      
  12. I am sending a number of files which make up a Fortran and a Pascal mode
  13. for Epsilon (I have V3.01).  The files are: FOR_LOAD.E, FOR_MODE.E,
  14. FOR_EXT.E, FOR_MENU, PAS_LOAD.E, PAS_MODE.E, PAS_EXT.E, and PAS_MENU.
  15. I attempted to make them somewhat user friendly,
  16. with some prompts and an on-line menu, but have not had time to document
  17. everything, so the source code is the only complete description of what the
  18. commands do.  This should be usable by anyone with a version of Epsilon
  19. that supports EEL code, but will probably be most useful to people with
  20. some familiarity of EEL, who can customize the code to their particular
  21. whims.
  22.      
  23. Because I often use the process window, and like to have memory available,
  24. I set up the commands to be read in only when a Fortran (or Pascal) program
  25. is being edited, similar to the auto-load stuff on UNIX Emacs.  Thus, when
  26. the commands are not used, they are not loaded.  The Fortran commands will be
  27. auto-loaded whenever a file with the extension .f or .for is edited, and
  28. the Pascal commands with .p or .pas.  In my system, I use a similar auto
  29. loading for the C-mode, bufed, and dired commands, so my basic editor is
  30. leaner than the standard configuration.
  31.      
  32. To set up the Fortran mode, the following files must be installed.  First,
  33. the file FOR_LOAD.E must be compiled and loaded into the basic Epsilon.  I
  34. suggest saving the state, rather than loading this file every time.  Next,
  35. set up a subdirectory \epsilon\modes, and compile the files FOR_MODE.E and
  36. FOR_EXT.E, with the *.B output in this subdirectory.  Also, copy the file
  37. FOR_MENU into this subdirectory.  The file FOR_LOAD.E assumes that the
  38. auto-load files are in the subdirectory "C:\EPSILON\MODES".  If a different
  39. subdirectory will be used, lines 17 and 18 should be changed.  If the menu is
  40. in a different subdirectory, change line 12 of FOR_EXT.E.  Similar steps will
  41. set up the Pascal mode, using the PAS files instead of the FOR files.
  42.      
  43. There are two levels of complexity available.  The first takes care of
  44. indenting and several other minor chores.  For the Fortran mode, this is in
  45. the file FOR_MODE.  The more complex mode is a template system, setting up a
  46. SUBROUTINE outline or a DO loop outline, for example.  These commands are in
  47. the file FOR_EXT.  If this extension is not desired, the auto-load command
  48. "fort_mode()" should be altered, deleting the line
  49.      
  50.         load_commands(FOR_EXT);
  51.      
  52. The organization of the Pascal mode is similar.  For the extension commands,
  53. a new prefix key CRTL-] is defined.  This is intended to be analagous to the
  54. prefix key CTRL-[.  The key sequence CTRL-] CTRL-] will call up an on-line
  55. menu of the available completions of the CTRL-].
  56.      
  57. For those who are not put off by EEL code, I have implemented a command which
  58. prompts for and completes the Fortran or Pascal mode commands.  However,
  59. this requires modifying the source code of the file complete.e.  I did not
  60. want these modes to be unusable by people who do not want to mess with
  61. the source code, so the files supplied have these commands - fort_named() and
  62. pas_named() - as comments.  For the adventureous types, the following
  63. modifications are needed.  First, remove the comment characters /* and */
  64. surrounding the commands fsub_match(), get_fsub(), get_fsub_index(), and
  65. fort_named() in FOR_EXT.E (similarly for the Pascal mode).  Next, in the
  66. Epsilon source file COMPLETE.E, make the following two changes:
  67.      
  68. 1) Line 29: change
  69.      
  70.     int i = 0, j, num_match = 0;
  71.      
  72. to
  73.      
  74.     int i = strlen(trystr), j, num_match = 0;
  75.      
  76. 2) Before every call to comp_read(), add the line
  77.      
  78.     res[0]=0;
  79.      
  80. (8 occurances).  The first change allows a partially formed string to be
  81. passed to comp_read, so the command completed will already have the prefix
  82. "fort-" or "pas-".  The second change sets this initial string to NULL, so
  83. the existing commands operate the same.  Once these changes are made, and
  84. the whole thing is recompiled, the completion is invoked by ALT-].  The
  85. command is similar to the ALT-X command, prompting for fortran or pascal
  86. commands and completing.
  87.      
  88. I have used both formats for about 9 months now, and I think I have cleaned
  89. up all the major bugs.  One minor bug that creeps in now and then is that
  90. the new keytable associated with the prefix key CTRL-] seems to have bindings
  91. which I never asked for.  So, when a key which is not defined is pressed,
  92. odd things sometimes happen.  These have always been benign, and I have not
  93. had the time to track down what is happening.  If anyone does manage to fix
  94. this, I would appreciate it if they would let me know what the problem is.
  95.      
  96. I grant full right to anyone to use and modify these programs, subject to
  97. to conditions of the modified Lugaru code in the *_LOAD.E files.  I would
  98. appreciate hearing about any good extensions any bugs found, especially if
  99. the cure has been found as well.  I will be losing this computer account as I
  100. move into the wild world of industry, so if there are any questions or
  101. suggestions, the best way to contact me is by U.S. mail, at
  102.      
  103.     James S. Storey
  104.     Teknekron, C.S.D.
  105.     2121 Allston Way
  106.     Berkeley, CA, 94704
  107.      
  108.     (415) 548-4100
  109. -------
  110. 31-Oct-86 13:17:38-PST,18890;000000000001
  111. Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
  112. Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:14:27 PST
  113. Date: Fri 31 Oct 86 13:13:13-PST
  114. From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
  115. Subject: FOR_EXT.E file
  116. To: info-ibmpc@B.ISI.EDU
  117. Message-ID: <12251269478.17.FAT.STOREY@Sierra.Stanford.EDU>
  118.      
  119.      
  120. /* Written by James S. Storey */
  121.      
  122. /* Subroutines and commands in Fortran extension table (C-] table)
  123.     These routines insert templates for Fortran statements. */
  124.      
  125. #include "\epsilon\eel.h"
  126.      
  127. #define PREINDENT() if (current_column() < 6) move_to_column(6);\
  128. if (current_column() < 6) to_column(6)
  129.      
  130. #define MENU "c:\\epsilon\\modes\\for_menu"
  131.      
  132. keytable fort_tab;    /* table for basic commands */
  133. keytable fort_ext_tab;    /* table for extended commands */
  134.      
  135. buffer short bell_key;
  136.      
  137. get_fort_menu()    /* make sure Fortran menu file is ready to go */
  138. {
  139.     int exists = exist("-fort_menu");
  140.     char *oldbuf = bufname;
  141.      
  142.      
  143.     create("-fort_menu");
  144.     bufname = "-fort_menu";
  145.     if (!exists) {
  146.         sayput("Loading Fortran menu file. . .");
  147.         if (file_read(MENU, 1)) {
  148.             bufname = oldbuf;
  149.             delete_buffer("-fort_menu");
  150.             gripe("Can't find Fortran menu file %s", MENU);
  151.             say("");
  152.             return 0;
  153.         }
  154.         say("");
  155.         point = 0;
  156.         bufname = oldbuf;
  157.         return 1;
  158.     }
  159.     else {
  160.         if (size()==0) {
  161.             bufname = oldbuf;
  162.             delete_buffer("-fort_menu");
  163.             gripe("No Fortran menu file %s", MENU);
  164.             return 0;
  165.         }
  166.         point = 0;
  167.         bufname = oldbuf;
  168.         return 1;
  169.     }
  170. }
  171.      
  172. fort_menu() on fort_ext_tab[CTRL(']')], fort_ext_tab['?']
  173. {
  174.     sayput("C-] ");
  175.     if (get_fort_menu())
  176.         view_buffer("-fort_menu");
  177.     check_abort();
  178.     do {
  179.         getkey();
  180.     } while ((key == CTRL(']'))||(key == '?'));
  181.     say("");
  182.     do_again();
  183. }
  184.      
  185. fort_function()    on fort_ext_tab['f']
  186. {
  187.     jmp_buf this_level, *old_level = top_level;
  188.     short orig_ret = fort_tab[CTRL('J')];
  189.     int i;
  190.      
  191.     /* Set up abort trap to unbind keys */
  192.     top_level = &this_level;
  193.     bell_key = fort_tab[CTRL('G')];
  194.     if (setjmp(top_level)) {
  195.         major_mode = strsave("Fortran");
  196.         make_mode();
  197.         say("Aborted.");
  198.         fort_tab[CTRL('J')] = orig_ret;
  199.         reg_tab[CTRL('G')] = find_index("abort");
  200.         fort_tab[CTRL('G')] = bell_key;
  201.         top_level = old_level;
  202.         return;
  203.     }
  204.      
  205.     PREINDENT();
  206.     bprintf("FUNCTION ()\n\n");
  207.     fort_indenter();
  208.     stuff("RETURN\n");
  209.     fort_indenter();
  210.     stuff("END\n");
  211.     for (i=1; i++<=4; nl_reverse())
  212.         ;
  213.     move_to_column(6);
  214.     re_search(1,"[ \t]*");
  215.     insert(' ');
  216.     --point;
  217.     major_mode = strsave("FUNCTION type (single letter)");
  218.     strcpy(mode, major_mode);
  219.     maybe_refresh();
  220.      
  221.     /* Get type, completing on a single key */
  222.     fort_tab[CTRL('G')] = find_index("f-abort");
  223.     reg_tab[CTRL('G')] = find_index("f-abort");
  224.     do {
  225.         getkey();
  226.         check_abort();
  227.         if ((key >= 'A') && (key <= 'Z'))
  228.             key -= 'A' - 'a';
  229.         switch (key) {
  230.             case ' ': {
  231.                 delete(point,point+1);
  232.                 break;
  233.             }
  234.             case 'c': {
  235.                 stuff("CHARACTER");
  236.                 break;
  237.             }
  238.             case 'd': {
  239.                 stuff("DOUBLE PRECISION");
  240.                 break;
  241.             }
  242.             case 'i': {
  243.                 stuff("INTEGER");
  244.                 break;
  245.             }
  246.             case 'j': {
  247.                 stuff("COMPLEX");
  248.                 break;
  249.             }
  250.             case 'l': {
  251.                 stuff("LOGICAL");
  252.                 break;
  253.             }
  254.             case 'r': {
  255.                 stuff("REAL");
  256.                 break;
  257.             }
  258.             case BELL: {
  259.                 ungot_key=BELL;
  260.                 f_abort();
  261.                 break;
  262.             }
  263.             default : {
  264.                 maybe_ding();
  265.                 break;
  266.             }
  267.         }
  268.     } while (!index(" cdijlr",key));
  269.      
  270.     /* Input function name in recursive edit mode. */
  271.     point += 10;
  272.     fort_tab[CTRL('J')] = find_index("exit-level");
  273.     fort_tab[(' ')] = find_index("exit-level");
  274.     major_mode = strsave("FUNCTION name (<cr> to exit)");
  275.     strcpy(mode, major_mode);
  276.     recursive_edit();
  277.     fort_tab[(' ')] = find_index("normal-character");
  278.     check_abort();
  279.      
  280.     /* Input parameters in recursive edit mode. */
  281.     ++point;
  282.     major_mode = strsave("FUNCTION parameters (<cr> to exit)");
  283.     strcpy(mode, major_mode);
  284.     recursive_edit();
  285.     check_abort();
  286.      
  287.     /* Restore keys */
  288.     major_mode = strsave("Fortran");
  289.     make_mode();
  290.     fort_tab[CTRL('J')] = orig_ret;
  291.     reg_tab[CTRL('G')] = find_index("abort");
  292.     fort_tab[CTRL('G')] = bell_key;
  293.     nl_forward();
  294.     top_level = old_level;
  295. }
  296.      
  297. fort_program() on fort_ext_tab['p']
  298. {
  299.     int i;
  300.      
  301.     PREINDENT();
  302.     bprintf("PROGRAM \n\n");
  303.     fort_indenter();
  304.     stuff("END\n");
  305.     for (i=1; i++<=3; nl_reverse())
  306.         ;
  307. }
  308.      
  309. fort_subroutine() on fort_ext_tab['s']
  310. {
  311.     jmp_buf this_level, *old_level = top_level;
  312.     short orig_ret = fort_tab[CTRL('J')];
  313.     int i;
  314.      
  315.     /* Set up abort trap to unbind keys */
  316.     top_level = &this_level;
  317.     bell_key = fort_tab[CTRL('G')];
  318.     if (setjmp(top_level)) {
  319.         major_mode = strsave("Fortran");
  320.         make_mode();
  321.         say("Aborted.");
  322.         fort_tab[CTRL('J')] = orig_ret;
  323.         reg_tab[CTRL('G')] = find_index("abort");
  324.         fort_tab[CTRL('G')] = bell_key;
  325.         top_level = old_level;
  326.         return;
  327.     }
  328.      
  329.     PREINDENT();
  330.     bprintf("SUBROUTINE ()\n\n");
  331.     fort_indenter();
  332.     stuff("RETURN\n");
  333.     fort_indenter();
  334.     stuff("END\n");
  335.     for (i=1; i++<=3; nl_reverse())
  336.         ;
  337.     point -=3;
  338.      
  339.     /* Input subroutine name in recursive edit mode. */
  340.     fort_tab[CTRL('J')] = find_index("exit-level");
  341.     fort_tab[(' ')] = find_index("exit-level");
  342.     fort_tab[CTRL('G')] = find_index("f-abort");
  343.     reg_tab[CTRL('G')] = find_index("f-abort");
  344.     major_mode = strsave("SUBROUTINE name (<cr> to exit)");
  345.     strcpy(mode, major_mode);
  346.     recursive_edit();
  347.     fort_tab[(' ')] = find_index("normal-character");
  348.     check_abort();
  349.      
  350.     /* Input parameters in recursive edit mode. */
  351.     ++point;
  352.     major_mode = strsave("SUBROUTINE parameters (<cr> to exit)");
  353.     strcpy(mode, major_mode);
  354.     recursive_edit();
  355.     check_abort();
  356.      
  357.     /* Restore keys */
  358.     major_mode = strsave("Fortran");
  359.     make_mode();
  360.     fort_tab[CTRL('J')] = orig_ret;
  361.     reg_tab[CTRL('G')] = find_index("abort");
  362.     fort_tab[CTRL('G')] = bell_key;
  363.     top_level = old_level;
  364.     nl_forward();
  365. }
  366.      
  367.      
  368. fort_character() on fort_ext_tab['a']
  369. {
  370.     PREINDENT();
  371.     stuff("CHARACTER\t\t");
  372. }
  373.      
  374. fort_double() on fort_ext_tab['d']
  375. {
  376.     PREINDENT();
  377.     stuff("DOUBLE PRECISION\t");
  378. }
  379.      
  380. fort_complex() on fort_ext_tab['j']
  381. {
  382.     PREINDENT();
  383.     stuff("COMPLEX\t\t");
  384. }
  385.      
  386. fort_integer() on fort_ext_tab['i']
  387. {
  388.     PREINDENT();
  389.     stuff("INTEGER\t\t");
  390. }
  391.      
  392. fort_logical() on fort_ext_tab['l']
  393. {
  394.     PREINDENT();
  395.     stuff("LOGICAL\t\t");
  396. }
  397.      
  398. fort_real() on fort_ext_tab['r']
  399. {
  400.     PREINDENT();
  401.     stuff("REAL\t\t\t");
  402. }
  403.      
  404.      
  405.      
  406. fort_common() on fort_ext_tab[ALT('c')]
  407. {
  408.     PREINDENT();
  409.     stuff("COMMON /  / ");
  410.     point-=3;
  411. }
  412.      
  413. fort_data() on fort_ext_tab[ALT('d')]
  414. {
  415.     PREINDENT();
  416.     stuff("DATA //");
  417.     point-=2;
  418. }
  419.      
  420.      
  421.      
  422. fort_blockif() on fort_ext_tab[CTRL('B')]
  423. {
  424.     short orig_ret = fort_tab[CTRL('J')];
  425.      
  426.     bell_key = fort_tab[CTRL('G')];
  427.      
  428.     PREINDENT();
  429.     stuff("IF () THEN\n");
  430.     fort_indenter();
  431.     fort_tabify();
  432.     insert('\n');
  433.     fort_indenter();
  434.     stuff("ENDIF\n");
  435.     nl_reverse();
  436.     nl_reverse();
  437.     nl_reverse();
  438.     point -= 6;
  439.      
  440.     /* enter condition in recursive edit mode */
  441.     fort_tab[CTRL('G')] = find_index("f-abort");
  442.     reg_tab[CTRL('G')] = find_index("f-abort");
  443.     fort_tab[CTRL('J')] = find_index("exit-level");
  444.     major_mode = strsave("IF condition (<cr> to exit)");
  445.     strcpy(mode, major_mode);
  446.     recursive_edit();
  447.      
  448.     /* Restore keys */
  449.     major_mode = strsave("Fortran");
  450.     make_mode();
  451.     fort_tab[CTRL('J')] = orig_ret;
  452.     reg_tab[CTRL('G')] = find_index("abort");
  453.     fort_tab[CTRL('G')] = bell_key;
  454.     check_abort();
  455.      
  456.     nl_forward();
  457.     to_end_line();
  458. }
  459.      
  460.      
  461. fort_call() on fort_ext_tab['c']
  462. {
  463.     stuff("CALL ()");
  464.     point-=2;
  465. }
  466.      
  467. fort_continue() on fort_ext_tab[CTRL('C')]
  468. {
  469.     PREINDENT();
  470.     stuff("CONTINUE\n");
  471.     fort_indenter();
  472. }
  473.      
  474. fort_do() on fort_ext_tab[CTRL('D')]
  475. {
  476.     jmp_buf this_level, *old_level = top_level;
  477.     char line_no[20];
  478.     int tag;
  479.     short orig_ret = fort_tab[CTRL('J')];
  480.      
  481.     /* Set up abort trap to unbind keys */
  482.     top_level = &this_level;
  483.     bell_key = fort_tab[CTRL('G')];
  484.     if (setjmp(top_level)) {
  485.         major_mode = strsave("Fortran");
  486.         make_mode();
  487.         say("Aborted.");
  488.         fort_tab[' '] = find_index("maybe-break-line");
  489.         fort_tab[CTRL('J')] = orig_ret;
  490.         reg_tab[CTRL('G')] = find_index("abort");
  491.         fort_tab[CTRL('G')] = bell_key;
  492.         top_level = old_level;
  493.         return;
  494.     }
  495.      
  496.     PREINDENT();
  497.     bprintf("DO  =,\n");
  498.     fort_indenter();
  499.     fort_tabify();
  500.     nl_reverse();
  501.     point -= 3;
  502.      
  503.     /* Input line number in recursive edit mode.
  504.         Space or <cr> exits.    */
  505.     fort_tab[CTRL('J')] = find_index("exit-level");
  506.     fort_tab[' '] = find_index("exit-level");
  507.     fort_tab[CTRL('G')] = find_index("f-abort");
  508.     reg_tab[CTRL('G')] = find_index("f-abort");
  509.     major_mode = strsave("DO CONTINUE line number (<cr> to exit)");
  510.     strcpy(mode, major_mode);
  511.     recursive_edit();
  512.     check_abort();
  513.      
  514.     /* Grab the line number if entered */
  515.     tag = point;
  516.     re_search(-1,"[0123456789]*");
  517.     if (point!=tag)
  518.         grab(point,tag,line_no);
  519.     nl_forward();
  520.     to_end_line();
  521.     insert('\n');
  522.     fort_indenter();
  523.     fort_tabify();
  524.     stuff("continue\n");
  525.     nl_reverse();
  526.     nl_reverse();
  527.     tag = point++;
  528.     bprintf("%5.5s",line_no);
  529.     re_search(1,"[ \t]*");
  530.     say("Continuation line?");
  531.     major_mode = strsave("DO CONTINUE query");
  532.     strcpy(mode, major_mode);
  533.     maybe_refresh();
  534.     getkey();
  535.     if (key == CTRL('G'))
  536.         error("Aborted.");
  537.     delete(point,point+8);
  538.     if ((key == CTRL('H'))||(toupper(key) == 'N')||(key == GREYBACK)) {
  539.         to_end_line();
  540.         delete(tag,point);
  541.     }
  542.     else
  543.         stuff("CONTINUE");
  544.     say("");
  545.      
  546.     /* Input index in recursive edit mode.  <cr> exits */
  547.     search(-1,"=,");
  548.     major_mode = strsave("DO index (<cr> or Space to exit)");
  549.     strcpy(mode, major_mode);
  550.     recursive_edit();
  551.     check_abort();
  552.      
  553.     /* insert range */
  554.     ++point;
  555.     major_mode = strsave("DO start (<cr> or Space to exit)");
  556.     strcpy(mode, major_mode);
  557.     recursive_edit();
  558.     check_abort();
  559.     ++point;
  560.     major_mode = strsave("DO end (<cr> or Space to exit)");
  561.     strcpy(mode, major_mode);
  562.     recursive_edit();
  563.      
  564.     /* Restore keys */
  565.     major_mode = strsave("Fortran");
  566.     make_mode();
  567.     fort_tab[' '] = find_index("maybe-break-line");
  568.     fort_tab[CTRL('J')] = orig_ret;
  569.     reg_tab[CTRL('G')] = find_index("abort");
  570.     fort_tab[CTRL('G')] = bell_key;
  571.     top_level = old_level;
  572.      
  573.     check_abort();
  574.     ++point;
  575.     nl_forward();
  576.     --point;
  577. }
  578.      
  579.      
  580. fort_else() on fort_ext_tab[CTRL('E')]
  581. {
  582.     PREINDENT();
  583.     fort_delete_tab();
  584.     stuff("ELSE\n");
  585.     fort_indenter();
  586.     fort_tabify();
  587. }
  588.      
  589. fort_elseif() on fort_ext_tab['e']
  590. {
  591.     short orig_ret = fort_tab[CTRL('J')];
  592.      
  593.     bell_key = fort_tab[CTRL('G')];
  594.      
  595.     PREINDENT();
  596.     fort_delete_tab();
  597.     stuff("ELSEIF () THEN\n");
  598.     fort_indenter();
  599.     fort_tabify();
  600.     nl_reverse();
  601.     point -= 6;
  602.      
  603.     /* enter condition in recursive edit mode */
  604.     fort_tab[CTRL('J')] = find_index("exit-level");
  605.     fort_tab[CTRL('G')] = find_index("f-abort");
  606.     reg_tab[CTRL('G')] = find_index("f-abort");
  607.     major_mode = strsave("ELSE IF condition (<cr> to exit)");
  608.     strcpy(mode, major_mode);
  609.     recursive_edit();
  610.      
  611.     /* Restore keys */
  612.     major_mode = strsave("Fortran");
  613.     make_mode();
  614.     fort_tab[CTRL('J')] = orig_ret;
  615.     reg_tab[CTRL('G')] = find_index("abort");
  616.     fort_tab[CTRL('G')] = bell_key;
  617.     check_abort();
  618.      
  619.     nl_forward();
  620.     nl_forward();
  621.     --point;
  622. }
  623.      
  624. fort_goto() on fort_ext_tab['g']
  625. {
  626.     PREINDENT();
  627.     stuff("GOTO ");
  628. }
  629.      
  630. fort_if() on fort_ext_tab[CTRL('I')]
  631. {
  632.     short orig_ret = fort_tab[CTRL('J')];
  633.      
  634.     bell_key = fort_tab[CTRL('G')];
  635.      
  636.     PREINDENT();
  637.     stuff("IF () ");
  638.     point -= 2;
  639.      
  640.     /* enter condition in recursive edit mode */
  641.     fort_tab[CTRL('J')] = find_index("exit-level");
  642.     fort_tab[CTRL('G')] = find_index("f-abort");
  643.     reg_tab[CTRL('G')] = find_index("f-abort");
  644.     major_mode = strsave("IF condition (<cr> to exit)");
  645.     strcpy(mode, major_mode);
  646.     recursive_edit();
  647.      
  648.     /* Restore keys */
  649.     major_mode = strsave("Fortran");
  650.     make_mode();
  651.     fort_tab[CTRL('J')] = orig_ret;
  652.     reg_tab[CTRL('G')] = find_index("abort");
  653.     fort_tab[CTRL('G')] = bell_key;
  654.     check_abort();
  655.      
  656.     point +=2;
  657. }
  658.      
  659.      
  660.      
  661. fort_format() on fort_ext_tab[CTRL('f')]
  662. {
  663.     jmp_buf this_level, *old_level = top_level;
  664.     char line_no[20];
  665.     short orig_ret = fort_tab[CTRL('J')];
  666.     int tag;
  667.      
  668.     /* Set up abort trap to unbind keys */
  669.     top_level = &this_level;
  670.     bell_key = fort_tab[CTRL('G')];
  671.     if (setjmp(top_level)) {
  672.         major_mode = strsave("Fortran");
  673.         make_mode();
  674.         say("Aborted.");
  675.         fort_tab[' '] = find_index("maybe-break-line");
  676.         fort_tab[CTRL('J')] = orig_ret;
  677.         reg_tab[CTRL('G')] = find_index("abort");
  678.         fort_tab[CTRL('G')] = bell_key;
  679.         top_level = old_level;
  680.         return;
  681.     }
  682.      
  683.     PREINDENT();
  684.     bprintf("FORMAT ()");
  685.     to_begin_line();
  686.      
  687.     /* Input line number in recursive edit mode.
  688.         Space or <cr> exits.    */
  689.     fort_tab[CTRL('J')] = find_index("exit-level");
  690.     fort_tab[' '] = find_index("exit-level");
  691.     fort_tab[CTRL('G')] = find_index("f-abort");
  692.     reg_tab[CTRL('G')] = find_index("f-abort");
  693.     major_mode = strsave("FORMAT line number");
  694.     make_mode();
  695.      
  696.     recursive_edit();
  697.     check_abort();
  698.      
  699.     /* Grab the line number if entered, and right justify */
  700.     tag = point;
  701.     re_search(-1,"[0123456789]*");
  702.     if (point!=tag) {
  703.         grab(point,tag,line_no);
  704.         move_to_column(0);
  705.         delete(point,tag);
  706.         bprintf("%5.5s",line_no);
  707.     }
  708.      
  709.     /* Restore keys */
  710.     major_mode = strsave("Fortran");
  711.     make_mode();
  712.     fort_tab[' '] = find_index("maybe-break-line");
  713.     fort_tab[CTRL('J')] = orig_ret;
  714.     reg_tab[CTRL('G')] = find_index("abort");
  715.     fort_tab[CTRL('G')] = bell_key;
  716.     top_level = old_level;
  717.      
  718.     search(1,"FORMAT (");
  719. }
  720.      
  721.      
  722. fort_open() on fort_ext_tab[CTRL('o')]
  723. {
  724.     jmp_buf this_level, *old_level = top_level;
  725.     char unit_no[20];
  726.     int tag;
  727.     short orig_ret = fort_tab[CTRL('J')];
  728.      
  729.     /* Set up abort trap to unbind keys */
  730.     top_level = &this_level;
  731.     bell_key = fort_tab[CTRL('G')];
  732.     if (setjmp(top_level)) {
  733.         major_mode = strsave("Fortran");
  734.         make_mode();
  735.         say("Aborted.");
  736.         fort_tab[' '] = find_index("maybe-break-line");
  737.         fort_tab[CTRL('J')] = orig_ret;
  738.         reg_tab[CTRL('G')] = find_index("abort");
  739.         fort_tab[CTRL('G')] = bell_key;
  740.         top_level = old_level;
  741.         return;
  742.     }
  743.      
  744.     PREINDENT();
  745.     bprintf("OPEN (*,FILE='for*.dat',status='new')");
  746.     point -= 31;
  747.     major_mode = strsave("OPEN unit number (<cr> or Space to exit)");
  748.     strcpy(mode, major_mode);
  749.     maybe_refresh();
  750.     getkey();
  751.     check_abort();
  752.     ungot_key = key;
  753.     delete(point,point+1);
  754.      
  755.     /* Input unit number in recursive edit mode.
  756.         Space, or <cr> exits.    */
  757.     fort_tab[CTRL('J')] = find_index("exit-level");
  758.     fort_tab[' '] = find_index("exit-level");
  759.     fort_tab[CTRL('G')] = find_index("f-abort");
  760.     reg_tab[CTRL('G')] = find_index("f-abort");
  761.     recursive_edit();
  762.     fort_tab[' '] = find_index("maybe-break-line");
  763.      
  764.     /* Grab the unit number if entered, and right justify */
  765.     tag = point;
  766.     re_search(-1,"[0123456789]*");
  767.     if (point!=tag) {
  768.         grab(point,tag,unit_no);
  769.     }
  770.     else{
  771.         unit_no[0] = 0;
  772.     }
  773.      
  774.     /* Query standard file name */
  775.     if (search(1,"for*")) {
  776.         delete(point,point-1);
  777.         tag = point-3;
  778.         bprintf("%.4s",unit_no);
  779.         point = tag;
  780.         say("Standard Filename?");
  781.         major_mode = strsave("OPEN filename query");
  782.         strcpy(mode, major_mode);
  783.         maybe_refresh();
  784.         getkey();
  785.         if (key == CTRL('G'))
  786.             error("Aborted.");
  787.         if ((key == CTRL('H'))
  788.             ||(toupper(key) == 'N')||(key == GREYBACK)) {
  789.             if (search(1,"dat")) {
  790.                 delete(tag,point);
  791.                 /* Enter filename in recursive edit */
  792.                 major_mode = strsave(
  793.                     "OPEN file name (<cr> to exit)");
  794.                 strcpy(mode, major_mode);
  795.                 recursive_edit();
  796.             }
  797.         }
  798.         else {
  799.             delete(point,point+3);
  800.             stuff("FOR");
  801.             if (search(1,"dat")) {
  802.                 delete(point-3,point);
  803.                 stuff("DAT");
  804.             }
  805.         }
  806.         say("");
  807.     }
  808.      
  809.     /* Query status */
  810.     if (search(1,"status")) {
  811.         point -= 6;
  812.         say("Status=New?");
  813.         major_mode = strsave("OPEN status query");
  814.         strcpy(mode,major_mode);
  815.         maybe_refresh();
  816.         getkey();
  817.         if (key == CTRL('G'))
  818.             error("Aborted.");
  819.         delete(point,point+12);
  820.         if ((key == CTRL('H'))
  821.             ||(toupper(key) == 'N')||(key == GREYBACK)) {
  822.             delete(point-1,point);
  823.         }
  824.         else
  825.             stuff("STATUS='NEW'");
  826.         say("");
  827.     }
  828.      
  829.     /* Restore keys */
  830.     major_mode = strsave("Fortran");
  831.     make_mode();
  832.     fort_tab[CTRL('J')] = orig_ret;
  833.     reg_tab[CTRL('G')] = find_index("abort");
  834.     fort_tab[CTRL('G')] = bell_key;
  835.     check_abort();
  836.     top_level = old_level;
  837.      
  838.     to_end_line();
  839. }
  840.      
  841.      
  842. fort_read() on fort_ext_tab[CTRL('r')]
  843. {
  844.     PREINDENT();
  845.     stuff("READ (*,*) ");
  846.      
  847.     /* Input unit number */
  848.     point -= 5;
  849.     maybe_refresh();
  850.     getkey();
  851.     if (isdigit(key)) {
  852.         delete(point,point+1);
  853.         while (isdigit(key)) {
  854.             insert(key);
  855.             maybe_refresh();
  856.             getkey();
  857.         }
  858.     }
  859.     else {
  860.         check_abort();
  861.         ++point;
  862.     }
  863.      
  864.     /* Input format line number */
  865.     ++point;
  866.     maybe_refresh();
  867.     getkey();
  868.     if (isdigit(key)) {
  869.         delete(point,point+1);
  870.         while (isdigit(key)) {
  871.             insert(key);
  872.             maybe_refresh();
  873.             getkey();
  874.         }
  875.     }
  876.     else {
  877.         check_abort();
  878.         ++point;
  879.     }
  880.      
  881.     point += 2;
  882. }
  883.      
  884.      
  885. fort_write() on fort_ext_tab[CTRL('w')]
  886. {
  887.     PREINDENT();
  888.     stuff("WRITE (*,*) ");
  889.      
  890.     /* Input unit number */
  891.     point -= 5;
  892.     maybe_refresh();
  893.     getkey();
  894.     if (isdigit(key)) {
  895.         delete(point,point+1);
  896.         while (isdigit(key)) {
  897.             insert(key);
  898.             maybe_refresh();
  899.             getkey();
  900.         }
  901.     }
  902.     else {
  903.         check_abort();
  904.         ++point;
  905.     }
  906.      
  907.     /* Input format line number */
  908.     ++point;
  909.     maybe_refresh();
  910.     getkey();
  911.     if (isdigit(key)) {
  912.         delete(point,point+1);
  913.         while (isdigit(key)) {
  914.             insert(key);
  915.             maybe_refresh();
  916.             getkey();
  917.         }
  918.     }
  919.     else {
  920.         check_abort();
  921.         ++point;
  922.     }
  923.      
  924.     point += 2;
  925. }
  926.      
  927.      
  928. /* Commands to prompt for and complete names of fort- routines */
  929. /* Requires modified COMPLETE.E file */
  930. /*
  931. /char *fsub_match(s, start)
  932. /char *s;
  933. /{
  934. /int i;
  935. /
  936. /for (; i = name_match(s, start); start = 0)
  937. /    switch (name_type(i)) {
  938. /        case NT_COMMAND: case NT_SUBR:
  939. /            return name_name(i);
  940. /    }
  941. /return 0;
  942. /}
  943. /
  944. /get_fsub(res, pr)
  945. /char *res, *pr;
  946. /{
  947. /strcpy(res,"fort-");
  948. /comp_read(res, pr, fsub_match, 0);
  949. /}
  950. /
  951. /get_fsub_index(pr)
  952. /char *pr;
  953. /{
  954. /char fsub[80];
  955. /int name_index;
  956. /
  957. /get_fsub(fsub, pr);
  958. /name_index = find_index(fsub);
  959. /if (name_index && (name_type(name_index) == NT_SUBR ||
  960. /            name_type(name_index) == NT_COMMAND))
  961. /    return name_index;
  962. /error("There's no Fortran command named '%.50s'.",fsub);
  963. /return 0;
  964. /}
  965. /
  966. /command fort_named() on fort_tab[ALT(']')], fort_tab[FALT(2)]
  967. /{
  968. /char msg[40];
  969. /int index;
  970. /
  971. /if (has_arg)
  972. /    sprintf(msg, "%d Fortran Command: ", iter);
  973. /else
  974. /    sprintf(msg, "Fortran Command: ");
  975. /if (index = get_fsub_index(msg))
  976. /    do_command(index);
  977. /}
  978. */
  979.      
  980. when_loading()
  981. {
  982.     int i;
  983.      
  984.     fort_tab[CTRL(']')] = find_index("fort-ext-tab");
  985.     for (i = 'A'; i <= 'Z'; i++) {
  986.         if (fort_ext_tab[ALT(i)] <= 0)
  987.             fort_ext_tab[ALT(i)] = find_index("case-indirect");
  988.         if (fort_ext_tab[i] <= 0)
  989.             fort_ext_tab[i] = find_index("case-indirect");
  990.     }
  991.     fort_ext_tab[CTRL('H')] = find_index("fort-delete-tab");
  992. }
  993. -------
  994. 31-Oct-86 13:17:39-PST,577;000000000001
  995. Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
  996. Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:15:14 PST
  997. Date: Fri 31 Oct 86 13:13:40-PST
  998. From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
  999. Subject: FOR_MENU file
  1000. To: info-ibmpc@B.ISI.EDU
  1001. Message-ID: <12251269559.17.FAT.STOREY@Sierra.Stanford.EDU>
  1002.      
  1003. ^B    block if    d    double prec.    l    logical
  1004. c    call        i    integer        ^O    open
  1005. a    character    ^E    else        p    program
  1006. A-c    common        e    elseif        ^R    read
  1007. j    complex        ^F    format        r    real
  1008. ^C    continue    f    function    s    subroutine
  1009. A-d    data        g    goto        ^W    write
  1010. ^D    do        ^I    if
  1011. -------
  1012. 31-Oct-86 13:17:40-PST,2239;000000000001
  1013. Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
  1014. Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:15:35 PST
  1015. Date: Fri 31 Oct 86 13:14:11-PST
  1016. From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
  1017. Subject: PAS_LOAD.E file
  1018. To: info-ibmpc@B.ISI.EDU
  1019. Message-ID: <12251269653.17.FAT.STOREY@Sierra.Stanford.EDU>
  1020.      
  1021. /************************************************************************
  1022. * "Epsilon", "EEL" and "Lugaru" are trademarks of Lugaru Software, Ltd. *
  1023. *                                    *
  1024. *     Copyright (C) 1985 Lugaru Software Ltd.  All rights reserved.    *
  1025. *                                    *
  1026. * Limited permission is hereby granted to reproduce and modify this    *
  1027. * copyrighted material provided that the resulting code is used only in    *
  1028. * conjunction with Lugaru products and that this notice is retained in    *
  1029. * any such reproduction or modification.                *
  1030. ************************************************************************/
  1031.      
  1032. /*          Developed by James S. Storey                                   */
  1033.      
  1034. #include "\epsilon\eel.h"
  1035.      
  1036. /* This mode auto-loads from files PAS_MODE and PAS_EXT */
  1037. #define PAS_MODE "c:\\epsilon\\modes\\pas_mode"
  1038. #define PAS_EXT "c:\\epsilon\\modes\\pas_ext"
  1039.      
  1040. /* Format buffer for Pascal programs.
  1041.     This command puts the current buffer in the Pascal mode,
  1042.     appropriate for editing programs written in Pascal.
  1043.     Command names are of the form pas-COMMAND.  A series of
  1044.     statement commands automatically insert a template for most
  1045.     Pascal statements.  These statement commands are bound to keys
  1046.     prefixed by the C-] key.
  1047.      
  1048.     By default, the find-file command automatically turns on
  1049.     Pascal mode for files with the extensions .p or .pas. */
  1050.      
  1051. command pas_mode()
  1052. {
  1053.     char *_pas_tab = "pas-tab", *_ind_ptr = "pas-indenter";
  1054.     short *_pas_ptr;
  1055.      
  1056.     if (!find_index("pas-tab")) {
  1057.         sayput("Loading Pascal mode commands. . .");
  1058.         load_commands(PAS_MODE);
  1059.         load_commands(PAS_EXT);
  1060.         say("");
  1061.     }
  1062.     _pas_ptr=index_table(find_index(_pas_tab));
  1063.     mode_keys = _pas_ptr;
  1064.     major_mode = strsave("Pascal");
  1065.     make_mode();
  1066.     (short) indenter = find_index(_ind_ptr);
  1067.     auto_indent = 1;
  1068. }
  1069.      
  1070. /* make this the default mode for .p and .pas files */
  1071. suffix_p()    { pas_mode(); }
  1072. suffix_pas()    { pas_mode(); }
  1073. -------
  1074. 31-Oct-86 13:17:41-PST,5975;000000000001
  1075. Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
  1076. Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:15:55 PST
  1077. Date: Fri 31 Oct 86 13:14:40-PST
  1078. From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
  1079. Subject: PAS_MODE.E file
  1080. To: info-ibmpc@B.ISI.EDU
  1081. Message-ID: <12251269742.17.FAT.STOREY@Sierra.Stanford.EDU>
  1082.      
  1083.      
  1084. /* Written by James S. Storey */
  1085.      
  1086. /* Subroutines and commands for Pascal mode.
  1087.     These commands are read in when Pascal mode is invoked for the
  1088.     first time    */
  1089.      
  1090. #include "\epsilon\eel.h"
  1091.      
  1092. /* define an RE matching Pascal comments or whitespace */
  1093. #define P_LSKIP "((%(%*([^*]|%*[^)])*%*%))|{([^}])*}|[ \t\n])*"
  1094.      
  1095. /* define an RE matching Pascal comments or whitespace, on same line */
  1096. #define P_SKIP "((%(%*([^*\n]|%*[^)\n])*%*%))|{([^}\n])*}|[ \t])*"
  1097.      
  1098. int Matchdelim = 1;    /* 1 for showing matching ')' */
  1099.      
  1100. keytable pas_tab;        /* key table for Pascal mode */
  1101.      
  1102. buffer short bell_key;
  1103.      
  1104. p_abort()
  1105. {
  1106.     pas_tab[BELL] = bell_key;
  1107.     reg_tab[BELL] = find_index("abort");
  1108.     if (recursion_level>0)
  1109.         exit_level();
  1110.     user_abort = 1;
  1111. }
  1112.      
  1113.      
  1114. /* backward-kill-spaces(back) Delete up to BACK spaces preceding point */
  1115.      
  1116. backward_kill_spaces(back)
  1117. int back;
  1118. {
  1119.     int orig = point;
  1120.      
  1121.     re_search(-1,"( )*");
  1122.     if (point <= orig-back) {
  1123.         point = orig;
  1124.         delete(point-back,point);
  1125.     }
  1126.     else {
  1127.         delete(point,orig);
  1128.     }
  1129. }
  1130.      
  1131. /* pas-tabify    Indent by half-tabs.
  1132.     If the point is in the current line's indentation, a half-tab is
  1133.     added to the indentation.  Otherwise, a half-tab is added before
  1134.     the point.
  1135.      
  1136.     When adding half-tabs, if the point is preceded by 1/2 a tab or
  1137.     more spaces, the spaces following the last tab-stop are deleted
  1138.     and a tab is added.  Otherwise, spaces are added up to 1/2 a tab
  1139.     past the last tab stop. */
  1140.      
  1141. #define HALF_TAB tab_size/2
  1142.      
  1143. command pas_tabify() on pas_tab[CTRL('I')]
  1144. {
  1145.     int orig = point, excess, lack;
  1146.      
  1147.     /* skip leading blanks */
  1148.     to_begin_line();
  1149.     if (!re_search(1, "[^ \t]") || point > orig) { /* skip blanks */
  1150.         point = orig;
  1151.         to_indentation();
  1152.     }
  1153.     else                       /* restore point */
  1154.         point = orig;
  1155.      
  1156.     /* Insert half tab */
  1157.     excess = (current_column()%tab_size);
  1158.     lack = HALF_TAB-excess;
  1159.     if (lack > 0) {        /* between tab and half-tab stops */
  1160.         for (; lack-- > 0; insert(' ')) ;
  1161.     }
  1162.     else {            /* between half-tab and tab stops */
  1163.         backward_kill_spaces(excess);
  1164.         insert('\t');
  1165.     }
  1166. }
  1167.      
  1168. /* pas-delete-tab    Delete a half tab preceding the point, hacking full
  1169.     tabs. */
  1170.      
  1171. pas_delete_tab()  /* on pas_ext_tab[CTRL('H')] */
  1172. {
  1173.     int excess, i;
  1174.      
  1175.     excess = (current_column()%tab_size);
  1176.     if (excess == 0) {        /* at a tab stop */
  1177.         if (character(point-1) == '\t') {
  1178.             /* delete previous tab, insert half tab */
  1179.             delete(point-1,point);
  1180.             for( i=1 ; i++ <=HALF_TAB ; insert(' ')) ;
  1181.         }
  1182.         else         /* delete to last non-space or half tab stop */
  1183.             backward_kill_spaces(HALF_TAB);
  1184.     }
  1185.     else  {
  1186.         if (excess <= HALF_TAB)        /* Between tab and half tab */
  1187.             backward_kill_spaces(excess);
  1188.         else                /* Between half tab and tab */
  1189.             backward_kill_spaces(excess-HALF_TAB);
  1190.     }
  1191. }
  1192.      
  1193.      
  1194. /* pas-comment    Insert a pascal comment. */
  1195.      
  1196. command pas_comment() on pas_tab[ALT(';')]
  1197. {
  1198. #define L_COMMENT  "(*"
  1199. #define R_COMMENT  "*)"
  1200.      
  1201.     int com_size;
  1202.     short orig_alt_ret = pas_tab[CTRL(ALT('j'))];
  1203.      
  1204.     bell_key = pas_tab[BELL];
  1205.      
  1206.     com_size = strlen(R_COMMENT);
  1207.     bprintf("%s  %s",L_COMMENT,R_COMMENT);
  1208.     point -= com_size+1;
  1209.     major_mode = strsave("COMMENT body (BACKSPACE to delete)");
  1210.     strcpy(mode, major_mode);
  1211.     maybe_refresh();
  1212.     getkey();
  1213.     if (((key == CTRL('H'))||(key == GREYBACK))||(key == CTRL('G'))) {
  1214.         delete(point-com_size-1,point+com_size+1);
  1215.         major_mode = strsave("Pascal");
  1216.         strcpy(mode, major_mode);
  1217.     }
  1218.     else {
  1219.         ungot_key = key;
  1220.         pas_tab[BELL] = find_index("p-abort");
  1221.         reg_tab[BELL] = find_index("p-abort");
  1222.         pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
  1223.         major_mode = strsave("COMMENT body (A-<cr> to exit)");
  1224.         strcpy(mode, major_mode);
  1225.         recursive_edit();
  1226.         major_mode = strsave("Pascal");
  1227.         strcpy(mode, major_mode);
  1228.         pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  1229.         check_abort();
  1230.         reg_tab[BELL] = find_index("abort");
  1231.         pas_tab[BELL] = bell_key;
  1232.      
  1233.         point += com_size+1;
  1234.     }
  1235. }
  1236.      
  1237. /* pas_indenter    Like the command indent previous, but gives no indentation
  1238.     if the previous line is not indented. */
  1239.      
  1240. command pas_indenter() on pas_tab[ALT('i')]
  1241. {
  1242.     int orig_column, prev_indent;
  1243.     int orig = point;
  1244.      
  1245.     orig_column = current_column();            /* point's column */
  1246.     to_begin_line();
  1247.     if (re_search(-1, "[^ \t\n]")) {  /* find previous non-blank line */
  1248.         to_indentation();
  1249.         prev_indent = current_column();
  1250.     }
  1251.     else
  1252.         prev_indent = 0;
  1253.     point = orig;
  1254.     to_indentation();        /* go to current line's indent */
  1255.      
  1256.     to_column(prev_indent);        /* indentation as previous */
  1257. }
  1258.      
  1259. /* pas-return    Insert a ';' if necessary, then return. */
  1260.      
  1261. pas_return() on pas_tab[CTRL('J')]
  1262. {
  1263.     int orig = point;
  1264.     char prev,comm[3];
  1265.      
  1266.     to_end_line();
  1267.     if (point == orig) {
  1268.         re_search(-1,P_SKIP);
  1269.         if (point>0) {
  1270.             prev = character(point-1);
  1271.             if ( (prev!=';') && (prev!='\n') ) {
  1272.                 grab(point-2,point,comm);
  1273.                 if ( (strncmp(comm,"*)",2)) &&
  1274.                     (prev!='}')) {
  1275.                     insert(';');
  1276.                     ++orig;
  1277.                 }
  1278.             }
  1279.         }
  1280.     }
  1281.     point = orig;
  1282.     insert('\n');
  1283.     pas_indenter();
  1284. }
  1285.      
  1286. /* norm-return    Normal return. */
  1287.      
  1288. norm_return() on pas_tab[CTRL(ALT('j'))],pas_tab[ALT('j')]
  1289. {
  1290.     insert('\n');
  1291.     pas_indenter();
  1292. }
  1293.      
  1294. /* pas-equal    Inserts " := " */
  1295. pas_equal() on pas_tab['=']
  1296. {
  1297.     stuff(" := ");
  1298. }
  1299.      
  1300. normal_equal() on pas_tab[ALT('=')]
  1301. {
  1302.     insert('=');
  1303. }
  1304.      
  1305. when_loading()
  1306. {
  1307.     int i;
  1308.      
  1309.     pas_tab[CTRL('M')] = find_index("newline");
  1310.     pas_tab[CTRL('H')] = find_index("delete-hacking-tabs");
  1311.     for (i = 'A'; i <= 'Z'; i++)
  1312.         if (pas_tab[ALT(i)] <= 0)
  1313.             pas_tab[ALT(i)] = find_index("case-indirect");
  1314.     if (Matchdelim)
  1315.         pas_tab[')'] = pas_tab[']'] =
  1316.             find_index("show-matching-delimiter");
  1317. }
  1318. -------
  1319. 31-Oct-86 13:22:40-PST,28968;000000000001
  1320. Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
  1321. Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:18:05 PST
  1322. Date: Fri 31 Oct 86 13:17:04-PST
  1323. From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
  1324. Subject: PAS_EXT.E file
  1325. To: info-ibmpc@B.ISI.EDU
  1326. Message-ID: <12251270179.17.FAT.STOREY@Sierra.Stanford.EDU>
  1327.      
  1328.      
  1329. /* Written by James S. Storey */
  1330.      
  1331. /* Subroutines and commands in Pascal extension table (C-] table)
  1332.     These routines insert templates for Pascal statements. */
  1333.      
  1334. #include "\epsilon\eel.h"
  1335.      
  1336. #define MENU "c:\\epsilon\\modes\\pas_menu"
  1337.      
  1338. /* define an RE matching Pascal comments or whitespace, on same line */
  1339. #define P_SKIP "((%(%*([^*\n]|%*[^)\n])*%*%))|{([^}\n])*}|[ \t])*"
  1340.      
  1341. keytable pas_tab;    /* table for basic commands */
  1342. keytable pas_ext_tab;    /* table for extended commands */
  1343.      
  1344. buffer short bell_key;
  1345.      
  1346. int end_comments = 1;    /* end_comments=1 causes comments to be added to
  1347.               end statements */
  1348.      
  1349. get_pas_menu()    /* make sure Pascal menu file is ready to go */
  1350. {
  1351.     int exists = exist("-pas_menu");
  1352.     char *oldbuf = bufname;
  1353.      
  1354.      
  1355.     create("-pas_menu");
  1356.     bufname = "-pas_menu";
  1357.     if (!exists) {
  1358.         sayput("Loading Pascal menu file. . .");
  1359.         if (file_read(MENU, 1)) {
  1360.             bufname = oldbuf;
  1361.             delete_buffer("-menu");
  1362.             gripe("Can't find Pascal menu file %s", MENU);
  1363.             say("");
  1364.             return 0;
  1365.         }
  1366.         say("");
  1367.         point = 0;
  1368.         bufname = oldbuf;
  1369.         return 1;
  1370.     }
  1371.     else {
  1372.         if (size()==0) {
  1373.             bufname = oldbuf;
  1374.             delete_buffer("-pas_menu");
  1375.             gripe("No Pascal menu file %s", MENU);
  1376.             return 0;
  1377.         }
  1378.         point = 0;
  1379.         bufname = oldbuf;
  1380.         return 1;
  1381.     }
  1382. }
  1383.      
  1384. pas_menu() on pas_ext_tab[CTRL(']')], pas_ext_tab['?']
  1385. {
  1386.     sayput("C-] ");
  1387.     if (get_pas_menu())
  1388.         view_buffer("-pas_menu");
  1389.     check_abort();
  1390.     do {
  1391.         getkey();
  1392.     } while ((key == CTRL(']'))||(key == '?'));
  1393.     say("");
  1394.     do_again();
  1395. }
  1396.      
  1397. command set_comments()    /* Command to toggle end_comments */
  1398. {
  1399.     end_comments = (has_arg? (iter != 0) : !end_comments);
  1400.     say(end_comments?"End comments":"No end comments");
  1401.     iter = 1;
  1402. }
  1403.      
  1404.      
  1405.      
  1406. pas_begin() on pas_ext_tab[CTRL('B')]
  1407. {
  1408.     stuff("BEGIN\n");
  1409.     pas_tabify();
  1410.     insert('\n');
  1411.     pas_indenter();
  1412.     pas_tabify();
  1413.     stuff("END;");
  1414.     if (end_comments)
  1415.         stuff(" (* BEGIN *)");
  1416.     search(-1,"\n");
  1417. }
  1418.      
  1419. pas_end() on pas_ext_tab['e']
  1420. {
  1421.     stuff("END;\n");
  1422.     pas_indenter();
  1423. }
  1424.      
  1425. pas_program() on pas_ext_tab['p']
  1426. {
  1427.     jmp_buf this_level, *old_level = top_level;
  1428.     int i, tag1, tag2, diff1, diff2;
  1429.     char prog_name[40];
  1430.     short orig_ret = pas_tab[CTRL('J')],
  1431.         orig_alt_ret = pas_tab[CTRL(ALT('j'))];
  1432.      
  1433.     /* Set up abort trap to unbind keys */
  1434.     top_level = &this_level;
  1435.     bell_key = pas_tab[CTRL('G')];
  1436.     if (setjmp(top_level)) {
  1437.         major_mode = strsave("Pascal");
  1438.         make_mode();
  1439.         say("Aborted.");
  1440.         pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  1441.         reg_tab[CTRL('G')] = find_index("abort");
  1442.         pas_tab[CTRL('G')] = bell_key;
  1443.         top_level = old_level;
  1444.         return;
  1445.     }
  1446.      
  1447.     /* Insert PROGRAM, BEGIN/END block, label with program name */
  1448.     bprintf("PROGRAM  ();\n\n");
  1449.     stuff("BEGIN");
  1450.     if (end_comments)
  1451.         stuff(" (*  *)");
  1452.     tag1 = point-3;
  1453.     insert('\n');
  1454.     pas_tabify();
  1455.     insert('\n');
  1456.     stuff("END.");
  1457.     if (end_comments) {
  1458.         stuff("  (*  *)");
  1459.         tag2 = point-3;
  1460.     }
  1461.     insert('\n');
  1462.     for (i=1; i++<=5; nl_reverse())
  1463.         ;
  1464.     point -= 4;
  1465.      
  1466.     /* tag BEGIN and END comments for inserting program name */
  1467.     if (end_comments) {
  1468.         diff1 = tag1-point;
  1469.         diff2 = tag2-point;
  1470.     }
  1471.      
  1472.     /* Input program name in recursive edit mode.
  1473.         <cr>, A-<cr> and space exit from recursion    */
  1474.     pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
  1475.     pas_tab[CTRL('J')] = find_index("exit-level");
  1476.     pas_tab[CTRL('G')] = find_index("p-abort");
  1477.     reg_tab[CTRL('G')] = find_index("p-abort");
  1478.     pas_tab[' '] = find_index("exit-level");
  1479.     major_mode = strsave("PROGRAM name (<cr> to exit)");
  1480.     strcpy(mode, major_mode);
  1481.     recursive_edit();
  1482.     pas_tab[' '] = find_index("normal-character");
  1483.     pas_tab[CTRL('J')] = orig_ret;
  1484.     check_abort();
  1485.      
  1486.     /* Grab the program name and insert it in BEGIN and END comments */
  1487.     if (end_comments) {
  1488.         tag1 = point;
  1489.         backward_word();
  1490.         grab(point,tag1,prog_name);
  1491.         point = tag1+diff2;
  1492.         stuff(prog_name);
  1493.         point = tag1+diff1;
  1494.         stuff(prog_name);
  1495.         point = tag1+2;
  1496.     }
  1497.      
  1498.     /* Input parameters in recursive edit mode.  A-<cr> exits */
  1499.     major_mode = strsave("PROGRAM parameters (A-<cr> to exit)");
  1500.     strcpy(mode, major_mode);
  1501.     recursive_edit();
  1502.     check_abort();
  1503.      
  1504.     /* Set point to beginning of next block, and tag location */
  1505.     nl_forward();
  1506.     nl_forward();
  1507.     tag1 = point;
  1508.      
  1509.     /* Insert CONST declaration block, and delete if C-H is input */
  1510.     insert('\n');
  1511.     --point;
  1512.     stuff("CONST\n");
  1513.     pas_tabify();
  1514.     stuff(";\n");
  1515.     point -= 2;
  1516.     major_mode = strsave("PROGRAM CONST block (BACKSPACE to delete)");
  1517.     strcpy(mode, major_mode);
  1518.     maybe_refresh();
  1519.     getkey();
  1520.     if (key == CTRL('G'))
  1521.         error("Aborted.");
  1522.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  1523.         delete(tag1,point+3);
  1524.     }
  1525.     else {
  1526.         ungot_key = key;
  1527.         delete(point,point+1);
  1528.         major_mode = strsave("PROGRAM CONST block (A-<cr> to exit)");
  1529.         strcpy(mode, major_mode);
  1530.         recursive_edit();
  1531.         check_abort();
  1532.         nl_forward();
  1533.         nl_forward();
  1534.         tag1 = point;
  1535.     }
  1536.      
  1537.     /* Insert TYPE declaration block, and delete if C-H is input */
  1538.     insert('\n');
  1539.     --point;
  1540.     stuff("TYPE\n");
  1541.     pas_tabify();
  1542.     stuff(";\n");
  1543.     point -= 2;
  1544.     major_mode = strsave("PROGRAM TYPE block (BACKSPACE to delete)");
  1545.     strcpy(mode, major_mode);
  1546.     maybe_refresh();
  1547.     getkey();
  1548.     if (key == CTRL('G'))
  1549.         error("Aborted.");
  1550.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  1551.         delete(tag1,point+3);
  1552.     }
  1553.     else {
  1554.         ungot_key = key;
  1555.         delete(point,point+1);
  1556.         major_mode = strsave("PROGRAM TYPE block (A-<cr> to exit)");
  1557.         strcpy(mode, major_mode);
  1558.         recursive_edit();
  1559.         check_abort();
  1560.         nl_forward();
  1561.         nl_forward();
  1562.         tag1 = point;
  1563.     }
  1564.      
  1565.     /* Insert VAR declaration block, and delete if C-H is input */
  1566.     insert('\n');
  1567.     --point;
  1568.     stuff("VAR\n");
  1569.     pas_tabify();
  1570.     stuff(";\n");
  1571.     point -= 2;
  1572.     major_mode = strsave("PROGRAM VAR block (BACKSPACE to delete)");
  1573.     strcpy(mode, major_mode);
  1574.     maybe_refresh();
  1575.     getkey();
  1576.     if (key == CTRL('G'))
  1577.         error("Aborted.");
  1578.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  1579.         delete(tag1,point+3);
  1580.     }
  1581.     else {
  1582.         ungot_key = key;
  1583.         delete(point,point+1);
  1584.         major_mode = strsave("PROGRAM VAR block (A-<cr> to exit)");
  1585.         strcpy(mode, major_mode);
  1586.         recursive_edit();
  1587.         check_abort();
  1588.         nl_forward();
  1589.         nl_forward();
  1590.         tag1 = point;
  1591.     }
  1592.      
  1593.     /* Restore keys */
  1594.     major_mode = strsave("Pascal");
  1595.     make_mode();
  1596.     pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  1597.     reg_tab[CTRL('G')] = find_index("abort");
  1598.     pas_tab[CTRL('G')] = bell_key;
  1599.     top_level = old_level;
  1600.      
  1601.     /* Move point to beginning of program body */
  1602.     nl_forward();
  1603.     to_end_line();
  1604. }
  1605.      
  1606. pas_var_param()
  1607. {
  1608.     stuff("VAR ");
  1609. }
  1610.      
  1611. pas_procedure() on pas_ext_tab[CTRL('P')]
  1612. {
  1613.     jmp_buf this_level, *old_level = top_level;
  1614.     int i, tag1, tag2, diff1, diff2, left = current_column();
  1615.     char proc_name[40];
  1616.     short orig_ret = pas_tab[CTRL('J')],
  1617.         orig_alt_ret = pas_tab[CTRL(ALT('j'))];
  1618.      
  1619.     /* Set up abort trap to unbind keys */
  1620.     top_level = &this_level;
  1621.     bell_key = pas_tab[CTRL('G')];
  1622.     if (setjmp(top_level)) {
  1623.         major_mode = strsave("Pascal");
  1624.         make_mode();
  1625.         say("Aborted.");
  1626.         pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  1627.         reg_tab[CTRL('G')] = find_index("abort");
  1628.         pas_tab[CTRL('G')] = bell_key;
  1629.         top_level = old_level;
  1630.         return;
  1631.     }
  1632.      
  1633.     /* Insert PROCEDURE, BEGIN/END block, label with procedure name */
  1634.     bprintf("PROCEDURE  ();\n\n");
  1635.     to_column(left);
  1636.     stuff("BEGIN");
  1637.     if (end_comments)
  1638.         stuff(" (*  *)");
  1639.     tag1 = point-3;
  1640.     insert('\n');
  1641.     to_column(left);
  1642.     pas_tabify();
  1643.     insert('\n');
  1644.     to_column(left);
  1645.     stuff("END;");
  1646.     if (end_comments) {
  1647.         stuff("  (*  *)");
  1648.         tag2 = point-3;
  1649.     }
  1650.     insert('\n');
  1651.     for (i=1; i++<=5; nl_reverse())
  1652.         ;
  1653.     point -= 4;
  1654.      
  1655.     /* tag BEGIN and END comments for inserting procedure name */
  1656.     if (end_comments) {
  1657.         diff1 = tag1-point;
  1658.         diff2 = tag2-point;
  1659.     }
  1660.      
  1661.     /* Input procedure name in recursive edit mode.
  1662.         <cr>, A-<cr> and space exit from recursion    */
  1663.     pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
  1664.     pas_tab[CTRL('J')] = find_index("exit-level");
  1665.     pas_tab[' '] = find_index("exit-level");
  1666.     pas_tab[CTRL('G')] = find_index("p-abort");
  1667.     reg_tab[CTRL('G')] = find_index("p-abort");
  1668.     major_mode = strsave("PROCEDURE name (<cr> to exit)");
  1669.     strcpy(mode, major_mode);
  1670.     recursive_edit();
  1671.     pas_tab[' '] = find_index("normal-character");
  1672.     pas_tab[CTRL('J')] = orig_ret;
  1673.     check_abort();
  1674.      
  1675.     /* Grab the procedure name and insert it in BEGIN and END comments */
  1676.     tag1 = point;
  1677.     if (end_comments) {
  1678.         backward_word();
  1679.         grab(point,tag1,proc_name);
  1680.         point = tag1+diff2;
  1681.         stuff(proc_name);
  1682.         point = tag1+diff1;
  1683.         stuff(proc_name);
  1684.     }
  1685.     point = tag1+2;
  1686.      
  1687.      
  1688.     /* Input parameters in recursive edit mode.  A-<cr> exits,
  1689.         ^V inserts the string "VAR "        */
  1690.     pas_tab[CTRL('V')] = (short) pas_var_param;
  1691.     major_mode = strsave("PROCEDURE parameters (A-<cr> to exit)");
  1692.     strcpy(mode, major_mode);
  1693.     recursive_edit();
  1694.     pas_tab[CTRL('V')] = find_index("next-page");
  1695.     check_abort();
  1696.      
  1697.      
  1698.     /* Set point to beginning of next block, and tag location */
  1699.     nl_forward();
  1700.     nl_forward();
  1701.     tag1 = point;
  1702.      
  1703.     /* Insert TYPE declaration block, and delete if C-H is input */
  1704.     insert('\n');
  1705.     --point;
  1706.     to_column(left);
  1707.     stuff("TYPE\n");
  1708.     to_column(left);
  1709.     pas_tabify();
  1710.     stuff(";\n");
  1711.     point -= 2;
  1712.     major_mode = strsave("PROCEDURE TYPE block (BACKSPACE to delete)");
  1713.     strcpy(mode, major_mode);
  1714.     maybe_refresh();
  1715.     getkey();
  1716.     if (key == CTRL('G'))
  1717.         error("Aborted.");
  1718.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  1719.         delete(tag1,point+3);
  1720.     }
  1721.     else {
  1722.         ungot_key = key;
  1723.         delete(point,point+1);
  1724.         major_mode = strsave("PROCEDURE TYPE block (A-<cr> to exit)");
  1725.         strcpy(mode, major_mode);
  1726.         recursive_edit();
  1727.         check_abort();
  1728.         nl_forward();
  1729.         nl_forward();
  1730.         tag1 = point;
  1731.     }
  1732.      
  1733.     /* Insert VAR declaration block, and delete if C-H is input */
  1734.     insert('\n');
  1735.     --point;
  1736.     to_column(left);
  1737.     stuff("VAR\n");
  1738.     to_column(left);
  1739.     pas_tabify();
  1740.     stuff(";\n");
  1741.     point -= 2;
  1742.     major_mode = strsave("PROCEDURE VAR block (BACKSPACE to delete)");
  1743.     strcpy(mode, major_mode);
  1744.     maybe_refresh();
  1745.     getkey();
  1746.     if (key == CTRL('G'))
  1747.         error("Aborted.");
  1748.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  1749.         delete(tag1,point+3);
  1750.     }
  1751.     else {
  1752.         ungot_key = key;
  1753.         delete(point,point+1);
  1754.         major_mode = strsave("PROCEDURE VAR block (A-<cr> to exit)");
  1755.         strcpy(mode, major_mode);
  1756.         recursive_edit();
  1757.         check_abort();
  1758.         nl_forward();
  1759.         nl_forward();
  1760.         tag1 = point;
  1761.     }
  1762.      
  1763.     /* Restore keys */
  1764.     major_mode = strsave("Pascal");
  1765.     make_mode();
  1766.     reg_tab[CTRL('G')] = find_index("abort");
  1767.     pas_tab[CTRL('G')] = bell_key;
  1768.     pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  1769.     top_level = old_level;
  1770.      
  1771.     /* Move point to beginning of procedure body */
  1772.     nl_forward();
  1773.     to_end_line();
  1774. }
  1775.      
  1776. pas_function() on pas_ext_tab['f']
  1777. {
  1778.     jmp_buf this_level, *old_level = top_level;
  1779.     int i, tag1, tag2, diff1, diff2, left = current_column();
  1780.     char func_name[40];
  1781.     short orig_ret = pas_tab[CTRL('J')],
  1782.         orig_alt_ret = pas_tab[CTRL(ALT('j'))];
  1783.      
  1784.     /* Set up abort trap to unbind keys */
  1785.     top_level = &this_level;
  1786.     bell_key = pas_tab[CTRL('G')];
  1787.     if (setjmp(top_level)) {
  1788.         major_mode = strsave("Pascal");
  1789.         make_mode();
  1790.         say("Aborted.");
  1791.         pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  1792.         reg_tab[CTRL('G')] = find_index("abort");
  1793.         pas_tab[CTRL('G')] = bell_key;
  1794.         top_level = old_level;
  1795.         return;
  1796.     }
  1797.      
  1798.      
  1799.     /* Insert FUNCTION, BEGIN/END block, label with function name */
  1800.     bprintf("FUNCTION  (): ;\n\n");
  1801.     to_column(left);
  1802.     stuff("BEGIN");
  1803.     if (end_comments)
  1804.         stuff(" (*  *)");
  1805.     tag1 = point-3;
  1806.     insert('\n');
  1807.     to_column(left);
  1808.     pas_tabify();
  1809.     insert('\n');
  1810.     to_column(left);
  1811.     stuff("END;");
  1812.     if (end_comments) {
  1813.         stuff("  (*  *)");
  1814.         tag2 = point-3;
  1815.     }
  1816.     insert('\n');
  1817.     for (i=1; i++<=5; nl_reverse())
  1818.         ;
  1819.     point -= 6;
  1820.      
  1821.     /* tag BEGIN and END comments for inserting function name */
  1822.     if (end_comments) {
  1823.         diff1 = tag1-point;
  1824.         diff2 = tag2-point;
  1825.     }
  1826.      
  1827.     /* Input function name in recursive edit mode.
  1828.         <cr>, A-<cr> and space exit from recursion    */
  1829.     pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
  1830.     pas_tab[CTRL('J')] = find_index("exit-level");
  1831.     pas_tab[' '] = find_index("exit-level");
  1832.     pas_tab[CTRL('G')] = find_index("p-abort");
  1833.     reg_tab[CTRL('G')] = find_index("p-abort");
  1834.     major_mode = strsave("FUNCTION name (<cr> to exit)");
  1835.     strcpy(mode, major_mode);
  1836.     recursive_edit();
  1837.     pas_tab[' '] = find_index("normal-character");
  1838.     pas_tab[CTRL('J')] = orig_ret;
  1839.     check_abort();
  1840.      
  1841.     /* Grab the function name and insert it in BEGIN and END comments */
  1842.     tag1 = point;
  1843.     if (end_comments) {
  1844.         backward_word();
  1845.         grab(point,tag1,func_name);
  1846.         point = tag1+diff2;
  1847.         stuff(func_name);
  1848.         point = tag1+diff1;
  1849.         stuff(func_name);
  1850.     }
  1851.     point = tag1+2;
  1852.      
  1853.     /* Input parameters in recursive edit mode.  A-<cr> exits,
  1854.         ^V inserts the string "VAR "        */
  1855.     pas_tab[CTRL('V')] = (short) pas_var_param;
  1856.     major_mode = strsave("FUNCTION parameters (A-<cr> to exit)");
  1857.     strcpy(mode, major_mode);
  1858.     recursive_edit();
  1859.     pas_tab[CTRL('V')] = find_index("next-page");
  1860.     check_abort();
  1861.      
  1862.     /* Input function type in recursive edit mode.
  1863.         <cr> or A-<cr> exits. */
  1864.     search(1,":");
  1865.     ++point;
  1866.     pas_tab[CTRL('J')] = find_index("exit-level");
  1867.     major_mode = strsave("FUNCTION type (<cr> to exit)");
  1868.     strcpy(mode, major_mode);
  1869.     recursive_edit();
  1870.     pas_tab[CTRL('J')] = orig_ret;
  1871.     check_abort();
  1872.      
  1873.     /* Set point to beginning of next block, and tag location */
  1874.     nl_forward();
  1875.     nl_forward();
  1876.     tag1 = point;
  1877.      
  1878.     /* Insert TYPE declaration block, and delete if C-H is input */
  1879.     insert('\n');
  1880.     --point;
  1881.     to_column(left);
  1882.     stuff("TYPE\n");
  1883.     to_column(left);
  1884.     pas_tabify();
  1885.     stuff(";\n");
  1886.     point -= 2;
  1887.     major_mode = strsave("FUNCTION TYPE block (BACKSPACE to delete)");
  1888.     strcpy(mode, major_mode);
  1889.     maybe_refresh();
  1890.     getkey();
  1891.     if (key == CTRL('G'))
  1892.         error("Aborted.");
  1893.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  1894.         delete(tag1,point+3);
  1895.     }
  1896.     else {
  1897.         ungot_key = key;
  1898.         delete(point,point+1);
  1899.         major_mode = strsave("FUNCTION TYPE block (A-<cr> to exit)");
  1900.         strcpy(mode, major_mode);
  1901.         recursive_edit();
  1902.         check_abort();
  1903.         nl_forward();
  1904.         nl_forward();
  1905.         tag1 = point;
  1906.     }
  1907.      
  1908.     /* Insert VAR declaration block, and delete if C-H is input */
  1909.     insert('\n');
  1910.     --point;
  1911.     to_column(left);
  1912.     stuff("VAR\n");
  1913.     to_column(left);
  1914.     pas_tabify();
  1915.     stuff(";\n");
  1916.     point -= 2;
  1917.     major_mode = strsave("FUNCTION VAR block (BACKSPACE to delete)");
  1918.     strcpy(mode, major_mode);
  1919.     maybe_refresh();
  1920.     getkey();
  1921.     if (key == CTRL('G'))
  1922.         error("Aborted.");
  1923.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  1924.         delete(tag1,point+3);
  1925.     }
  1926.     else {
  1927.         ungot_key = key;
  1928.         delete(point,point+1);
  1929.         major_mode = strsave("FUNCTION VAR block (A-<cr> to exit)");
  1930.         strcpy(mode, major_mode);
  1931.         recursive_edit();
  1932.         check_abort();
  1933.         nl_forward();
  1934.         nl_forward();
  1935.         tag1 = point;
  1936.     }
  1937.      
  1938.     /* Restore keys */
  1939.     major_mode = strsave("Pascal");
  1940.     make_mode();
  1941.     reg_tab[CTRL('G')] = find_index("abort");
  1942.     pas_tab[CTRL('G')] = bell_key;
  1943.     pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  1944.     top_level = old_level;
  1945.      
  1946.     /* Move point to beginning of function body */
  1947.     nl_forward();
  1948.     to_end_line();
  1949. }
  1950.      
  1951. pas_var() on pas_ext_tab[CTRL('V')]
  1952. {
  1953.     stuff("VAR\n");
  1954.     pas_indenter();
  1955.     pas_tabify();
  1956. }
  1957.      
  1958. pas_type() on pas_ext_tab[CTRL('T')]
  1959. {
  1960.     stuff("TYPE\n");
  1961.     pas_indenter();
  1962.     pas_tabify();
  1963. }
  1964.      
  1965. pas_record() on pas_ext_tab['r']
  1966. {
  1967.     int left ,exit;
  1968.      
  1969.     /* Insert RECORD */
  1970.     stuff("RECORD\n");
  1971.     point -= 7;
  1972.      
  1973.     /* Check for new indentation */
  1974.     exit = 0;
  1975.      say("Set indentation (TAB or BACKSPACE)");
  1976.     do {
  1977.         refresh();
  1978.         getkey();
  1979.         switch (key) {
  1980.             case CTRL('H') : ;
  1981.             case GREYBACK  : {
  1982.                 pas_delete_tab();
  1983.                 break;
  1984.             }
  1985.             case CTRL('I') : ;
  1986.             case GREYTAB   : {
  1987.                 pas_tabify();
  1988.                 break;
  1989.             }
  1990.             default : exit = 1;
  1991.         }
  1992.     } while (!exit);
  1993.     say("");
  1994.     check_abort();
  1995.     left = current_column();
  1996.      
  1997.     /* Insert END */
  1998.     nl_forward();
  1999.     to_column(left);
  2000.     pas_tabify();
  2001.     insert('\n');
  2002.     to_column(left);
  2003.     stuff("END;");
  2004.     if (end_comments)
  2005.         stuff(" (* RECORD *)");
  2006.     nl_reverse();
  2007.     insert(';');
  2008.     --point;
  2009.     maybe_refresh();
  2010.     getkey();
  2011.     check_abort();
  2012.     ungot_key = key;
  2013.     delete(point,point+1);
  2014. }
  2015.      
  2016.      
  2017. pas_while() on pas_ext_tab[CTRL('W')]
  2018. {
  2019.     int tag1,tag2;
  2020.     short orig_ret = pas_tab[CTRL('J')],
  2021.         orig_eq = pas_tab['='],
  2022.         orig_alt_ret = pas_tab[CTRL(ALT('j'))];
  2023.      
  2024.      
  2025.     bell_key = pas_tab[CTRL('G')];
  2026.      
  2027.     /* Insert WHILE DO */
  2028.     stuff("WHILE  DO\n");
  2029.     point -= 4;
  2030.      
  2031.     /* Input condition in recursive edit mode.  A-<cr> or <cr> exits */
  2032.     pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
  2033.     pas_tab['='] = find_index("normal-character");
  2034.     pas_tab[CTRL('J')] = find_index("exit-level");
  2035.     pas_tab[CTRL('G')] = find_index("p-abort");
  2036.     reg_tab[CTRL('G')] = find_index("p-abort");
  2037.     major_mode = strsave("WHILE condition (<cr> to exit)");
  2038.     strcpy(mode, major_mode);
  2039.     recursive_edit();
  2040.     major_mode = strsave("Pascal");
  2041.     make_mode();
  2042.     pas_tab[CTRL('J')] = orig_ret;
  2043.     pas_tab['='] = orig_eq;
  2044.     pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  2045.     reg_tab[CTRL('G')] = find_index("abort");
  2046.     pas_tab[CTRL('G')] = bell_key;
  2047.     check_abort();
  2048.      
  2049.     /* Insert BEGIN/END pair, delete if CTRL('H') is entered */
  2050.     to_end_line();
  2051.     tag1 = point;
  2052.     stuff(" BEGIN");
  2053.     nl_forward();
  2054.     pas_indenter();
  2055.     pas_tabify();
  2056.     insert('\n');
  2057.     pas_indenter();
  2058.     pas_tabify();
  2059.     stuff("END;");
  2060.     if (end_comments)
  2061.         stuff(" (* WHILE *)");
  2062.     tag2 = point;
  2063.     nl_reverse();
  2064.     insert(';');
  2065.     --point;
  2066.     maybe_refresh();
  2067.     getkey();
  2068.     if (key == CTRL('G'))
  2069.         error("Aborted.");
  2070.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  2071.         delete(point,tag2+1);
  2072.         delete(tag1,tag1+6);
  2073.     }
  2074.     else {
  2075.         ungot_key = key;
  2076.         delete(point,point+1);
  2077.     }
  2078. }
  2079.      
  2080. pas_for() on pas_ext_tab[CTRL('F')]
  2081. {
  2082.     jmp_buf this_level, *old_level = top_level;
  2083.     int tag1,tag2;
  2084.     short orig_ret = pas_tab[CTRL('J')],
  2085.         orig_alt_ret = pas_tab[CTRL(ALT('j'))];
  2086.      
  2087.     /* Set up abort trap to unbind keys */
  2088.     top_level = &this_level;
  2089.     bell_key = pas_tab[CTRL('G')];
  2090.     if (setjmp(top_level)) {
  2091.         major_mode = strsave("Pascal");
  2092.         make_mode();
  2093.         say("Aborted.");
  2094.         pas_tab[CTRL('J')] = orig_ret;
  2095.         pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  2096.         reg_tab[CTRL('G')] = find_index("abort");
  2097.         pas_tab[CTRL('G')] = bell_key;
  2098.         top_level = old_level;
  2099.         return;
  2100.     }
  2101.      
  2102.     /* Insert FOR TO DO */
  2103.     stuff("FOR  :=  TO  DO\n");
  2104.     point -= 12;
  2105.      
  2106.     /* Input index in recursive edit mode.  A-<cr> or <cr> exits */
  2107.     pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
  2108.     pas_tab[CTRL('J')] = find_index("exit-level");
  2109.     pas_tab[CTRL('G')] = find_index("p-abort");
  2110.     reg_tab[CTRL('G')] = find_index("p-abort");
  2111.     major_mode = strsave("FOR index (<cr> to exit)");
  2112.     strcpy(mode, major_mode);
  2113.     recursive_edit();
  2114.     check_abort();
  2115.      
  2116.     /* find ":=" on this line */
  2117.     to_begin_line();
  2118.     search(1,":=");
  2119.      
  2120.     /* Input start in recursive edit mode.  A-<cr> or <cr> exits */
  2121.     ++point;
  2122.     major_mode = strsave("FOR start (<cr> to exit)");
  2123.     strcpy(mode, major_mode);
  2124.     recursive_edit();
  2125.     check_abort();
  2126.      
  2127.     /* Change TO to DOWNTO on 'd' or 'D' */
  2128.     re_search(1,"( )*");
  2129.     stuff("down");
  2130.     point -= 4;
  2131.     major_mode = strsave("FOR downTO (d for DOWNTO)");
  2132.     strcpy(mode, major_mode);
  2133.     maybe_refresh();
  2134.     delete(point,point+4);
  2135.     getkey();
  2136.     if (key == CTRL('G'))
  2137.         error("Aborted.");
  2138.     if (toupper(key) == 'D')
  2139.         stuff("DOWN");
  2140.      
  2141.     /* Input end in recursive edit mode.  A-<cr> or <cr> exits */
  2142.     point += 3;
  2143.     major_mode = strsave("FOR end (<cr> to exit)");
  2144.     strcpy(mode, major_mode);
  2145.     recursive_edit();
  2146.     pas_tab[CTRL('J')] = orig_ret;
  2147.     pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  2148.     reg_tab[CTRL('G')] = find_index("abort");
  2149.     pas_tab[CTRL('G')] = bell_key;
  2150.     top_level = old_level;
  2151.     check_abort();
  2152.      
  2153.     /* Insert BEGIN/END pair, delete if CTRL('H') is entered */
  2154.     to_end_line();
  2155.     tag1 = point;
  2156.     stuff(" BEGIN");
  2157.     nl_forward();
  2158.     pas_indenter();
  2159.     pas_tabify();
  2160.     insert('\n');
  2161.     pas_indenter();
  2162.     pas_tabify();
  2163.     stuff("END;");
  2164.     if (end_comments)
  2165.         stuff(" (* FOR *)");
  2166.     tag2 = point;
  2167.     nl_reverse();
  2168.     insert(';');
  2169.     --point;
  2170.     major_mode = strsave("FOR body (BACKSPACE to delete)");
  2171.     strcpy(mode, major_mode);
  2172.     maybe_refresh();
  2173.     getkey();
  2174.     if (key == CTRL('G'))
  2175.         error("Aborted.");
  2176.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  2177.         delete(point,tag2+1);
  2178.         delete(tag1,tag1+6);
  2179.     }
  2180.     else {
  2181.         ungot_key = key;
  2182.         delete(point,point+1);
  2183.     }
  2184.     major_mode = strsave("Pascal");
  2185.     make_mode();
  2186. }
  2187.      
  2188. pas_with() on pas_ext_tab['w']
  2189. {
  2190.     int tag1,tag2;
  2191.     short orig_ret = pas_tab[CTRL('J')],
  2192.         orig_eq = pas_tab['='],
  2193.         orig_alt_ret = pas_tab[CTRL(ALT('j'))];
  2194.      
  2195.     bell_key = pas_tab[CTRL('G')];
  2196.      
  2197.     /* Insert WITH DO */
  2198.     stuff("WITH  DO\n");
  2199.     point -= 4;
  2200.      
  2201.     /* Input condition in recursive edit mode.  A-<cr> or <cr> exits */
  2202.     pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
  2203.     pas_tab['='] = find_index("normal-character");
  2204.     pas_tab[CTRL('J')] = find_index("exit-level");
  2205.     pas_tab[CTRL('G')] = find_index("p-abort");
  2206.     reg_tab[CTRL('G')] = find_index("p-abort");
  2207.     major_mode = strsave("WHILE condition (<cr> to exit)");
  2208.     strcpy(mode, major_mode);
  2209.     recursive_edit();
  2210.     major_mode = strsave("Pascal");
  2211.     make_mode();
  2212.     pas_tab[CTRL('J')] = orig_ret;
  2213.     pas_tab['='] = orig_eq;
  2214.     pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  2215.     reg_tab[CTRL('G')] = find_index("abort");
  2216.     pas_tab[CTRL('G')] = bell_key;
  2217.     check_abort();
  2218.      
  2219.     /* Insert BEGIN/END pair, delete if CTRL('H') is entered */
  2220.     to_end_line();
  2221.     tag1 = point;
  2222.     stuff(" BEGIN");
  2223.     nl_forward();
  2224.     pas_indenter();
  2225.     pas_tabify();
  2226.     insert('\n');
  2227.     pas_indenter();
  2228.     pas_tabify();
  2229.     stuff("END;");
  2230.     if (end_comments)
  2231.         stuff(" (* WITH *)");
  2232.     tag2 = point;
  2233.     nl_reverse();
  2234.     insert(';');
  2235.     --point;
  2236.     maybe_refresh();
  2237.     getkey();
  2238.     if (key == CTRL('G'))
  2239.         error("Aborted.");
  2240.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  2241.         delete(point,tag2+1);
  2242.         delete(tag1,tag1+6);
  2243.     }
  2244.     else {
  2245.         ungot_key = key;
  2246.         delete(point,point+1);
  2247.     }
  2248. }
  2249.      
  2250. pas_if() on pas_ext_tab[CTRL('I')]
  2251. {
  2252.     int tag1,tag2;
  2253.     short orig_ret = pas_tab[CTRL('J')],
  2254.         orig_eq = pas_tab['='],
  2255.         orig_alt_ret = pas_tab[CTRL(ALT('j'))];
  2256.      
  2257.     bell_key = pas_tab[CTRL('G')];
  2258.      
  2259.     /* Insert IF THEN */
  2260.     stuff("IF  THEN\n");
  2261.     point -= 6;
  2262.      
  2263.     /* Input condition in recursive edit mode.  A-<cr> or <cr> exits */
  2264.     pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
  2265.     pas_tab['='] = find_index("normal-character");
  2266.     pas_tab[CTRL('J')] = find_index("exit-level");
  2267.     pas_tab[CTRL('G')] = find_index("p-abort");
  2268.     reg_tab[CTRL('G')] = find_index("p-abort");
  2269.     major_mode = strsave("IF condition (<cr> to exit)");
  2270.     strcpy(mode, major_mode);
  2271.     recursive_edit();
  2272.     major_mode = strsave("Pascal");
  2273.     make_mode();
  2274.     pas_tab[CTRL('J')] = orig_ret;
  2275.     pas_tab['='] = orig_eq;
  2276.     pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  2277.     reg_tab[CTRL('G')] = find_index("abort");
  2278.     pas_tab[CTRL('G')] = bell_key;
  2279.     check_abort();
  2280.      
  2281.     /* Insert BEGIN/END pair, delete if CTRL('H') is entered */
  2282.     to_end_line();
  2283.     tag1 = point;
  2284.     stuff(" BEGIN");
  2285.     nl_forward();
  2286.     pas_indenter();
  2287.     pas_tabify();
  2288.     insert('\n');
  2289.     pas_indenter();
  2290.     pas_tabify();
  2291.     stuff("END;");
  2292.     if (end_comments)
  2293.         stuff(" (* THEN *)");
  2294.     tag2 = point;
  2295.     nl_reverse();
  2296.     insert(';');
  2297.     --point;
  2298.     maybe_refresh();
  2299.     getkey();
  2300.     if (key == CTRL('G'))
  2301.         error("Aborted.");
  2302.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  2303.         delete(point,tag2+1);
  2304.         delete(tag1,tag1+6);
  2305.     }
  2306.     else {
  2307.         ungot_key = key;
  2308.         delete(point,point+1);
  2309.     }
  2310. }
  2311.      
  2312. pas_else() on pas_ext_tab[CTRL('E')]
  2313. {
  2314.     int tag1,tag2;
  2315.     short exit;
  2316.      
  2317.     /* delete half-tab */
  2318.     pas_delete_tab();
  2319.      
  2320.     /* Insert ELSE */
  2321.     stuff("ELSE\n");
  2322.      
  2323.     /* Delete ; on previous line */
  2324.     --point;
  2325.     nl_reverse();
  2326.     re_search(-1,P_SKIP);
  2327.     if (character(point-1) == ';')
  2328.         delete(point-1,point);
  2329.     nl_forward();
  2330.     nl_forward();
  2331.     point -= 5;
  2332.      
  2333.     /* Check for new indentation */
  2334.     exit = 0;
  2335.     say("Set indentation (TAB or BACKSPACE)");
  2336.     do {
  2337.         refresh();
  2338.         getkey();
  2339.         switch (key) {
  2340.             case CTRL('H') : ;
  2341.             case GREYBACK  : {
  2342.                 pas_delete_tab();
  2343.                 break;
  2344.             }
  2345.             case CTRL('I') : ;
  2346.             case GREYTAB   : {
  2347.                 pas_tabify();
  2348.                 break;
  2349.             }
  2350.             default : exit = 1;
  2351.         }
  2352.     } while (!exit);
  2353.     say("");
  2354.     check_abort();
  2355.      
  2356.     /* Insert BEGIN/END pair, delete if CTRL('H') is entered */
  2357.     to_end_line();
  2358.     tag1 = point;
  2359.     stuff(" BEGIN");
  2360.     nl_forward();
  2361.     pas_indenter();
  2362.     pas_tabify();
  2363.     insert('\n');
  2364.     pas_indenter();
  2365.     pas_tabify();
  2366.     stuff("END;");
  2367.     if (end_comments)
  2368.         stuff(" (* ELSE *)");
  2369.     tag2 = point;
  2370.     nl_reverse();
  2371.     insert(';');
  2372.     --point;
  2373.     maybe_refresh();
  2374.     getkey();
  2375.     check_abort();
  2376.     if ((key == CTRL('H'))||(key == GREYBACK)) {
  2377.         delete(point,tag2+1);
  2378.         delete(tag1,tag1+6);
  2379.     }
  2380.     else {
  2381.         ungot_key = key;
  2382.         delete(point,point+1);
  2383.     }
  2384. }
  2385.      
  2386. pas_repeat() on pas_ext_tab[CTRL('R')]
  2387. {
  2388.     short exit, orig_ret = pas_tab[CTRL('J')],
  2389.         orig_eq = pas_tab['='],
  2390.         orig_alt_ret = pas_tab[CTRL(ALT('j'))];
  2391.      
  2392.     bell_key = pas_tab[CTRL('G')];
  2393.      
  2394.     /* Insert REPEAT */
  2395.     stuff("REPEAT\n");
  2396.     point -= 7;
  2397.      
  2398.     /* Check for new indentation */
  2399.     exit = 0;
  2400.     say("Set indentation (TAB or BACKSPACE)");
  2401.     do {
  2402.         refresh();
  2403.         getkey();
  2404.         switch (key) {
  2405.             case CTRL('H') : ;
  2406.             case GREYBACK  : {
  2407.                 pas_delete_tab();
  2408.                 break;
  2409.             }
  2410.             case CTRL('I') : ;
  2411.             case GREYTAB   : {
  2412.                 pas_tabify();
  2413.                 break;
  2414.             }
  2415.             default : exit = 1;
  2416.         }
  2417.     } while (!exit);
  2418.     say("");
  2419.     check_abort();
  2420.      
  2421.     /* Insert UNTIL */
  2422.     nl_forward();
  2423.     insert('\n');
  2424.     pas_indenter();
  2425.     stuff("UNTIL ;");
  2426.     --point;
  2427.      
  2428.     /* Input condition in recursive edit mode.  A-<cr> or <cr> exits */
  2429.     pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
  2430.     pas_tab['='] = find_index("normal-character");
  2431.     pas_tab[CTRL('J')] = find_index("exit-level");
  2432.     pas_tab[CTRL('G')] = find_index("p-abort");
  2433.     reg_tab[CTRL('G')] = find_index("p-abort");
  2434.     major_mode = strsave("UNTIL condition (<cr> to exit)");
  2435.     strcpy(mode, major_mode);
  2436.     recursive_edit();
  2437.     major_mode = strsave("Pascal");
  2438.     make_mode();
  2439.     pas_tab[CTRL('J')] = orig_ret;
  2440.     pas_tab['='] = orig_eq;
  2441.     pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  2442.     reg_tab[CTRL('G')] = find_index("abort");
  2443.     pas_tab[CTRL('G')] = bell_key;
  2444.     check_abort();
  2445.      
  2446.     /* go to indentation of loop body */
  2447.     nl_reverse();
  2448.     pas_indenter();
  2449.     pas_tabify();
  2450. }
  2451.      
  2452. pas_case() on pas_ext_tab[CTRL('C')]
  2453. {
  2454.     short orig_ret = pas_tab[CTRL('J')],
  2455.         orig_alt_ret = pas_tab[CTRL(ALT('j'))];
  2456.      
  2457.     bell_key = pas_tab[CTRL('G')];
  2458.      
  2459.     /* Insert CASE OF */
  2460.     stuff("CASE  OF\n");
  2461.     point -= 4;
  2462.      
  2463.     /* Input case expression in recursive edit mode.
  2464.         A-<cr> or <cr> exits             */
  2465.     pas_tab[CTRL(ALT('j'))] = find_index("exit-level");
  2466.     pas_tab[CTRL('J')] = find_index("exit-level");
  2467.     pas_tab[CTRL('G')] = find_index("p-abort");
  2468.     reg_tab[CTRL('G')] = find_index("p-abort");
  2469.     major_mode = strsave("CASE expression (<cr> to exit)");
  2470.     strcpy(mode, major_mode);
  2471.     recursive_edit();
  2472.     major_mode = strsave("Pascal");
  2473.     make_mode();
  2474.     reg_tab[CTRL('G')] = find_index("abort");
  2475.     pas_tab[CTRL('G')] = bell_key;
  2476.     pas_tab[CTRL('J')] = orig_ret;
  2477.     pas_tab[CTRL(ALT('j'))] = orig_alt_ret;
  2478.     check_abort();
  2479.      
  2480.     /* Insert END */
  2481.     to_end_line();
  2482.     nl_forward();
  2483.     pas_indenter();
  2484.     pas_tabify();
  2485.     insert('\n');
  2486.     pas_indenter();
  2487.     pas_tabify();
  2488.     stuff("END;");
  2489.     if (end_comments)
  2490.         stuff(" (* CASE *)");
  2491.     nl_reverse();
  2492.     insert(' :');
  2493.     point-=2;
  2494. }
  2495.      
  2496. /* Commands to prompt for and complete names of pas- routines */
  2497. /* Requires modified COMPLETE.E file */
  2498. /*
  2499. /char *psub_match(s, start)
  2500. /char *s;
  2501. /{
  2502. /int i;
  2503. /
  2504. /for (; i = name_match(s, start); start = 0)
  2505. /    switch (name_type(i)) {
  2506. /        case NT_COMMAND: case NT_SUBR:
  2507. /            return name_name(i);
  2508. /    }
  2509. /return 0;
  2510. /}
  2511. /
  2512. /get_psub(res, pr)
  2513. /char *res, *pr;
  2514. /{
  2515. /strcpy(res,"pas-");
  2516. /comp_read(res, pr, psub_match, 0);
  2517. /}
  2518. /
  2519. /get_psub_index(pr)
  2520. /char *pr;
  2521. /{
  2522. /char psub[80];
  2523. /int name_index;
  2524. /
  2525. /get_psub(psub, pr);
  2526. /name_index = find_index(psub);
  2527. /if (name_index && (name_type(name_index) == NT_SUBR ||
  2528. /            name_type(name_index) == NT_COMMAND))
  2529. /    return name_index;
  2530. /error("There's no Pascal command named '%.50s'.",psub);
  2531. /return 0;
  2532. /}
  2533. /
  2534. /command pas_named() on pas_tab[ALT(']')], pas_tab[FALT(2)]
  2535. /{
  2536. /char msg[40];
  2537. /int index;
  2538. /
  2539. /if (has_arg)
  2540. /    sprintf(msg, "%d Pascal Command: ", iter);
  2541. /else
  2542. /    sprintf(msg, "Pascal Command: ");
  2543. /if (index = get_psub_index(msg))
  2544. /    do_command(index);
  2545. /}
  2546. */
  2547.      
  2548. when_loading()
  2549. {
  2550.     int i;
  2551.      
  2552.     pas_tab[CTRL(']')] = find_index("pas-ext-tab");
  2553.     for (i = 'A'; i <= 'Z'; i++) {
  2554.         if (pas_ext_tab[ALT(i)] <= 0)
  2555.             pas_ext_tab[ALT(i)] = find_index("case-indirect");
  2556.         if (pas_ext_tab[i] <= 0)
  2557.             pas_ext_tab[i] = find_index("case-indirect");
  2558.     }
  2559.     pas_ext_tab[CTRL('H')] = find_index("pas-delete-tab");
  2560. }
  2561.      
  2562. -------
  2563. 31-Oct-86 13:22:44-PST,503;000000000001
  2564. Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
  2565. Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 13:19:20 PST
  2566. Date: Fri 31 Oct 86 13:17:37-PST
  2567. From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
  2568. Subject: PAS_MENU file
  2569. To: info-ibmpc@B.ISI.EDU
  2570. Message-ID: <12251270280.17.FAT.STOREY@Sierra.Stanford.EDU>
  2571.      
  2572.      
  2573. ^B    begin        ^H    del tabs    ^T    type
  2574. ^C    case        ^I    if        w    with
  2575. ^E    else        ^P    procedure    ^W    while
  2576. e    end        p    program        ^V    var
  2577. ^F    for        r    record
  2578. f    function    ^R    repeat
  2579. -------
  2580. 31-Oct-86 14:14:03-PST,8796;000000000001
  2581. Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
  2582. Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 14:12:27 PST
  2583. Date: Fri 31 Oct 86 13:05:00-PST
  2584. From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
  2585. Subject: FOR_MODE.E file
  2586. To: info-ibmpc@B.ISI.EDU
  2587. Message-ID: <12251267981.17.FAT.STOREY@Sierra.Stanford.EDU>
  2588.      
  2589.      
  2590. /* Written by James S. Storey */
  2591.      
  2592. /* Subroutines and commands for Fortran mode.
  2593.     These commands are read in when Fortran mode is invoked for the
  2594.     first time    */
  2595.      
  2596. #include "\epsilon\eel.h"
  2597.      
  2598. int structured = 1;    /* 1 indents to previous line, 0 indents to col 7 */
  2599. int Matchdelim = 1;    /* 1 for showing matching ')' */
  2600.      
  2601. keytable fort_tab;        /* key table for Fortran mode */
  2602.      
  2603. buffer short bell_key;
  2604.      
  2605. f_abort()
  2606. {
  2607.     fort_tab[BELL] = bell_key;
  2608.     reg_tab[BELL] = find_index("abort");
  2609.     if (recursion_level>0)
  2610.         exit_level();
  2611.     user_abort = 1;
  2612. }
  2613.      
  2614.      
  2615. /* Routine used by fort-cont and fort-indent to decide how to continue
  2616.  the line. */
  2617.      
  2618. fort_cont_indent()
  2619. {
  2620.     char cont_char;
  2621.     int eol = point, indent_col;
  2622.      
  2623.     to_begin_line();
  2624.     cont_char=curchar();
  2625.     if (index("*cC",cont_char)) {    /* Previous line was a comment */
  2626.         indent_col = 3;
  2627.         if (structured) {    /* find first darkspace past col 1 */
  2628.             ++point;    /* skip comment character */
  2629.             if ((re_search(1, "[^ \t]")) && (point <= eol)) {
  2630.                 /* set indentation to begn of darkspace */
  2631.                 indent_col = current_column() -1;
  2632.             }
  2633.         }
  2634.         point = eol+1;
  2635.         bprintf("%c  ",cont_char);
  2636.         to_column(indent_col);
  2637.     }
  2638.     else {                /* Previous line was a statement */
  2639.         indent_col = 6;
  2640.         if (structured) {    /* find first darkspace past col 1 */
  2641.             move_to_column(6);
  2642.             if ((re_search(1, "[^ \t]")) && (point <= eol)) {
  2643.                 /* set indentation to begn of darkspace */
  2644.                 indent_col = current_column() -1;
  2645.             }
  2646.         }
  2647.         point = eol+1;
  2648.         bprintf("     +");
  2649.         to_column(indent_col);
  2650.     }
  2651. }
  2652.      
  2653. /* fort-cont    Fortran continue current line.
  2654.     Continues current line on next line.  If the current line is
  2655.     blank, another blank line is inserted.  If the current line is
  2656.     a comment line, the comment character is copied to the next
  2657.     line and the line is indented to column 4. If the current line
  2658.     is a program line, the continuation character '+' is inserted
  2659.     in column 6 */
  2660.      
  2661. command fort_cont() on fort_tab[ALT('j')], fort_tab[CTRL(ALT('j'))]
  2662. {
  2663.     insert('\n');
  2664.     --point;
  2665.     fort_cont_indent();
  2666. }
  2667.      
  2668. /* fort-late-cont    This command makes an existing line into a
  2669.     continuation of the previous line. */
  2670.      
  2671. command fort_late_cont() /* on A-N-+ */
  2672. {
  2673.     int orig = point;
  2674.      
  2675.     move_to_column(6);
  2676.     if (current_column() < 6) {
  2677.         to_column(5);
  2678.         insert('+');
  2679.     }
  2680.     else {
  2681.         if (character(point-1) == '\t')
  2682.             orig += tab_size - 1;
  2683.         delete_hacking_tabs();
  2684.         insert('+');
  2685.         point = orig;
  2686.     }
  2687. }
  2688.      
  2689.      
  2690. /* command to toggle structured indentation */
  2691.      
  2692. command set_struct()
  2693. {
  2694.     structured = (has_arg? (iter != 0) : !structured);
  2695.     say(structured?"Structured indentation on" :
  2696.         "Structured indentation off");
  2697.     iter = 1;
  2698. }
  2699.      
  2700. /* fort-indenter    Indent newlines in Fortran mode.
  2701.     Called following a newline character.  If the newline is at the
  2702.     end of a line, the line is indented normally.  If the newline
  2703.     is the middle of a program line, the line is continued as in
  2704.     "fort-cont", Fortran continue current line.
  2705.      
  2706.     Bugs: With auto-fill, it continues lines after a newline if the
  2707.     last character in the previous line is at the fill-column, and
  2708.     it does not continue lines if more than one space preceded the
  2709.     character which caused the auto-fill. */
  2710.      
  2711. fort_indenter()
  2712. {
  2713.     int orig = point;
  2714.      
  2715.     /* Check for newline at the end of a line, or followed by blanks */
  2716.      
  2717.     to_end_line();
  2718.     if (!re_search(-1, "[^ \t]") || point < orig) {
  2719.      
  2720.         /* Check for auto-return */
  2721.      
  2722.         point = orig-1;
  2723.         if ((current_column() < margin_right-1) || !(fill_mode)) {
  2724.             ++point;
  2725.             if (structured) {
  2726.                 indent_previous();
  2727.                 if (current_column() < 6)
  2728.                     to_column(6);
  2729.             }
  2730.             else
  2731.                 to_column(6);    /* indent to column 7 */
  2732.         }
  2733.         else
  2734.             /* Auto-return, continue previous line */
  2735.             fort_cont_indent();
  2736.     }
  2737.     else {
  2738.         point = orig-1;
  2739.         fort_cont_indent();
  2740.     }
  2741. }
  2742.      
  2743. /* backward-kill-spaces(back) Delete up to BACK spaces preceding point */
  2744.      
  2745. backward_kill_spaces(back)
  2746. int back;
  2747. {
  2748.     int orig = point;
  2749.      
  2750.     re_search(-1,"( )*");
  2751.     if (point <= orig-back) {
  2752.         point = orig;
  2753.         delete(point-back,point);
  2754.     }
  2755.     else {
  2756.         delete(point,orig);
  2757.     }
  2758. }
  2759.      
  2760. /* fort-tabify    Indent by half-tabs.
  2761.     If the point is in the current line's indentation, a half-tab is
  2762.     added to the indentation.  Otherwise, if the point is in columns
  2763.     1 to 6, whitespace is added out to column 6, or if the point is
  2764.     past column 6, a half-tab is added before the point.
  2765.      
  2766.     When adding half-tabs, if the point is preceded by 1/2 a tab or
  2767.     more spaces, the spaces following the last tab-stop are deleted
  2768.     and a tab is added.  Otherwise, spaces are added up to 1/2 a tab
  2769.     past the last tab stop. */
  2770.      
  2771. #define HALF_TAB tab_size/2
  2772.      
  2773. command fort_tabify() on fort_tab[CTRL('I')]
  2774. {
  2775.     int orig = point, excess, lack;
  2776.      
  2777.     /* skip leading blanks */
  2778.     to_begin_line();
  2779.     if (!re_search(1, "[^ \t]") || point > orig) { /* skip blanks */
  2780.         point = orig;
  2781.         to_indentation();
  2782.     }
  2783.     else                       /* restore point */
  2784.         point = orig;
  2785.      
  2786.     /* Tabify line */
  2787.     if (current_column() < 5 )     /* insert tab */
  2788.         to_column(6);
  2789.     else {                /* insert half-tab */
  2790.         excess = (current_column()%tab_size);
  2791.         lack = HALF_TAB-excess;
  2792.         if (lack > 0) {        /* between tab and half-tab stops */
  2793.             for (; lack-- > 0; insert(' ')) ;
  2794.         }
  2795.         else {            /* between half-tab and tab stops */
  2796.             backward_kill_spaces(excess);
  2797.             insert('\t');
  2798.         }
  2799.     }
  2800. }
  2801.      
  2802. /* fort-delete-tab    If at column 7, delete the label field.  Otherwise,
  2803.     Delete a half tab preceding the point, hacking full tabs. */
  2804.      
  2805.      
  2806. fort_delete_tab()  /* on fort_ext_tab[CTRL('H')] */
  2807. {
  2808.     int excess, i;
  2809.      
  2810.     if (current_column() == tab_size) {
  2811.         if (character(point-1) == '\t')
  2812.             delete(point-1,point);
  2813.         else
  2814.             backward_kill_spaces(tab_size);
  2815.         return;
  2816.     }
  2817.     /* Else */
  2818.     excess = (current_column()%tab_size);
  2819.     if (excess == 0) {        /* at a tab stop */
  2820.         if (character(point-1) == '\t') {
  2821.             /* delete previous tab, insert half tab */
  2822.             delete(point-1,point);
  2823.             for( i=1 ; i++ <=HALF_TAB ; insert(' ')) ;
  2824.         }
  2825.         else         /* delete to last non-space or half tab stop */
  2826.             backward_kill_spaces(HALF_TAB);
  2827.     }
  2828.     else  {
  2829.         if (excess <= HALF_TAB)        /* Between tab and half tab */
  2830.             backward_kill_spaces(excess);
  2831.         else                /* Between half tab and tab */
  2832.             backward_kill_spaces(excess-HALF_TAB);
  2833.     }
  2834. }
  2835.      
  2836. /* fort-merge    Fortran merge continuation with previous.
  2837.     Merges the current line with the previous, removing line numbers
  2838.     and continuation characters (if necessary) for statement lines,
  2839.     and removing the comment character for comment lines.  An error
  2840.     message is given if the command would merge a comment character
  2841.     onto the end of a statement character. */
  2842.      
  2843. command fort_merge() on fort_tab[ALT('^')]
  2844. {
  2845.     int orig = point, bol;
  2846.      
  2847.     to_begin_line();
  2848.     bol = point;
  2849.     if (index("*cC",curchar())) {    /* Merge continuation line */
  2850.         --point;
  2851.         to_begin_line();
  2852.         if (!index("*cC",curchar())) {
  2853.             /* Error: Attempt to Merge with statement */
  2854.             say("Error: cannot merge continuation line with statement line");
  2855.             point = orig;
  2856.             return;
  2857.         }
  2858.         else {
  2859.             if (orig = bol)
  2860.                 orig = bol-1;
  2861.             else
  2862.                 orig -= 2;
  2863.             delete(bol-1,bol+1);
  2864.         }
  2865.     }
  2866.     else {
  2867.         if (!search(1, "\t") || (point > bol+6)) {
  2868.             /* No tabs in Col 1-6 */
  2869.             if (orig < bol+6)
  2870.                 orig = bol-1;  /* end of previous line */
  2871.             else
  2872.                 orig -= 7;     /* orig minus amount deleted */
  2873.             delete(bol-1,bol+6);
  2874.         }
  2875.         else {
  2876.             if (orig < point)
  2877.                 orig = bol-1;    /* end of previous line */
  2878.             else
  2879.                 orig -= point-bol+1;
  2880.                            /* orig minus amount deleted */
  2881.             delete(bol-1,point);
  2882.         }
  2883.     }
  2884.     point = orig;
  2885. }
  2886.      
  2887. /* fort-comment    Pad the current line with blanks out to column 80.
  2888.     This command allows end of line comments that will wrap to the
  2889.     next screen line. */
  2890.      
  2891. command fort_comment() on fort_tab[ALT(';')]
  2892. {
  2893.     int orig=point, col7;
  2894.      
  2895.     move_to_column(6);
  2896.     col7 = point;
  2897.     for (point = orig; point <= col7+72; insert(' '))
  2898.         ;
  2899. }
  2900.      
  2901. when_loading()
  2902. {
  2903.     int i;
  2904.      
  2905.     for (i = 'A'; i <= 'Z'; i++)
  2906.         if (fort_tab[ALT(i)] <= 0)
  2907.             fort_tab[ALT(i)] = find_index("case-indirect");
  2908.     if (Matchdelim)
  2909.         fort_tab[')'] = find_index("show-matching-delimiter");
  2910.     fort_tab[ALT('i')] = find_index("indent-under");
  2911.     fort_tab[CTRL('M')] = find_index("newline");
  2912.     fort_tab[CTRL('H')] = find_index("delete-hacking-tabs");
  2913.     keytran[NUMALT(GREYPLUS)] = NUMALT(GREYPLUS);
  2914.     fort_tab[NUMALT(GREYPLUS)] = (short) fort_late_cont;
  2915. }
  2916.      
  2917.      
  2918. -------
  2919. 31-Oct-86 14:36:29-PST,2275;000000000001
  2920. Return-Path: <FAT.STOREY@Sierra.Stanford.EDU>
  2921. Received: FROM SU-SIERRA.ARPA BY B.ISI.EDU WITH TCP ; 31 Oct 86 14:35:36 PST
  2922. Date: Fri 31 Oct 86 13:01:12-PST
  2923. From: James S. Storey <FAT.STOREY@Sierra.Stanford.EDU>
  2924. Subject: FOR_LOAD.E files
  2925. To: info-ibmpc@B.ISI.EDU
  2926. Message-ID: <12251267290.17.FAT.STOREY@Sierra.Stanford.EDU>
  2927.      
  2928. /************************************************************************
  2929. * "Epsilon", "EEL" and "Lugaru" are trademarks of Lugaru Software, Ltd. *
  2930. *                                    *
  2931. *     Copyright (C) 1985 Lugaru Software Ltd.  All rights reserved.    *
  2932. *                                    *
  2933. * Limited permission is hereby granted to reproduce and modify this    *
  2934. * copyrighted material provided that the resulting code is used only in    *
  2935. * conjunction with Lugaru products and that this notice is retained in    *
  2936. * any such reproduction or modification.                *
  2937. ************************************************************************/
  2938.      
  2939. /*          Developed by James S. Storey                                   */
  2940.      
  2941. #include "\epsilon\eel.h"
  2942.      
  2943. /* This mode auto-loads from files FOR_MODE and FOR_EXT */
  2944. #define FOR_MODE "c:\\epsilon\\modes\\for_mode"
  2945. #define FOR_EXT "c:\\epsilon\\modes\\for_ext"
  2946.      
  2947. /* Format buffer for FORTRAN programs.
  2948.     This command puts the current buffer in the Fortran mode,
  2949.     appropriate for editing programs written in Fortran.
  2950.     Command names are of the form fort-COMMAND.  A series of
  2951.     statement commands automatically insert a template for most
  2952.     Fortran statements.  These statement commands are bound to keys
  2953.     prefixed by the C-] key.
  2954.      
  2955.     By default, the find-file command automatically turns on
  2956.     Fortran mode for files with the extensions .f or .for. */
  2957.      
  2958. command fort_mode()
  2959. {
  2960.     char *_fort_tab = "fort-tab", *_ind_ptr = "fort-indenter";
  2961.     short *_fort_ptr;
  2962.      
  2963.     if (!find_index("fort-tab")) {
  2964.         sayput("Loading Fortran mode commands. . .");
  2965.         load_commands(FOR_MODE);
  2966.         load_commands(FOR_EXT);
  2967.         say("");
  2968.     }
  2969.     _fort_ptr=index_table(find_index(_fort_tab));
  2970.     mode_keys = _fort_ptr;
  2971.     major_mode = strsave("Fortran");
  2972.     make_mode();
  2973.     (short) indenter = find_index(_ind_ptr);
  2974.     auto_indent = 1;
  2975.     tab_size = 6;
  2976. }
  2977.      
  2978. /* make this the default mode for .f and .for files */
  2979. suffix_f()    { fort_mode(); }
  2980. suffix_for()    { fort_mode(); }
  2981. -------
  2982. -------
  2983.