home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / mlepm.zip / cmode.e next >
Text File  |  1995-08-26  |  28KB  |  810 lines

  1. /* cmode.e - this is the E part of the C mode package        940522 */
  2.  
  3. /* The enter and space bar keys have been defined to do             */
  4. /* specific C editing features.                                     */
  5.  
  6. /* 950810: Martin Lafaix (lafaix@alto.unice.fr)                     */
  7. /*                                                                  */
  8. /*  .mhilite_C_mark now only highlight function headers.            */
  9. /*                                                                  */
  10. /* 950130: Martin Lafaix (lafaix@mimosa.unice.fr)                   */
  11. /*                                                                  */
  12. /*  .Added a new key assignment : a_1 (over a #include line).       */
  13. /*  .Minor speed improvement in mhilite_C_mark.                     */
  14. /*                                                                  */
  15. /* 940522: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  16. /*                                                                  */
  17. /*  .A new function : C_mode.  It sets current editing mode to      */
  18. /*   be C mode.                                                     */
  19. /*                                                                  */
  20. /* 940507: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  21. /*                                                                  */
  22. /*  .Hook support -- defload kludge removed!                        */
  23. /*                                                                  */
  24. /* 940505: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  25. /*                                                                  */
  26. /*  .Highlighting is now optional.                                  */
  27. /*          I_like_highlighting                                     */
  28. /*  .Indentation style can be changed at runtime: cindentstyle.     */
  29. /*  .WANT_BRACE_BELOW_STATEMENTS and I_like_systematic_braces       */
  30. /*   removed.                                                       */
  31. /*                                                                  */
  32. /* 940501: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  33. /*                                                                  */
  34. /*  .New naming convention.  Exported functions are mhilite[file],  */
  35. /*   mrehilite[file], munhilite[file], mindentline (and all         */
  36. /*   'highlight' synonyms).                                         */
  37. /*  .It's now compatible with the MLHILITE package (be sure to link */
  38. /*   MyCKeys before MLHILITE if MyCKeys is used as an externally    */
  39. /*   linked module.)                                                */
  40. /*  .mhilite_C_mark function added (required by MLHILITE).          */
  41. /*  .Removed the 'endembed comments' bug.                           */
  42. /*                                                                  */
  43. /* 940403: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  44. /*                                                                  */
  45. /*  .unhighlight_file and rehighlight_file functions added          */
  46. /*   (unhilite_file and rehilite_file works, too).                  */
  47. /*                                                                  */
  48. /* 940402: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  49. /*                                                                  */
  50. /*  .Better Q support. :)                                           */
  51. /*  .Misc. comments handling changes.                               */
  52. /*  .hilite_file is now a highlight_file synonym.                   */
  53. /*                                                                  */
  54. /* 940401: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  55. /*                                                                  */
  56. /*  .New file extension handling.                                   */
  57. /*          C_EXTENSIONS                                            */
  58. /*  .C++ comments (//) recognized.                                  */
  59. /*  .highlight_file function added.                                 */
  60. /*                                                                  */
  61. /* 940304: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  62. /*                                                                  */
  63. /*  .indent_pos really indents                                      */
  64. /*  .indentline function added (you can assign it to your favorite  */
  65. /*   key)                                                           */
  66. /*  .use ebooke hook (as an option)                                 */
  67. /*          I_m_using_ebooke                                        */
  68. /*                                                                  */
  69. /* 930930: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  70. /*                                                                  */
  71. /*  .Highlight support for comments, case statements &              */
  72. /*   functions headers.                                             */
  73. /*  .Autoindentation in STREAM mode.                                */
  74. /*          I_like_automatic_indent                                 */
  75. /*  .Misc expansion changes.                                        */
  76. /*          I_like_systematic_braces                                */
  77. /*                                                                  */
  78.  
  79. /* this file is an adaptation of the EPM 'ckeys.e' E Macro file     */
  80.  
  81.  
  82. ;  Usage:
  83. ;
  84. ;  Preliminary notes
  85. ;
  86. ;  mcindentstyle n
  87. ;
  88. ;     This command modifies the C-code indentation style.  Three
  89. ;     styles are actually recognized (-1 is the default):
  90. ;
  91. ;        1        int dummy(int a)        3        int dummy(int a)
  92. ;                 {                                {
  93. ;                   int b;                           int b;
  94. ;
  95. ;                   if(a)                            if(a)
  96. ;                     {                              {
  97. ;                     b=a;                             b=a;
  98. ;                     }                              }
  99. ;                   else                             else
  100. ;                     b=a+1;                           b=a+1;
  101. ;                 }                                }
  102. ;
  103. ;        2        int dummy(int a)
  104. ;                 {
  105. ;                   int b;
  106. ;
  107. ;                   if(a) {
  108. ;                     b=a;
  109. ;                   }
  110. ;                   else
  111. ;                     b=a+1;
  112. ;                 }
  113. ;
  114. ;     If n is negative, braces will not be automatically added.
  115. ;
  116. ;     Example:
  117. ;
  118. ;        mcindentstyle 2
  119. ;
  120. ;     The second indent style will be used (it does not 'reflow' the
  121. ;     previously entered code.)
  122. ;
  123.  
  124.  
  125.  
  126. compile if not defined(BLACK)
  127. const
  128.    my_c_keys_is_external = 1
  129.    INCLUDING_FILE = 'CMODE.E'
  130.    EXTRA_EX = 0
  131.    include 'stdconst.e'
  132. compile else
  133.    const my_c_keys_is_external = 0
  134. compile endif
  135.  
  136. /*
  137. ** Expansion control constants
  138. **
  139. ** You can modify those constants to adjust autoexpansion behavior
  140. */
  141.  
  142. CONST
  143. compile if not defined(I_like_my_cases_under_my_switch)
  144.    I_like_my_cases_under_my_switch = 1
  145. compile endif
  146. compile if not defined(I_like_a_semicolon_supplied_after_default)
  147.    I_like_a_semicolon_supplied_after_default = 0
  148. compile endif
  149. compile if not defined(ADD_BREAK_AFTER_DEFAULT)
  150.    ADD_BREAK_AFTER_DEFAULT = 1
  151. compile endif
  152. compile if not defined(C_EXTENSIONS)
  153.    C_EXTENSIONS = 'C H PH IH SQC CPP HPP CXX XH XPH XIH'
  154. compile endif
  155. compile if not defined(USE_ANSI_C_NOTATION)
  156.    USE_ANSI_C_NOTATION = 1  -- 1 means use shorter ANSI C notation on MAIN.
  157. compile endif
  158. compile if not defined(I_like_highlighting)
  159.    I_like_highlighting = 1
  160. compile endif
  161.  
  162. compile if my_c_keys_is_external = 1
  163.    C_TABS = 2
  164.    C_MARGINS = 1 MAXMARGIN 1
  165.    WANT_CUA_MARKING = 'SWITCH'
  166.    ASSIST_TRIGGER = 'ENTER'
  167.    ENHANCED_ENTER_KEYS = 1
  168.    ENTER_ACTION   = 'ADDATEND'
  169.    C_ENTER_ACTION = 'ADDLINE'
  170.    SYNTAX_INDENT = 2
  171. compile endif
  172.  
  173. /*
  174. ** End of expansion control constants
  175. */
  176.  
  177. compile if INCLUDING_FILE <> 'EXTRA.E'  -- Following only gets defined in the base
  178.  
  179. definit
  180.    universal ML_C_indentstyle
  181.    ML_C_indentstyle = -1
  182. compile if my_c_keys_is_external = 0
  183.    'maddhook load_hook c_load_hook'
  184. compile endif
  185.  
  186. defc C_mode
  187.    keys my_c_keys
  188.    'msetfilemode C mode'
  189.  
  190. defc c_load_hook
  191.    universal load_ext
  192.    universal load_var
  193.    if wordpos(load_ext,C_EXTENSIONS) then
  194.  compile if C_TABS <> 0
  195.       if not (load_var // 2) then  -- 1 would be on if tabs set from EA EPM.TABS
  196.          'tabs' C_TABS
  197.       endif
  198.  compile endif
  199.  compile if C_MARGINS <> 0
  200.       if not (load_var%2 - 2*(load_var%4)) then  -- 2 would be on if tabs set from EA EPM.MARGINS
  201.          'ma'   C_MARGINS
  202.       endif
  203.  compile endif
  204.       'C_mode'
  205.    endif
  206.  
  207. compile if I_like_highlighting = 1
  208. defc mhilite_C_mark=
  209.    sayerror 'Highlighting...'
  210.    display -3
  211.    call psave_pos(savepos)
  212.    call psave_mark(savemark)
  213.    getsearch oldsearch
  214.    if .last then
  215.       .line=0
  216.       while .line<.last do
  217.          .line=.line+1
  218.          getline line
  219.          if line<>'' then
  220.             if substr(line,1,1)='{' then -- function header?
  221.                call highlight_function_header()
  222.             endif
  223.             -- now, we're looking for comments, but we don't highlight them!
  224.             i=pos('//',line)
  225.             if i then
  226.                .col=i; endline
  227.             endif
  228.             j=1
  229.             j=pos('/*',line,j)
  230.             if j<i or i=0 then
  231.                k=pos('*/',line,j+2)
  232.                while j and (i=0 or j<i) and k do
  233.                   if k then
  234.                      .col=k+1
  235.                   endif
  236.                   j=pos('/*',line,k+2); k=pos('*/',line,j+2)
  237.                endwhile
  238.                if j then
  239.                   .col=j
  240.                   'xcom L $*/$+'
  241.                   .col=.col+2
  242.                   .line=.line-1
  243.                endif
  244.             endif
  245.          endif
  246.       endwhile
  247.    endif
  248.    setsearch oldsearch
  249.    call prestore_mark(savemark)
  250.    call prestore_pos(savepos)
  251.    display 3
  252.    sayerror 0
  253. compile endif
  254.  
  255. defc mcindentstyle=
  256.    universal ML_C_indentstyle
  257.    if arg(1)='' then
  258.       sayerror 'Current C indent style : 'ML_C_indentstyle
  259.    elseif (arg(1)>=1 & arg(1)<=3) | (arg(1)>=-3 & arg(1)<=-1) then
  260.       ML_C_indentstyle = arg(1)
  261.       sayerror 'Current C indent style : 'ML_C_indentstyle
  262.    else
  263.       sayerror 'Invalid arguments (|[-]1|[-]2|[-]3)'
  264.    endif
  265.  
  266. defc indent_c_line=
  267.   call indent_pos()
  268.  
  269. compile if WANT_CUA_MARKING & EPM
  270.  defkeys my_c_keys clear
  271. compile else
  272.  defkeys my_c_keys
  273. compile endif
  274.  
  275. def space=
  276.    universal expand_on
  277.    if expand_on then
  278.       if  not my_c_first_expansion() then
  279.          keyin ' '
  280.       endif
  281.    else
  282.       keyin ' '
  283.    endif
  284.    undoaction 1, junk                -- Create a new state
  285.  
  286. def a_1=
  287.    getline line
  288.    if substr(strip(line),1,1) = '#' then  -- it's a compiler directive
  289.       parse value line with '#' key file rest
  290.       if upcase(key) = 'INCLUDE' then     -- it's a #include directive
  291.          key = substr(file,1,1)
  292.          file = substr(file,2,length(file)-2)
  293.          if key = '"' then
  294.             'e ='file
  295.          elseif key = '<' then
  296.             'ep 'file' INCLUDE'
  297.          endif
  298.       endif
  299.    endif
  300.  
  301. compile if ASSIST_TRIGGER = 'ENTER'
  302. def enter=
  303.  compile if ENHANCED_ENTER_KEYS & ENTER_ACTION <> ''
  304.    universal enterkey
  305.  compile endif
  306. compile else
  307. def c_enter=
  308.  compile if ENHANCED_ENTER_KEYS & c_ENTER_ACTION <> ''
  309.    universal c_enterkey
  310.  compile endif
  311. compile endif
  312.    universal expand_on
  313.    universal ML_autoindent
  314.  
  315.    if expand_on then
  316.       if not my_c_second_expansion() then
  317. compile if ASSIST_TRIGGER = 'ENTER'
  318.  compile if ENHANCED_ENTER_KEYS & ENTER_ACTION <> ''
  319.          call enter_common(enterkey)
  320.  compile else
  321.          call my_enter()
  322.  compile endif
  323. compile else  -- ASSIST_TRIGGER
  324.  compile if ENHANCED_ENTER_KEYS & c_ENTER_ACTION <> ''
  325.          call enter_common(c_enterkey)
  326.  compile else
  327.          call my_c_enter()
  328.  compile endif
  329. compile endif -- ASSIST_TRIGGER
  330.          if ML_autoindent then
  331.             call indent_pos()
  332.          endif
  333.       endif
  334.    else
  335. compile if ASSIST_TRIGGER = 'ENTER'
  336.  compile if ENHANCED_ENTER_KEYS & ENTER_ACTION <> ''
  337.       call enter_common(enterkey)
  338.  compile else
  339.       call my_enter()
  340.  compile endif
  341. compile else  -- ASSIST_TRIGGER
  342.  compile if ENHANCED_ENTER_KEYS & c_ENTER_ACTION <> ''
  343.       call enter_common(c_enterkey)
  344.  compile else
  345.       call my_c_enter()
  346.  compile endif
  347. compile endif -- ASSIST_TRIGGER
  348.    endif
  349.  
  350. /* Taken out, interferes with some people's c_enter. */
  351. ;def c_enter=   /* I like Ctrl-Enter to finish the comment field also. */
  352. ;   getline line
  353. ;   if pos('/*',line) then
  354. ;      if not pos('*/',line) then
  355. ;         end_line;keyin' */'
  356. ;      endif
  357. ;   endif
  358. ;   down;begin_line
  359.  
  360. def c_x=       /* Force expansion if we don't have it turned on automatic */
  361.    if not my_c_first_expansion() then
  362.       call my_c_second_expansion()
  363.    endif
  364.  
  365. def '{'=
  366.    universal expand_on
  367.    universal ML_C_indentstyle
  368.  
  369.    keyin '{'
  370.    if expand_on then
  371.       getline line
  372.       if line='{' then
  373.          if .col>3 and (ML_C_indentstyle=2 | ML_C_indentstyle=-2) then
  374.             .col=.col-3; deletechar; deletechar; deletechar; keyin '{'
  375.             insertline '',.line+1
  376.             insertline substr('',1,.col-2)'}',.line+2
  377.             .col=.col+2
  378.          else
  379.             temp=substr('',1,.col-2)
  380.             insertline '',.line+1
  381.             insertline temp'}',.line+2
  382.          endif
  383.          .col=.col-1
  384.          if .col=1 then
  385. compile if I_like_highlighting = 1
  386.             call highlight_function_header()
  387. compile endif
  388.             .col=.col+SYNTAX_INDENT
  389.             refresh
  390.          endif
  391.          .line=.line+1
  392.       else
  393.          keyin '}'
  394.          .col=.col-1
  395.       endif
  396.    endif
  397.  
  398. compile endif  -- EXTRA
  399.  
  400. compile if not EXTRA_EX or INCLUDING_FILE = 'EXTRA.E'  -- Following gets defined in EXTRA.EX if it's being used
  401.  
  402. compile if I_like_highlighting
  403. defproc highlight_function_header /* Highlight function header */
  404.    call psave_pos(savepos_hfh)
  405.    call psave_mark(savemark_hfh)
  406.    .line=.line-1
  407.    while .line and substr(word(textline(.line),1),1,2)='//' do
  408.       .line=.line-1
  409.    endwhile
  410.    if .line and word(textline(.line),words(textline(.line)))='*/' then
  411.       getsearch savesearch
  412.       .col=wordindex(textline(.line),words(textline(.line)))
  413.       'xcom L $/*$r-'
  414.       setsearch savesearch
  415.       if .col=1 then
  416.          .line=.line-1
  417.       endif
  418.    endif
  419.    mark_line
  420.    while .line and (pos(substr(textline(.line),1,1),' '\9) or
  421.                     pos(';',textline(.line))) do
  422.       .line=.line-1
  423.    endwhile
  424.    mark_line
  425.    if wordpos(word(textline(.line),1),'typedef struct class union') then
  426.       ;
  427.    else
  428.       'process_style Function'
  429.    endif
  430.    call prestore_mark(savemark_hfh)
  431.    call prestore_pos(savepos_hfh)
  432. compile endif
  433.  
  434. defproc indent_pos  /* Indent current line */
  435.    universal ML_C_indentstyle
  436.    if .line then
  437.       oldline=.line
  438.       .line=.line-1
  439.       while .line & textline(.line)='' do
  440.          .line=.line-1
  441.       endwhile
  442.       if .line then
  443.          call pfirst_nonblank()
  444.          getline line
  445.          line=strip(line,'T')
  446.          parse value line with wrd rest
  447.          i=verify(wrd,'({:;','M',1)-1
  448.          if i<=0 then i=length(wrd) endif
  449.          firstword=upcase(substr(wrd,1,i))
  450.          if wordpos(firstword,'CASE DEFAULT') then
  451.             getline oline, oldline
  452.             if wordpos('CASE', upcase(strip(oline,'L')))<>1 then
  453.                .col=.col+SYNTAX_INDENT
  454.             endif
  455.          elseif wordpos(firstword, 'IF FOR WHILE DO SWITCH ELSE') then
  456.             .col=.col+SYNTAX_INDENT
  457.          elseif firstword='}' then
  458.             if .col>1 & not pos('while',line) & (ML_C_indentstyle=1 | ML_C_indentstyle=-1) then
  459.                .col=.col-SYNTAX_INDENT
  460.             elseif pos('else',line) then
  461.                .col=.col+SYNTAX_INDENT
  462.             endif
  463.          elseif line='{' & ML_C_indentstyle<>1 & ML_C_indentstyle<>-1 then
  464.             .col=.col+SYNTAX_INDENT
  465.          elseif line='{' and .col=1 then
  466.             .col=SYNTAX_INDENT+1
  467.          endif
  468.       else
  469.          .col=1
  470.       endif
  471.       newpos=.col
  472.       .line=oldline
  473.       call pfirst_nonblank()
  474.       if .col<newpos then
  475.          for i=1 to newpos-.col
  476.             keyin ' '
  477.          endfor
  478.       elseif .col>newpos then
  479.          delta=.col-newpos; .col=.col-delta
  480.          for i=1 to delta
  481.             deletechar
  482.          endfor
  483.       endif
  484.    endif
  485.  
  486. defproc insertbraces(style,ws)
  487.    if style=1 | style=-1 then
  488.       insertline ws'  {',.line+1
  489.       insertline ws'  }',.line+2
  490.    else
  491.       insertline ws'{',.line+1
  492.       insertline ws'}',.line+2
  493.    endif
  494.  
  495. defproc my_c_first_expansion
  496.    universal ML_C_indentstyle
  497.    retc=1
  498.    if .line then
  499.       getline line
  500.       line=strip(line,'T')
  501.       w=line
  502.       wrd=upcase(w)
  503.       ws = substr(line, 1, max(verify(line, ' '\9)-1,0))
  504.       if wrd='FOR' then
  505.          if ML_C_indentstyle<0 then
  506.             replaceline w'(; ; )'
  507.          elseif ML_C_indentstyle=3 then
  508.             replaceline w'(; ; ) {'
  509.             insertline ws'}',.line+1
  510.          else
  511.             replaceline w'(; ; )'
  512.             call insertbraces(ML_C_indentstyle,ws)
  513.          endif
  514.          if not insert_state() then insert_toggle
  515.              call fixup_cursor()
  516.          endif
  517.          .col=.col+1
  518.       elseif wrd='IF' then
  519.          if ML_C_indentstyle<0 then
  520.             replaceline w'()'
  521.          elseif ML_C_indentstyle=3 then
  522.             replaceline w'() {'
  523.             insertline ws'} else {',.line+1
  524.             insertline ws'}',.line+2
  525.          else
  526.             replaceline w'()'
  527.             call insertbraces(ML_C_indentstyle,ws)
  528.          endif
  529.          if not insert_state() then insert_toggle
  530.          call fixup_cursor()
  531.          endif
  532.          .col=.col+1
  533.       elseif wrd='WHILE' then
  534.          if ML_C_indentstyle<0 then
  535.             replaceline w'()'
  536.          elseif ML_C_indentstyle=3 then
  537.             replaceline w'(){'
  538.             insertline ws'}',.line+1
  539.          else
  540.             replaceline w'()'
  541.             call insertbraces(ML_C_indentstyle,ws)
  542.          endif
  543.          if not insert_state() then insert_toggle
  544.              call fixup_cursor()
  545.          endif
  546.          .col=.col+1
  547.       elseif wrd='DO' then
  548.          if ML_C_indentstyle=3 | ML_C_indentstyle=-3 then
  549.             replaceline w' {'
  550.          else
  551.             replaceline w'{'
  552.          endif
  553.          insertline ws'} while();',.line+1
  554.          call einsert_line()
  555.          .col=.col+SYNTAX_INDENT    /* indent for new line */
  556.       elseif wrd='CASE' then
  557.          replaceline w' :'
  558.          .col=.col+1
  559.       elseif wrd='SWITCH' then
  560.          if ML_C_indentstyle=3 | ML_C_indentstyle=-3 then
  561.             replaceline w'() {'
  562.             insertline substr(wrd,1,length(wrd)-6)'}',.line+1
  563.          else
  564.             replaceline w'()'
  565.             call insertbraces(ML_C_indentstyle,ws)
  566.          endif
  567.          if not insert_state() then insert_toggle
  568.              call fixup_cursor()
  569.          endif
  570.          .col=.col+1    /* move cursor between parentheses of switch ()*/
  571.       elseif wrd='MAIN' then
  572.          call enter_main_heading()
  573.       elseif words(line) then
  574.          if word(line,words(line))='/*' then
  575.             keyin '  */'
  576.             .col=.col-3
  577.          else
  578.             retc=0
  579.          endif
  580.       else
  581.          retc=0
  582.       endif
  583.    else
  584.       retc=0
  585.    endif
  586.    return retc
  587.  
  588. defproc my_c_second_expansion
  589.    universal ML_C_indentstyle
  590.    universal ML_autohilite
  591.    retc=1
  592.    if .line then
  593.       getline line
  594.       parse value upcase(line) with '{' +0 a
  595.       brace = pos('{', line)
  596.       if .line < .last then
  597.          next_is_brace = textline(.line+1)='{'
  598.       else
  599.          next_is_brace = 0
  600.       endif
  601.       parse value line with wrd rest
  602.       i=verify(wrd,'({:;','M',1)-1
  603.       if i<=0 then i=length(wrd) endif
  604.       firstword=upcase(substr(wrd,1,i))
  605.       if firstword='FOR' then
  606.          /* do tabs to fields of C for statement */
  607.          cp=pos(';',line,.col)
  608.          if cp and cp>=.col then
  609.             .col=cp+2
  610.          else
  611.             cpn=pos(';',line,cp+1)
  612.             if cpn and (cpn>=.col) then
  613.                .col=cpn+2
  614.             else
  615.                if not brace and next_is_brace then down; endif
  616.                call einsert_line()
  617.                if ML_C_indentstyle<>1 & ML_C_indentstyle<>-1 then
  618.                   .col=.col+SYNTAX_INDENT
  619.                endif
  620.                if not brace and not next_is_brace then .col=.col+SYNTAX_INDENT; endif
  621.             endif
  622.          endif
  623.       elseif firstword='CASE' or firstword='DEFAULT' then
  624.          call psave_mark(savemark)
  625.          mark_line
  626.          call einsert_line()
  627.          if .line>2 then  /* take a look at the previous line */
  628.             getline prevline,.line-2
  629.             prevline=upcase(prevline)
  630.             parse value prevline with w .
  631.             if pos('(', w) then
  632.                parse value w with w '('
  633.             endif
  634.             if pos(':', w) then
  635.                parse value w with w ':'
  636.             endif
  637.             if w='CASE' then  /* align case statements */
  638.                i=pos('C',prevline)
  639.                replaceline substr('',1,i-1)||wrd rest,.line-1
  640.                .col=i+2
  641.             elseif w='DEFAULT' then
  642.                i=pos('D',prevline)
  643.                replaceline substr('',1,i-1)||wrd rest,.line-1
  644.                .col=i+2
  645.             elseif w<>'SWITCH' and w<>'{' and prevline<>'' then  /* shift current line over */
  646.                i=verify(prevline,' ')
  647.                if i then .col=i endif
  648.                if i>SYNTAX_INDENT then i=i-SYNTAX_INDENT else i=1 endif
  649.                .col=i+2
  650.                replaceline substr('',1,i-1)||wrd rest,.line-1
  651.             elseif w='SWITCH' & (ML_C_indentstyle=3 | ML_C_indentstyle=-3) then
  652.                .col=.col+SYNTAX_INDENT
  653.             elseif w='{' then
  654.                i=pos('{',prevline)
  655.                .col=i+2
  656.             endif
  657.             /* get rid of line containing just a ; */
  658.             if firstword='DEFAULT' and .line <.last then
  659.                getline line,.line+1
  660.                if line=';' then
  661.                   deleteline .line+1
  662.                endif
  663.             endif
  664.          endif
  665.          if ML_autohilite then
  666.             'process_style Case'
  667.          endif
  668.          call prestore_mark(savemark)
  669.       elseif firstword='BREAK' then
  670.          call einsert_line()
  671.          c=.col
  672.          if .col>SYNTAX_INDENT then
  673.             .col=.col-SYNTAX_INDENT
  674.          endif
  675.          keyin 'case :';left
  676.          insertline substr('',1,c-1)'break;',.line+1
  677.       elseif firstword='SWITCH' then
  678.          if not brace and next_is_brace then down; endif
  679.          call einsert_line()
  680.          c=.col
  681. compile if I_like_my_cases_under_my_switch
  682.          keyin 'case :';left
  683. compile else
  684.          keyin substr(' ',1,SYNTAX_INDENT)'case :';left
  685.          c=c+SYNTAX_INDENT
  686. compile endif
  687.          insertline substr(' ',1,c+SYNTAX_INDENT-1)'break;',.line+1
  688.          /* look at the next line to see if this is the first time */
  689.          /* the user typed enter on this switch statement */
  690.          if .line<=.last-2 then
  691.             getline line,.line+2
  692.             i=verify(line,' ')
  693.             if i then
  694.                if substr(line,i,1)='}' then
  695. compile if I_like_my_cases_under_my_switch
  696.                   if i>1 then
  697.                      i=i-1
  698.                      insertline substr(' ',1,i)'default:',.line+2
  699.                   else
  700.                      insertline 'default:',.line+2
  701.                   endif
  702. compile else
  703.                   i=i+SYNTAX_INDENT-1
  704.                   insertline substr(' ',1,i)'default:',.line+2
  705. compile endif
  706.                   if ML_autohilite then
  707.                      down;down;call psave_mark(savemark)
  708.                      mark_line
  709.                      'process_style Case'
  710.                      call prestore_mark(savemark)
  711.                      up; up
  712.                   endif
  713. compile if ADD_BREAK_AFTER_DEFAULT
  714.                   insertline substr(' ',1,i+SYNTAX_INDENT)'break;',.line+3
  715. compile elseif I_like_a_semicolon_supplied_after_default then
  716.                   insertline substr(' ',1,i+SYNTAX_INDENT)';',.line+3
  717. compile endif
  718.                endif
  719.             endif
  720.          endif
  721.       elseif a='{' or firstword='{' then  /* firstword or last word {?*/
  722. ;        if firstword='{' then
  723. ;           replaceline  wrd rest      -- This shifts the { to col 1.  Why???
  724. ;           call einsert_line();.col=SYNTAX_INDENT+1
  725. ;        else
  726.             call einsert_line()
  727.             if (ML_C_indentstyle<>1 & ML_C_indentstyle<>-1) | .col=1 then
  728.                .col=.col+SYNTAX_INDENT
  729.             endif
  730. ;        endif
  731.       elseif firstword='MAIN' then
  732.          call enter_main_heading()
  733.       elseif firstword<>'' & wordpos(firstword, 'DO IF ELSE WHILE') then
  734.          if not brace and next_is_brace then down; endif
  735.          call einsert_line()
  736.          if not brace and not next_is_brace then .col=.col+SYNTAX_INDENT; endif
  737. ;        insert
  738. ;        .col=length(a)+2
  739.       elseif firstword='}' and not pos('while',line) then
  740.          call einsert_line()
  741.          if .col>1 & (ML_C_indentstyle=1 | ML_C_indentstyle=-1) then
  742.             .col=pos('}',line)-SYNTAX_INDENT
  743.          endif
  744.       elseif pos('/*',line) then
  745.          if not pos('*/',line) then
  746.             end_line;keyin' */'
  747.          endif
  748.          call einsert_line()
  749.       elseif pos('//',line) then
  750.          call einsert_line()
  751.       else
  752.          retc=0
  753.       endif
  754.    else
  755.       retc=0
  756.    endif
  757.    return retc
  758.  
  759. defproc enter_main_heading
  760.    universal ML_autohilite
  761. compile if I_like_highlighting = 1
  762.    universal curlinedone
  763.    curlinedone = 1 -- protect function header
  764. compile endif
  765. compile if not USE_ANSI_C_NOTATION     -- Use standard notation
  766.    temp=substr('',1,SYNTAX_INDENT)  /* indent spaces */
  767.    replaceline 'main(argc, argv, envp)'
  768.    if ML_autohilite then
  769.       call psave_mark(savemark)
  770.       mark_line
  771.       'process_style Function'
  772.       call prestore_mark(savemark)
  773.    endif
  774.    insertline temp'int argc;',.line+1         /* double indent */
  775.    insertline temp'char *argv[];',.line+2
  776.    insertline temp'char *envp[];',.line+3
  777.    insertline '{',.line+4
  778.    insertline '',.line+5
  779.    mainline = .line
  780.    if .cursory<7 then
  781.       .cursory=7
  782.    endif
  783.    mainline+5
  784.    .col=SYNTAX_INDENT+1
  785.    insertline '}',.line+1
  786. compile else                           -- Use shorter ANSI notation
  787.    replaceline 'main(int argc, char *argv[], char *envp[])'
  788.    if ML_autohilite then
  789.       call psave_mark(savemark)
  790.       mark_line
  791.       'process_style Function'
  792.       call prestore_mark(savemark)
  793.    endif
  794.    insertline '{',.line+1
  795.    insertline '',.line+2
  796.    .col=SYNTAX_INDENT+1
  797.    insertline '}',.line+3
  798.    mainline = .line
  799.    if .cursory<4 then
  800.       .cursory=4
  801.    endif
  802.    mainline+2
  803. compile endif
  804.  
  805. compile endif  -- EXTRA
  806.  
  807. compile if EVERSION >= 6
  808.    EA_comment 'This is a C/C++ editing mode, w/ automatic expansion, indentation and highlighting'
  809. compile endif
  810.