home *** CD-ROM | disk | FTP | other *** search
/ Best Objectech Shareware Selections / UNTITLED.iso / boss / word / text / 024 / macro.c < prev    next >
C/C++ Source or Header  |  1993-06-04  |  26KB  |  739 lines

  1. /*
  2.  * The "macro" routines in TDE are not really macro routines in the classical
  3.  * sense.  In TDE, "macros" are just recordings of key sequences.  But,
  4.  * actually, I find the ability to record and playback keystrokes generally
  5.  * more useful than writing a macro.  Being that I'm so stupid, it takes me
  6.  * half the morning to write and half the afternoon to debug a simple classical
  7.  * macro.  For most of my routine, little jobs, I find it more convenient
  8.  * to record my keystrokes and playback those keystrokes at appropriate places
  9.  * in a file.  It just seems easier for me to "teach" the editor what to do
  10.  * rather than "instruct" the editor what to do.
  11.  *
  12.  * New editor name:  TDE, the Thomson-Davis Editor.
  13.  * Author:           Frank Davis
  14.  * Date:             June 5, 1991, version 1.0
  15.  * Date:             July 29, 1991, version 1.1
  16.  * Date:             October 5, 1991, version 1.2
  17.  * Date:             January 20, 1992, version 1.3
  18.  * Date:             February 17, 1992, version 1.4
  19.  * Date:             April 1, 1992, version 1.5
  20.  * Date:             June 5, 1992, version 2.0
  21.  * Date:             October 31, 1992, version 2.1
  22.  * Date:             April 1, 1993, version 2.2
  23.  * Date:             June 5, 1993, version 3.0
  24.  *
  25.  * This modification of Douglas Thomson's code is released into the
  26.  * public domain, Frank Davis.  You may distribute it freely.
  27.  */
  28.  
  29.  
  30. #include "tdestr.h"             /* tde types */
  31. #include "common.h"
  32. #include "define.h"
  33. #include "tdefunc.h"
  34.  
  35.  
  36. /*
  37.  *              keystroke record functions
  38.  */
  39.  
  40. /*
  41.  * Name:    record_on_off
  42.  * Purpose: save keystrokes in keystroke buffer
  43.  * Date:    April 1, 1992
  44.  * Passed:  window:  pointer to current window
  45.  * Notes:   -1 in .next field indicates the end of a recording
  46.  *          -1 in .key field indicates the initial, unassigned macro key
  47.  *          STROKE_LIMIT+1 in .next field indicates an unused space.
  48.  */
  49. int  record_on_off( WINDOW *window )
  50. {
  51. register int next;
  52. int  prev;
  53. int  line;
  54. int  key;
  55. int  func;
  56. char line_buff[(MAX_COLS+2)*2]; /* buffer for char and attribute  */
  57.  
  58.    mode.record = !mode.record;
  59.    if (mode.record == TRUE) {
  60.       line = window->bottom_line;
  61.       show_avail_strokes( );
  62.       save_screen_line( 0, line, line_buff );
  63.       /*
  64.        * press key that will play back recording
  65.        */
  66.       set_prompt( main11, line );
  67.  
  68.       /*
  69.        * get the candidate macro key and look up the function assigned to it.
  70.        */
  71.       key = getkey( );
  72.       func = getfunc( key );
  73.  
  74.       /*
  75.        * the key must be an unused, recognized function key or a function
  76.        *  key assigned to a previously defined macro.  we also need room
  77.        *  in the macro structure.
  78.        */
  79.       if (key <= 256 || (func != 0 && func != PlayBack)) {
  80.          /*
  81.           * cannot assign a recording to this key
  82.           */
  83.          error( WARNING, line, main12 );
  84.          mode.record = FALSE;
  85.       } else if (g_status.stroke_count == 0) {
  86.          /*
  87.           * no more room in recording buffer
  88.           */
  89.          error( WARNING, line, main13 );
  90.          mode.record = FALSE;
  91.       } else {
  92.  
  93.          /*
  94.           * everything is everything so far, just check for a prev macro
  95.           */
  96.          prev = OK;
  97.          if (func == PlayBack) {
  98.             /*
  99.              * overwrite recording (y/n)?
  100.              */
  101.             set_prompt( main14, line );
  102.             if (get_yn( ) == A_NO) {
  103.                prev = ERROR;
  104.                mode.record = FALSE;
  105.             }
  106.          }
  107.          if (prev == OK) {
  108.             g_status.recording_key = key;
  109.             next = macro.first_stroke[key-256];
  110.  
  111.             /*
  112.              * if key has already been assigned to a macro, clear macro def.
  113.              */
  114.             if (next != STROKE_LIMIT+1) {
  115.                do {
  116.                   prev = next;
  117.                   next = macro.strokes[next].next;
  118.                   macro.strokes[prev].key  = MAX_KEYS+1;
  119.                   macro.strokes[prev].next = STROKE_LIMIT+1;
  120.                   ++g_status.stroke_count;
  121.                } while (next != -1);
  122.                show_avail_strokes( );
  123.             }
  124.  
  125.             /*
  126.              * find the first open space and initialize
  127.              */
  128.             for (next=0; macro.strokes[next].next != STROKE_LIMIT+1;)
  129.                next++;
  130.             macro.first_stroke[key-256] = next;
  131.             macro.strokes[next].key  = -1;
  132.             macro.strokes[next].next = -1;
  133.             key_func.key[key-256] = PlayBack;
  134.             /*
  135.              * recording
  136.              */
  137.             s_output( main15, g_display.mode_line, 22,
  138.                       g_display.mode_color | 0x80 );
  139.          }
  140.       }
  141.       restore_screen_line( 0, line, line_buff );
  142.    }
  143.  
  144.    /*
  145.     * the flashing "Recording" and the stroke count write over the modes.
  146.     *  when we get thru defining a macro, redisplay the modes.
  147.     */
  148.    if (mode.record == FALSE) {
  149.       memset( line_buff, ' ', 36 );
  150.       line_buff[36] = '\0';
  151.       s_output( line_buff, g_display.mode_line, 22, g_display.mode_color );
  152.       show_tab_modes( );
  153.       show_indent_mode( );
  154.       show_sync_mode( );
  155.       show_search_case( );
  156.       show_wordwrap_mode( );
  157.  
  158.       /*
  159.        * let's look at the macro.  if the first .key of the macro is
  160.        *  still -1, which is the initial unassigned key in a macro, reset
  161.        *  the macro so other keys may be assigned to this node.
  162.        */
  163.       key = g_status.recording_key;
  164.       if (key != 0) {
  165.          next = macro.first_stroke[key-256];
  166.          if (macro.strokes[next].key == -1) {
  167.             macro.strokes[next].key  = MAX_KEYS+1;
  168.             macro.strokes[next].next = STROKE_LIMIT+1;
  169.             macro.first_stroke[key-256] = STROKE_LIMIT+1;
  170.             if (getfunc( key ) == PlayBack)
  171.                key_func.key[key-256] = 0;
  172.          }
  173.       }
  174.       g_status.recording_key = 0;
  175.    }
  176.    return( OK );
  177. }
  178.  
  179.  
  180. /*
  181.  * Name:    record_keys
  182.  * Purpose: save keystrokes in keystroke buffer
  183.  * Date:    April 1, 1992
  184.  * Passed:  line: line to display prompts
  185.  * Notes:   -1 in .next field indicates the end of a recording
  186.  *          STROKE_LIMIT+1 in .next field indicates an unused space.
  187.  */
  188. void record_keys( int line )
  189. {
  190. register int next;
  191. register int prev;
  192. int  key;
  193. int  func;
  194.  
  195.    if (mode.record == TRUE) {
  196.       if (g_status.stroke_count == 0)
  197.          /*
  198.           * no more room in recording buffer
  199.           */
  200.          error( WARNING, line, main13 );
  201.       else {
  202.          key = g_status.key_pressed;
  203.          func = getfunc( key );
  204.          if (func != RecordMacro && func != SaveMacro && func != LoadMacro &&
  205.              func != ClearAllMacros) {
  206.  
  207.             /*
  208.              * a -1 in the next field marks the end of the keystroke recording.
  209.              */
  210.             next = macro.first_stroke[g_status.recording_key - 256];
  211.             if (macro.strokes[next].next != STROKE_LIMIT+1) {
  212.                while (macro.strokes[next].next != -1)
  213.                   next = macro.strokes[next].next;
  214.             }
  215.             prev = next;
  216.  
  217.             /*
  218.              * now find an open space to record the current key.
  219.              */
  220.             if (macro.strokes[next].key != -1) {
  221.                for (; next < STROKE_LIMIT &&
  222.                             macro.strokes[next].next != STROKE_LIMIT+1;)
  223.                   next++;
  224.                if (next == STROKE_LIMIT) {
  225.                   for (next=0; next < prev &&
  226.                                macro.strokes[next].next != STROKE_LIMIT+1;)
  227.                      next++;
  228.                }
  229.             }
  230.             if (next == prev && macro.strokes[prev].key != -1)
  231.                /*
  232.                 * no more room in recording buffer
  233.                 */
  234.                error( WARNING, line, main13 );
  235.             else {
  236.             /*
  237.              * next == prev if we are recording the initial macro node.
  238.              */
  239.                macro.strokes[prev].next = next;
  240.                macro.strokes[next].next = -1;
  241.                m