home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / DEMO / RIM22 / MACROS / C_INDENT.RM < prev    next >
Text File  |  1994-02-04  |  12KB  |  516 lines

  1. /*
  2. ** indent.rm - indenting routines
  3. */
  4.  
  5. #include "macro.h"
  6.  
  7. /* IndentStyle is an internal variable within the editor
  8. ** set it with RSE_FLAGS or on the command line using
  9. ** the -Is flag 0 = none 1 = regular 2 = smart 3 = template
  10. ** Default: 1
  11. */
  12. extern long    IndentStyle;
  13.  
  14. /* IndentSize is an internal variable within the editor
  15. ** set it with RSE_FLAGS or on the command line using
  16. ** the -Iwnnn where 'nnn' is size of indent. Default: 3
  17. */
  18. extern long    IndentSize;
  19.  
  20. HKEYBOARD    _c_smart, _c_template,    _c_alt_template, _r_keymap;
  21.  
  22.  
  23. #define DEBUGGING    1
  24. #if DEBUGGING
  25. char    szDebug[256];
  26. #endif
  27.  
  28. typedef struct pstate {
  29.     long    beginning_of_defun;
  30.     long    containing_cexp;
  31.     int    incomment;
  32.     int    instring;
  33.     int    quoted;
  34.     int    level;
  35. } PSTATE;
  36.  
  37.  
  38. typedef struct template_t    TEMPLATE, *PTEMPLATE;
  39. struct template_t {
  40.     char        *abbrev;            /* what is tested to see if a match exists */
  41.     char        *expansion;        /* what to expand to */
  42.     short        min;                /* need at least this many chars for this template */
  43.     unsigned    flags;            /* special handling flags */
  44. };
  45.  
  46.  
  47.  
  48. extern int DistanceToNextIndent(long col);    /* defined in slide.rm */
  49. extern int DistanceToNextIndent(long col);
  50. extern void slide_in(void);
  51. extern void slide_out(void);
  52.  
  53. extern int  calculate_c_indent(PSTATE *);    /* defined in c_smart.rm */
  54. extern void _c_newline();
  55. extern void _c_indent();
  56. extern void _c_open(void);
  57. extern void _c_close(void);
  58.  
  59. void _expand(PTEMPLATE template);
  60. void _c_expand(PTEMPLATE template);
  61. void _c_matching_brace(void);
  62. void just_brace(void);
  63. void just_cbrace(void);
  64. void just_space(void);
  65.  
  66.  
  67. void
  68. _c_next_word(void) {
  69.     long    len;
  70.     len = SrchFwd("([a-zA-Z0-9_]+)|([^ \t\f\na-zA-Z0-9_]+)|([ \t\f\n]+)[ \t\f\n]*", -1, 1, 0);
  71.     if ( len > 0 )
  72.         PosNextChar(len);
  73. } /* end _c_next_word() */
  74.  
  75.  
  76. void
  77. _h_next_word(void) {
  78.     _c_next_word();
  79. }
  80.  
  81. void
  82. _cpp_next_word(void) {
  83.     _c_next_word();
  84. }
  85.  
  86. void
  87. _cxx_next_word(void) {
  88.     _c_next_word();
  89. }
  90.  
  91. void
  92. _hpp_next_word(void) {
  93.     _c_next_word();
  94. }
  95.  
  96. void
  97. _hxx_next_word(void) {
  98.     _c_next_word();
  99. }
  100.  
  101. void
  102. _inl_next_word(void) {
  103.     _c_next_word();
  104. }
  105.  
  106. void
  107. _rm_next_word(void) {
  108.     _c_next_word();
  109. }
  110.  
  111. void
  112. _c_prev_word(void) {
  113.     __prev_word();
  114. } /* end _c_next_word() */
  115.  
  116. void
  117. _h_prev_word(void) {
  118.     _c_prev_word();
  119. }
  120.  
  121. void
  122. _cpp_prev_word(void) {
  123.     _c_prev_word();
  124. }
  125.  
  126. void
  127. _cxx_prev_word(void) {
  128.     _c_prev_word();
  129. }
  130.  
  131. void
  132. _hpp_prev_word(void) {
  133.     _c_prev_word();
  134. }
  135.  
  136. void
  137. _hxx_prev_word(void) {
  138.     _c_prev_word();
  139. }
  140.  
  141. void
  142. _inl_prev_word(void) {
  143.     _c_prev_word();
  144. }
  145.  
  146. void
  147. _rm_prev_word(void) {
  148.     _c_prev_word();
  149. }
  150.  
  151.  
  152. void
  153. BufQueryPos(long *l, long *c) {
  154.     if ( l )
  155.         *l = BufQueryLine();
  156.     if ( c )
  157.         *c = BufQueryColumn();
  158. } /* end BufQueryPos() */
  159.  
  160.  
  161. int
  162. AtEOF(void) {
  163.     return BufQueryOffset() == BufQueryFilesize();
  164.  
  165. } /* end AtEOF() */
  166.  
  167.  
  168. /*
  169. **    Template editing
  170. **
  171. ** For a keyword to match it must only have whitespace ahead of it and
  172. **    you must be at the end of the line.
  173. ** If a match is found, the remainder of the statement
  174. ** is filled in and indented automatically.
  175. **
  176. */
  177.  
  178. #if 0
  179. typedef struct template_t    TEMPLATE, *PTEMPLATE;
  180. struct template_t {
  181.     char        *abbrev;            /* what is tested to see if a match exists */
  182.     char        *expansion;        /* what to expand to */
  183.     short        min;                /* need at least this many chars for this template */
  184.     unsigned    flags;            /* special handling flags */
  185. }
  186. #endif
  187.  
  188. /* if you want opening braces on same line as statement set to 1 else set to 0 */
  189. #define BRACES_ON_SAME_LINE    1
  190.  
  191. #if BRACES_ON_SAME_LINE
  192. TEMPLATE c_templates[] = {
  193.     { "if"            , "if ( % )"                    ,    2, 0    },
  194.     { "if{"            , "if ( % ) {\n}"                ,    3, 0    },
  195.     { "els"            , "else"                            ,    2, 0    },
  196.     { "el{"            , "else {\n% \n}"                ,    3, 0    },
  197.     { "ei"            , "else if ( % )"                ,    2, 0    },
  198.     { "ei{"            , "else if ( % ) {\n}"        ,    3, 0    },
  199.     { "else if"        , "else if ( % )"                ,    6, 0    },
  200.     { "else if{"    , "else if ( % ) {\n}"        ,    8, 0    },
  201.     { "while"        , "while ( % )"                ,    2, 0    },
  202.     { "wh{"            , "while ( % ) {\n}"            ,    3, 0    },
  203.     { "for"          , "for ( %; ; )"                ,    2, 0    },
  204.     { "for{"          , "for ( %; ; ) {\n}"        ,    4, 0    },
  205.     { "switch"        , "switch ( % ) {\n}"        ,    2, 0    },
  206.     { "break"        , "break;"                         ,    2, 0    },
  207.     { "case"         , "case :~\b"                    ,    2, 0    },
  208.     { "default"        , "default:"                    ,    2, 0    },
  209.     { "do"            , "do {\n%;\n} while ( );"    ,    2, 0    },
  210.     { "return"        , "return %;"                    ,  2, 0  },
  211.     { "continue"    , "continue;"                    ,  2, 0  },
  212.     { NULL            , NULL                            ,  0, 0  },
  213. };
  214. #else        /* place opening brace on following line */
  215. TEMPLATE c_templates[] = {
  216.     { "if"            , "if ( % )"                    ,    2, 0    },
  217.     { "if{"            , "if ( % )\n{\n}"            ,    3, 0    },
  218.     { "els"            , "else"                            ,    2, 0    },
  219.     { "el{"            , "else\n{\n% \n}"            ,    3, 0    },
  220.     { "ei"            , "else if ( % )"                ,    2, 0    },
  221.     { "ei{"            , "else if ( % )\n{\n}"        ,    3, 0    },
  222.     { "else if"        , "else if ( % )"                ,    6, 0    },
  223.     { "else if{"    , "else if ( % )\n{\n}"        ,    8, 0    },
  224.     { "while"        , "while ( % )"                ,    2, 0    },
  225.     { "wh{"            , "while ( % )\n{\n}"        ,    3, 0    },
  226.     { "for"          , "for ( %; ; )"                ,    2, 0    },
  227.     { "for{"          , "for ( %; ; )\n{\n}"        ,    4, 0    },
  228.     { "switch"        , "switch ( % )\n{\n}"        ,    2, 0    },
  229.     { "break"        , "break;"                         ,    2, 0    },
  230.     { "case"         , "case :~\b"                    ,    2, 0    },
  231.     { "default"        , "default:"                    ,    2, 0    },
  232.     { "do"            , "do\n{\n%;\n} while ( );",    2, 0    },
  233.     { "return"        , "return %;"                    ,  2, 0  },
  234.     { "continue"    , "continue;"                    ,  2, 0  },
  235.     { NULL            , NULL                            ,  0, 0  },
  236. };
  237. #endif
  238.  
  239. void
  240. _expand(PTEMPLATE template) {
  241.     int    expanded = 0;
  242.     long    len;
  243.     int    index;
  244.     int    c;
  245.     char *psz, *pszTrim;
  246.     PTEMPLATE    item = NULL;
  247.     HMARK    hmCursor = 0L;
  248.  
  249.     if ( !AtEOF() && BufQueryChar() != '\n' )    {    /* Are we at the end of the line? */
  250.         if ( KbdQueryBufferKeyboard() == _c_alt_template )    /* expand bound to Tab key */
  251.             slide_in();
  252.         else
  253.             SelfInsert();
  254.         return;
  255.     }
  256.     MarkPushPos();
  257.     PosSOT();
  258.     psz = BufRead();            /* get remainder of line */
  259.     pszTrim = rtrim(psz);
  260.     len = strlen(pszTrim);
  261.     if ( !len )    {
  262.         free(psz);
  263.         MarkPopPos();
  264.         SelfInsert();
  265.         return;
  266.     }
  267.  
  268.     /* try to match one of the templates */
  269.     for ( index = 0; template[index].abbrev; ++index ) {
  270.         if ( len >= template[index].min &&
  271.              !strncmp(template[index].abbrev, pszTrim, len) ) {
  272.             item = &template[index];
  273.             break;
  274.         }
  275.     }
  276.  
  277.     free(psz);
  278.     if ( !item ) {        /* no match */
  279.         MarkPopPos();
  280.         SelfInsert();
  281.         return;
  282.     }
  283.     /* dump saved position */
  284.     MarkPopPos(0);
  285.  
  286.     /* have a template to expand */
  287.     BufDeleteToEOL();
  288.     psz = item->expansion;
  289.     while ( c = *psz++ ) {
  290.         switch ( c ) {
  291.         default:
  292.             BufInsertChar(c);
  293.             break;
  294.         case '\n':
  295.             _c_newline();
  296.             break;
  297.         case '{':
  298.             _c_open();
  299.             break;
  300.         case '}':
  301.             _c_close();
  302.             break;
  303.         case '\b':    /* back-up a character */
  304.             PosPrevChar();
  305.             break;
  306.         case '~':    /* do indentation now */
  307.             c_indenter();
  308.             break;
  309.         case '%':    /* remember cursor position */
  310.             hmCursor = MarkAllocLocal();
  311.             break;
  312.         } /* end switch */
  313.     } /* end while there is more to the expansion */
  314.     c_indenter();
  315.     if ( hmCursor ) {
  316.         MarkGoto(hmCursor);
  317.         MarkFree(hmCursor);
  318.     }
  319. } /* end _expand() */
  320.  
  321.  
  322. void
  323. _c_expand(void) {
  324.     _expand(c_templates);
  325. }
  326.  
  327.  
  328. void
  329. _c_matching_brace(void) {
  330.     char *pszLine;
  331.     char *pszTmp;
  332.  
  333.     MarkPushPos();
  334.     PosSOL();
  335.     pszLine = BufRead();
  336.     MarkPopPos();
  337.     _c_open();
  338.  
  339.     /*
  340.     ** Search current line for:
  341.     **    Line start
  342.     **  or else or do
  343.     **  or typedef or struct followed by optional whitespace followed by optional non-whitespace
  344.     **  or ')' or ':'
  345.     ** followed by optional whitespace and end of line
  346.     */
  347.     if ( SrchString("((else)|(do))|((typedef)|(struct)[ \t]*[^ \t\n]*)|[):]|^[ \t]*&", pszLine, NULL, -1) >= 0 ) {
  348.         pszTmp = BufRead();
  349.         if ( !*rtrim(ltrim(pszTmp)) ) {    /* if no text following */
  350.             _c_newline();
  351.             _c_close();
  352.         }
  353.         free(pszTmp);
  354.     }
  355.     free(pszLine);
  356. } /* end _c_matching_brace() */
  357.  
  358.  
  359. void
  360. just_brace (void) {
  361.     BufInsertChar('{');
  362. }
  363.  
  364. void
  365. just_cbrace (void) {
  366.     BufInsertChar('}');
  367. }
  368.  
  369. void
  370. just_space (void) {
  371.     BufInsertChar(' ');
  372. }
  373.  
  374.  
  375. /*
  376. **    _c_init
  377. **
  378. **     Sets up the language specific features for 'C' and related language
  379. **     files.
  380. */
  381. _c_init(void) {
  382.     /*
  383.     ** Make the C keyboard bindings override the regular keyboard
  384.     **    for this buffer.
  385.     */
  386.     switch ( IndentStyle ) {
  387.     case 0:    return;
  388.     case 1:    KbdSetBufferKeyboard(_r_keymap);            break;
  389.     case 2:    KbdSetBufferKeyboard(_c_smart);            break;
  390.     case 3:    KbdSetBufferKeyboard(_c_template);        break;
  391.     case 4:    KbdSetBufferKeyboard(_c_alt_template);    break;
  392.     }
  393. } /* end _c_init() */
  394.  
  395.  
  396. _h_init(void) {
  397.     _c_init();
  398. }
  399.  
  400. _cpp_init(void) {    /* C++ source files */
  401.     _c_init();
  402. }
  403.  
  404. _cxx_init(void) {    /* C++ source files */
  405.     _c_init();
  406. }
  407.  
  408. _hpp_init(void) {    /* C++ header files */
  409.     _c_init();
  410. }
  411.  
  412. _hxx_init(void) {    /* C++ header files */
  413.     _c_init();
  414. }
  415.  
  416. _inl_init(void) {    /* C++ inline files */
  417.     _c_init();
  418. }
  419.  
  420. _rm_init(void) { /* RimStar macro files */
  421.     _c_init();
  422. }
  423.  
  424. _asm_init(void) {    /* assembler files */
  425.     BufSetTabs("9");
  426.     KbdSetBufferKeyboard(_r_keymap);    /* enable regular indenting */
  427. }
  428.  
  429. void
  430. _init(void) {
  431.  
  432.     LibAutoload("slide", "slide_in", "slide_out");
  433.     LibAutoload("c_smart",  "_c_newline", "_c_newline_break", "_c_indent", "_c_close", "_c_open",
  434.                                     "_c_indent_function", "_c_start_of_func",
  435.                                     "_c_end_of_func", "_c_forward_cexp",
  436.                                     "_c_backward_cexp", "c_indenter");
  437.  
  438.     /*
  439.     **    Create keyboards for the keys we need to remap
  440.     **    These keyboards are used as Buffer keyboards which
  441.     **    over-ride and/or supplement the current keyboard
  442.     **    when that buffer is current.
  443.     */
  444.  
  445.     /* Create regular indenting keyboard ( -Is1 ) */
  446.     KbdPush();
  447.     KbdBind("Enter",        "BufNewlineIndent");
  448.     KbdBind("Tab",            "slide_in");
  449.     KbdBind("Shift+Tab",    "slide_out");
  450.     _r_keymap = KbdPop();
  451.  
  452.     /* Create smart indenting keyboard ( -Is2 ) */
  453.     KbdPush();
  454.     KbdBind("Enter",              "_c_newline_break");
  455.     KbdBind("Kp_Enter",        "_c_newline");
  456.     KbdBind("Shift+Enter",    "BufNewlineIndent");
  457.     KbdBind("Tab",                "_c_indent");
  458.     KbdBind("Shift+Tab",     "slide_out");
  459.     KbdBind("Shift + {",     "_c_open");
  460.     KbdBind("Shift + }",     "_c_close");
  461.     KbdBind("Ctrl+Alt+A",    "_c_start_of_func");
  462.     KbdBind("Ctrl+Alt+E",    "_c_end_of_func");
  463.     KbdBind("Ctrl+Alt+Q",    "_c_indent_function");
  464.     KbdBind("Ctrl+Alt+F",    "_c_forward_cexp");
  465.     KbdBind("Ctrl+Alt+B",    "_c_backward_cexp");
  466.     KbdBind("Ctrl+{",             "just_brace");
  467.     KbdBind("Ctrl+}",             "just_cbrace");
  468.     _c_smart = KbdPop();
  469.  
  470.     /* Create template editing keyboard ( -Is3 ) */
  471.     KbdPush();
  472.     KbdBind("Enter",              "_c_newline_break");
  473.     KbdBind("Kp_Enter",        "_c_newline");
  474.     KbdBind("Shift+Enter",    "BufNewlineIndent");
  475.     KbdBind("Tab",                "_c_indent");
  476.     KbdBind("Shift+Tab",     "slide_out");
  477.     KbdBind("Space",              "_c_expand");
  478.     KbdBind("Shift + {",     "_c_matching_brace");
  479.     KbdBind("Shift + }",     "_c_close");
  480.     KbdBind("Ctrl+Alt+A",    "_c_start_of_func");
  481.     KbdBind("Ctrl+Alt+E",    "_c_end_of_func");
  482.     KbdBind("Ctrl+Alt+Q",    "_c_indent_function");
  483.     KbdBind("Ctrl+Alt+F",    "_c_forward_cexp");
  484.     KbdBind("Ctrl+Alt+B",    "_c_backward_cexp");
  485.     KbdBind("Ctrl+{",             "just_brace");
  486.     KbdBind("Ctrl+}",             "just_cbrace");
  487.     KbdBind("Ctrl+Space",    "just_space");
  488.     _c_template = KbdPop();
  489.  
  490.     /* Create alternate template editing keyboard ( -Is4 ) */
  491.     KbdPush();
  492.     KbdBind("Enter",              "_c_newline_break");
  493.     KbdBind("Kp_Enter",        "_c_newline");
  494.     KbdBind("Shift+Enter",    "BufNewlineIndent");
  495.     KbdBind("Tab",                "_c_expand");
  496.     KbdBind("Shift+Tab",        "slide_out");
  497.     KbdBind("Shift + {",     "_c_open");
  498.     KbdBind("Shift + }",     "_c_close");
  499.     KbdBind("Ctrl+Alt+A",    "_c_start_of_func");
  500.     KbdBind("Ctrl+Alt+E",    "_c_end_of_func");
  501.     KbdBind("Ctrl+Alt+Q",    "_c_indent_function");
  502.     KbdBind("Ctrl+Alt+F",    "_c_forward_cexp");
  503.     KbdBind("Ctrl+Alt+B",    "_c_backward_cexp");
  504.     KbdBind("Ctrl+{",            "just_brace");
  505.     KbdBind("Ctrl+}",            "just_cbrace");
  506.     KbdBind("Ctrl+Space",    "just_space");
  507.     _c_alt_template = KbdPop();
  508.  
  509. } /* end _init() */
  510.  
  511.  
  512.  
  513. /*
  514. ** End module: c_indent.rm
  515. */
  516.