home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / myckeys.zip / MYCKEYS.E < prev    next >
Text File  |  1994-03-04  |  19KB  |  610 lines

  1. /* myckeys.e - this is the E part of the MyCKeys package     940304 */
  2. /*                                                                  */
  3. /* The enter and space bar keys have been defined to do             */
  4. /* specific C editing features.                                     */
  5.  
  6. /* 940304: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  7. /*                                                                  */
  8. /*  .indent_pos really indents                                      */
  9. /*  .indentline function added (you can assign it to your favorite  */
  10. /*   key)                                                           */
  11. /*  .use ebooke hook (as an option)                                 */
  12. /*          I_m_using_ebooke                                        */
  13. /*                                                                  */
  14. /* 930930: Martin Lafaix (lafaix@sophia.inria.fr)                   */
  15. /*                                                                  */
  16. /*  .Highlight support for comments, case statements &              */
  17. /*   functions headers.                                             */
  18. /*  .Autoindentation in STREAM mode.                                */
  19. /*          I_like_automatic_indent                                 */
  20. /*  .Misc expansion changes.                                        */
  21. /*          I_like_systematic_braces                                */
  22. /*                                                                  */
  23.  
  24. /* this file is an adaptation of the EPM 'ckeys.e' E Macro file     */
  25.  
  26. compile if not defined(BLACK)
  27. const
  28.    my_c_keys_is_external = 1
  29.    INCLUDING_FILE = 'MYCKEYS.E'
  30.    EXTRA_EX = 0
  31.    include 'stdconst.e'
  32. compile else
  33.    const my_c_keys_is_external = 0
  34. compile endif
  35.  
  36. /*
  37. ** Expansion control constants
  38. **
  39. ** You can modify those constants to adjust autoexpansion behavior
  40. */
  41.  
  42. CONST
  43. compile if not defined(I_like_my_cases_under_my_switch)
  44.    I_like_my_cases_under_my_switch = 1
  45. compile endif
  46. compile if not defined(I_like_a_semicolon_supplied_after_default)
  47.    I_like_a_semicolon_supplied_after_default = 0
  48. compile endif
  49. compile if not defined(ADD_BREAK_AFTER_DEFAULT)
  50.    ADD_BREAK_AFTER_DEFAULT = 1
  51. compile endif
  52. compile if not defined(WANT_BRACE_BELOW_STATEMENT)
  53.    WANT_BRACE_BELOW_STATEMENT = 1
  54. compile endif
  55. compile if not defined(USE_ANSI_C_NOTATION)
  56.    USE_ANSI_C_NOTATION = 1  -- 1 means use shorter ANSI C notation on MAIN.
  57. compile endif
  58. compile if not defined(I_like_systematic_braces)
  59.    I_like_systematic_braces = 0
  60. compile endif
  61. compile if not defined(I_like_automatic_indent)
  62.    I_like_automatic_indent = 1
  63. compile endif
  64. compile if not defined(i_m_using_ebooke)
  65.    I_m_using_ebooke = 1
  66. compile endif
  67.  
  68. compile if my_c_keys_is_external = 1
  69.    C_TABS = 2
  70.    C_MARGINS = 1 MAXMARGIN 1
  71.    WANT_CUA_MARKING = 'SWITCH'
  72.    ASSIST_TRIGGER = 'ENTER'
  73.    ENHANCED_ENTER_KEYS = 1
  74.    ENTER_ACTION   = 'ADDATEND'
  75.    C_ENTER_ACTION = 'ADDLINE'
  76.    SYNTAX_INDENT = 2
  77. compile endif
  78.  
  79. /*
  80. ** End of expansion control constants
  81. */
  82.  
  83. compile if INCLUDING_FILE <> 'EXTRA.E'  -- Following only gets defined in the base
  84. ;  Keyset selection is now done once at file load time, not every time
  85. ;  the file is selected.  And because the DEFLOAD procedures don't have to be
  86. ;  kept together in the macros (ET will concatenate all the DEFLOADs the
  87. ;  same way it does DEFINITs), we can put the DEFLOAD here where it belongs,
  88. ;  with the rest of the keyset function.  (what a concept!)
  89. ;
  90. compile if my_c_keys_is_external = 1
  91.   compile if I_m_using_ebooke = 0
  92. defproc bkm_defload()
  93.   compile else
  94. defproc myckeys_defload()
  95.   compile endif
  96. compile else
  97. defload
  98. compile endif
  99.    universal load_ext
  100.    universal load_var
  101. ;                                               C++                       Data Base Manager
  102.    if load_ext='C' or load_ext='H' or load_ext='CPP' or load_ext='CXX' or load_ext='SQC' or load_ext='PH' then
  103.  compile if my_c_keys_is_external = 1 & I_m_using_ebooke = 0
  104.       keys   bkm_keys
  105.  compile else
  106.       keys   my_c_keys
  107.  compile endif
  108.  compile if C_TABS <> 0
  109.       if not (load_var // 2) then  -- 1 would be on if tabs set from EA EPM.TABS
  110.          'tabs' C_TABS
  111.       endif
  112.  compile endif
  113.  compile if C_MARGINS <> 0
  114.       if not (load_var%2 - 2*(load_var%4)) then  -- 2 would be on if tabs set from EA EPM.MARGINS
  115.          'ma'   C_MARGINS
  116.       endif
  117.  compile endif
  118.       load_ext = 'KLUDGE'
  119.       return 1
  120.    else
  121.       return 0
  122.    endif
  123.  
  124. compile if my_c_keys_is_external = 1
  125. defc myckeys=
  126.   compile if I_m_using_ebooke = 1
  127.    return myckeys_defload()
  128.   compile else
  129.    return bkm_defload()
  130.   compile endif
  131.  
  132. compile if I_m_using_ebooke = 0
  133. definit
  134.   universal bkm_avail
  135.   bkm_avail = -1
  136.  
  137. defproc bkm_defselect
  138. compile endif
  139. compile endif
  140.  
  141. defc indentline=
  142.   call indent_pos()
  143.  
  144. compile if WANT_CUA_MARKING & EPM
  145.   compile if I_m_using_ebooke = 1
  146.  defkeys my_c_keys clear
  147.   compile else
  148.  defkeys bkm_keys overlay clear
  149.   compile endif
  150. compile else
  151.   compile if I_m_using_ebooke = 1
  152.  defkeys my_c_keys
  153.   compile else
  154.  defkeys bkm_keys
  155.   compile endif
  156. compile endif
  157.  
  158. def space=
  159.    universal expand_on
  160.    if expand_on then
  161.       if  not my_c_first_expansion() then
  162.          keyin ' '
  163.       endif
  164.    else
  165.       keyin ' '
  166.    endif
  167.    undoaction 1, junk                -- Create a new state
  168.  
  169. compile if ASSIST_TRIGGER = 'ENTER'
  170. def enter=
  171.  compile if ENHANCED_ENTER_KEYS & ENTER_ACTION <> ''
  172.    universal enterkey
  173.  compile endif
  174. compile else
  175. def c_enter=
  176.  compile if ENHANCED_ENTER_KEYS & c_ENTER_ACTION <> ''
  177.    universal c_enterkey
  178.  compile endif
  179. compile endif
  180.    universal expand_on
  181.  
  182.    if expand_on then
  183.       if not my_c_second_expansion() then
  184. compile if ASSIST_TRIGGER = 'ENTER'
  185.  compile if ENHANCED_ENTER_KEYS & ENTER_ACTION <> ''
  186.          call enter_common(enterkey)
  187.  compile else
  188.          call my_enter()
  189.  compile endif
  190. compile else  -- ASSIST_TRIGGER
  191.  compile if ENHANCED_ENTER_KEYS & c_ENTER_ACTION <> ''
  192.          call enter_common(c_enterkey)
  193.  compile else
  194.          call my_c_enter()
  195.  compile endif
  196. compile endif -- ASSIST_TRIGGER
  197. compile if I_like_automatic_indent
  198.          call indent_pos()
  199. compile endif
  200.       endif
  201.    else
  202. compile if ASSIST_TRIGGER = 'ENTER'
  203.  compile if ENHANCED_ENTER_KEYS & ENTER_ACTION <> ''
  204.       call enter_common(enterkey)
  205.  compile else
  206.       call my_enter()
  207.  compile endif
  208. compile else  -- ASSIST_TRIGGER
  209.  compile if ENHANCED_ENTER_KEYS & c_ENTER_ACTION <> ''
  210.       call enter_common(c_enterkey)
  211.  compile else
  212.       call my_c_enter()
  213.  compile endif
  214. compile endif -- ASSIST_TRIGGER
  215.    endif
  216.  
  217. /* Taken out, interferes with some people's c_enter. */
  218. ;def c_enter=   /* I like Ctrl-Enter to finish the comment field also. */
  219. ;   getline line
  220. ;   if pos('/*',line) then
  221. ;      if not pos('*/',line) then
  222. ;         end_line;keyin' */'
  223. ;      endif
  224. ;   endif
  225. ;   down;begin_line
  226.  
  227. def c_x=       /* Force expansion if we don't have it turned on automatic */
  228.    if not my_c_first_expansion() then
  229.       call my_c_second_expansion()
  230.    endif
  231.  
  232. def '{'=
  233.    universal expand_on
  234.  
  235.    keyin '{'
  236.    if expand_on then
  237.       getline line
  238.       if line='{' then
  239.          temp=substr('',1,.col-2)
  240.          insertline '',.line+1
  241.          insertline temp'}',.line+2
  242.          .line=.line+1
  243.          .col=.col-1
  244.          if .col=1 then
  245.             oline=.line
  246.             call psave_mark(savemark)
  247.             .line=.line-2
  248.             mark_line
  249.             while .line and substr(textline(.line),1,1)=' ' do
  250.                .line=.line-1
  251.             endwhile
  252.             mark_line
  253.             if .line=oline-2 and word(textline(.line),1)='typedef' then
  254.                .line=oline /* nop */
  255.             else
  256.                'process_style Function'
  257.             endif
  258.             call prestore_mark(savemark)
  259.             .line=oline
  260.             .col=.col+SYNTAX_INDENT
  261.          endif
  262.       else
  263.          keyin '}'
  264.          .col=.col-1
  265.       endif
  266.    endif
  267.  
  268. defproc indent_pos  /* Indent current line */
  269.    if .line then
  270.       oldline=.line
  271.       .line=.line-1
  272.       if .line then getline line; endif
  273.       while .line and line='' do
  274.          .line=.line-1
  275.          if .line then getline line; endif
  276.       endwhile
  277.       if .line then
  278.          call pfirst_nonblank()
  279.          getline line
  280.          line=strip(line,'T')
  281.          parse value line with wrd rest
  282.          i=verify(wrd,'({:;','M',1)-1
  283.          if i<=0 then i=length(wrd) endif
  284.          firstword=upcase(substr(wrd,1,i))
  285.          if wordpos(firstword,'CASE DEFAULT') then
  286.             getline oline, oldline
  287.             if wordpos('CASE', upcase(strip(oline,'L')))<>1 then
  288.                .col=.col+SYNTAX_INDENT
  289.             endif
  290.          elseif wordpos(firstword, 'IF FOR WHILE DO SWITCH') then
  291.             .col=.col+SYNTAX_INDENT
  292.          elseif firstword='}' and not pos('while',line) then
  293.             if .col>1 then .col=.col-SYNTAX_INDENT; endif
  294.          elseif line='{' and .col=1 then
  295.             .col=SYNTAX_INDENT+1
  296.          endif
  297.       else
  298.          .col=1
  299.       endif
  300.       newpos=.col
  301.       .line=oldline
  302.       call pfirst_nonblank()
  303.       if .col<newpos then
  304.          for i=1 to newpos-.col 
  305.             keyin ' '
  306.          endfor
  307.       elseif .col>newpos then
  308.          for i=1 to .col-newpos
  309.             keyin backspace
  310.          endfor
  311.       endif
  312.    endif
  313. compile endif  -- EXTRA
  314.  
  315. compile if not EXTRA_EX or INCLUDING_FILE = 'EXTRA.E'  -- Following gets defined in EXTRA.EX if it's being used
  316. defproc my_c_first_expansion
  317.    retc=1
  318.    if .line then
  319.       getline line
  320.       line=strip(line,'T')
  321.       w=line
  322.       wrd=upcase(w)
  323.       ws = substr(line, 1, max(verify(line, ' '\9)-1,0))
  324.       if wrd='FOR' then
  325. compile if WANT_BRACE_BELOW_STATEMENT
  326.          replaceline w'(; ; )'
  327. compile if I_like_systematic_braces
  328.          insertline ws'  {',.line+1
  329.          insertline ws'  }',.line+2
  330. compile endif
  331. compile else
  332.          replaceline w'(; ; ) {'
  333.          insertline ws'}',.line+1
  334. compile endif -- WANT_BRACE_BELOW_STATEMENT
  335.          if not insert_state() then insert_toggle
  336.              call fixup_cursor()
  337.          endif
  338.          .col=.col+1
  339.       elseif wrd='IF' then
  340. compile if WANT_BRACE_BELOW_STATEMENT
  341.          replaceline w'()'
  342. compile else
  343.          replaceline w'() {'
  344.          insertline ws'} else {',.line+1
  345.          insertline ws'}',.line+2
  346. compile endif -- WANT_BRACE_BELOW_STATEMENT
  347.          if not insert_state() then insert_toggle
  348.          call fixup_cursor()
  349.          endif
  350.          .col=.col+1
  351.       elseif wrd='WHILE' then
  352. compile if WANT_BRACE_BELOW_STATEMENT
  353.          replaceline w'()'
  354. compile if I_like_systematic_braces
  355.          insertline ws'  {',.line+1
  356.          insertline ws'  }',.line+2
  357. compile endif
  358. compile else
  359.          replaceline w'(){'
  360.          insertline ws'}',.line+1
  361. compile endif -- WANT_BRACE_BELOW_STATEMENT
  362.          if not insert_state() then insert_toggle
  363.              call fixup_cursor()
  364.          endif
  365.          .col=.col+1
  366.       elseif wrd='DO' then
  367. compile if WANT_BRACE_BELOW_STATEMENT
  368.          replaceline w'{'
  369. ;        down
  370. compile else
  371.          replaceline w' {'
  372. compile endif -- WANT_BRACE_BELOW_STATEMENT
  373.          insertline ws'} while();',.line+1
  374.          call einsert_line()
  375.          .col=.col+SYNTAX_INDENT    /* indent for new line */
  376.       elseif wrd='CASE' then
  377.          replaceline w' :'
  378.          .col=.col+1
  379.       elseif wrd='SWITCH' then
  380. compile if WANT_BRACE_BELOW_STATEMENT
  381.          replaceline w'()'
  382.          insertline ws'  {',.line+1
  383.          insertline substr(wrd,1,length(wrd)-6)'  }',.line+2
  384. compile else
  385.          replaceline w' () {'
  386.          insertline substr(wrd,1,length(wrd)-6)'}',.line+1
  387. compile endif -- WANT_BRACE_BELOW_STATEMENT
  388.          if not insert_state() then insert_toggle
  389.              call fixup_cursor()
  390.          endif
  391.          .col=.col+1    /* move cursor between parentheses of switch ()*/
  392.       elseif wrd='MAIN' then
  393.          call enter_main_heading()
  394.       elseif words(line) then
  395.          if word(line,words(line))='/*' then
  396.             keyin '  */ x'
  397.             call psave_mark(savemark)
  398.             .col=.col-3
  399.             mark_char
  400.             .col=.col-5
  401.             mark_char
  402.             'process_style Commentaire'
  403.             end_line
  404.             rubout
  405.             call prestore_mark(savemark)
  406.             .col=.col-4
  407.          else
  408.             retc=0
  409.          endif
  410.       else
  411.          retc=0
  412.       endif
  413.    else
  414.       retc=0
  415.    endif
  416.    return retc
  417.  
  418. defproc my_c_second_expansion
  419.    retc=1
  420.    if .line then
  421.       getline line
  422.       parse value upcase(line) with '{' +0 a
  423.       brace = pos('{', line)
  424.       if .line < .last then
  425.          next_is_brace = textline(.line+1)='{'
  426.       else
  427.          next_is_brace = 0
  428.       endif
  429.       parse value line with wrd rest
  430.       i=verify(wrd,'({:;','M',1)-1
  431.       if i<=0 then i=length(wrd) endif
  432.       firstword=upcase(substr(wrd,1,i))
  433.       if firstword='FOR' then
  434.          /* do tabs to fields of C for statement */
  435.          cp=pos(';',line,.col)
  436.          if cp and cp>=.col then
  437.              .col=cp+2
  438.          else
  439.            cpn=pos(';',line,cp+1)
  440.            if cpn and (cpn>=.col) then
  441.              .col=cpn+2
  442.            else
  443.               if not brace and next_is_brace then down; endif
  444.              call einsert_line()
  445.               if not brace and not next_is_brace then .col=.col+SYNTAX_INDENT; endif
  446.  
  447.            endif
  448.          endif
  449.       elseif firstword='CASE' or firstword='DEFAULT' then
  450.          call psave_mark(savemark)
  451.          mark_line
  452.          call einsert_line()
  453.          if .line>2 then  /* take a look at the previous line */
  454.             getline prevline,.line-2
  455.             prevline=upcase(prevline)
  456.             parse value prevline with w .
  457.             if pos('(', w) then
  458.                parse value w with w '('
  459.             endif
  460.             if pos(':', w) then
  461.                parse value w with w ':'
  462.             endif
  463.             if w='CASE' then  /* align case statements */
  464.                i=pos('C',prevline)
  465.                replaceline substr('',1,i-1)||wrd rest,.line-1
  466.                .col=i+2
  467.             elseif w='DEFAULT' then
  468.                i=pos('D',prevline)
  469.                replaceline substr('',1,i-1)||wrd rest,.line-1
  470.                .col=i+2
  471.             elseif w<>'SWITCH' and w<>'{' and prevline<>'' then  /* shift current line over */
  472.                i=verify(prevline,' ')
  473.                if i then .col=i endif
  474.                if i>SYNTAX_INDENT then i=i-SYNTAX_INDENT else i=1 endif
  475.                .col=i+2
  476.                replaceline substr('',1,i-1)||wrd rest,.line-1
  477.             elseif w='{' then
  478.                i=pos('{',prevline)
  479.                .col=i+2
  480.             endif
  481.             /* get rid of line containing just a ; */
  482.             if firstword='DEFAULT' and .line <.last then
  483.                getline line,.line+1
  484.                if line=';' then
  485.                   deleteline .line+1
  486.                endif
  487.             endif
  488.          endif
  489.          'process_style Case'
  490.          call prestore_mark(savemark)
  491.       elseif firstword='BREAK' then
  492.          call einsert_line()
  493.          c=.col
  494.          if .col>SYNTAX_INDENT then
  495.             .col=.col-SYNTAX_INDENT
  496.          endif
  497.          keyin 'case :';left
  498.          insertline substr('',1,c-1)'break;',.line+1
  499.       elseif firstword='SWITCH' then
  500.          if not brace and next_is_brace then down; endif
  501.          call einsert_line()
  502.          c=.col
  503. compile if I_like_my_cases_under_my_switch
  504.          keyin 'case :';left
  505. compile else
  506.          keyin substr(' ',1,SYNTAX_INDENT)'case :';left
  507.          c=c+SYNTAX_INDENT
  508. compile endif
  509.          insertline substr(' ',1,c+SYNTAX_INDENT-1)'break;',.line+1
  510.          /* look at the next line to see if this is the first time */
  511.          /* the user typed enter on this switch statement */
  512.          if .line<=.last-2 then
  513.             getline line,.line+2
  514.             i=verify(line,' ')
  515.             if i then
  516.                if substr(line,i,1)='}' then
  517. compile if I_like_my_cases_under_my_switch
  518.                   if i>1 then
  519.                      i=i-1
  520.                      insertline substr(' ',1,i)'default:',.line+2
  521.                   else
  522.                      insertline 'default:',.line+2
  523.                   endif
  524. compile else
  525.                   i=i+SYNTAX_INDENT-1
  526.                   insertline substr(' ',1,i)'default:',.line+2
  527. compile endif
  528.                   down;down;call psave_mark(savemark)
  529.                   mark_line
  530.                   'process_style Case'
  531.                   call prestore_mark(savemark)
  532.                   up; up
  533. compile if ADD_BREAK_AFTER_DEFAULT
  534.                   insertline substr(' ',1,i+SYNTAX_INDENT)'break;',.line+3
  535. compile elseif I_like_a_semicolon_supplied_after_default then
  536.                   insertline substr(' ',1,i+SYNTAX_INDENT)';',.line+3
  537. compile endif
  538.                endif
  539.             endif
  540.          endif
  541.       elseif a='{' or firstword='{' then  /* firstword or last word {?*/
  542. ;        if firstword='{' then
  543. ;           replaceline  wrd rest      -- This shifts the { to col 1.  Why???
  544. ;           call einsert_line();.col=SYNTAX_INDENT+1
  545. ;        else
  546.             call einsert_line()
  547. ;        endif
  548.       elseif firstword='MAIN' then
  549.          call enter_main_heading()
  550.       elseif firstword<>'' & wordpos(firstword, 'DO IF ELSE WHILE') then
  551.          if not brace and next_is_brace then down; endif
  552.          call einsert_line()
  553.          if not brace and not next_is_brace then .col=.col+SYNTAX_INDENT; endif
  554. ;        insert
  555. ;        .col=length(a)+2
  556.       elseif firstword='}' and not pos('while',line) then
  557.          call einsert_line()
  558.          if .col>1 then .col=pos('}',line)-SYNTAX_INDENT; endif
  559.       elseif pos('/*',line) then
  560.          if not pos('*/',line) then
  561.             end_line;keyin' */'
  562.          endif
  563.          call einsert_line()
  564.       else
  565.          retc=0
  566.       endif
  567.    else
  568.       retc=0
  569.    endif
  570.    return retc
  571.  
  572. defproc enter_main_heading
  573. compile if not USE_ANSI_C_NOTATION     -- Use standard notation
  574.    temp=substr('',1,SYNTAX_INDENT)  /* indent spaces */
  575.    replaceline 'main(argc, argv, envp)'
  576.    call psave_mark(savemark)
  577.    mark_line
  578.    'process_style Function'
  579.    call prestore_mark(savemark)
  580.    insertline temp'int argc;',.line+1         /* double indent */
  581.    insertline temp'char *argv[];',.line+2
  582.    insertline temp'char *envp[];',.line+3
  583.    insertline '{',.line+4
  584.    insertline '',.line+5
  585.    mainline = .line
  586.    if .cursory<7 then
  587.       .cursory=7
  588.    endif
  589.    mainline+5
  590.    .col=SYNTAX_INDENT+1
  591.    insertline '}',.line+1
  592. compile else                           -- Use shorter ANSII notation
  593.    replaceline 'main(int argc, char *argv[], char *envp[])'
  594.    call psave_mark(savemark)
  595.    mark_line
  596.    'process_style Function'
  597.    call prestore_mark(savemark)
  598.    insertline '{',.line+1
  599.    insertline '',.line+2
  600.    .col=SYNTAX_INDENT+1
  601.    insertline '}',.line+3
  602.    mainline = .line
  603.    if .cursory<4 then
  604.       .cursory=4
  605.    endif
  606.    mainline+2
  607. compile endif
  608.  
  609. compile endif  -- EXTRA
  610.