home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / memacs400_src.lzh / MEMACS400 / SRC / abbrev.c next >
Text File  |  1996-04-25  |  10KB  |  441 lines

  1. /*    Code to handle Abbreviation Expansions
  2.     for MicroEMACS 4.00
  3.     (C)Copyright 1995 by Daniel M. Lawrence
  4. */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "eproto.h"
  9. #include    "edef.h"
  10. #include    "elang.h"
  11.  
  12. VOID PASCAL NEAR ab_save(c)
  13.  
  14. char c;        /* character to add to current word buffer */
  15.  
  16. {
  17.     char *s;    /* ptr to cycle chars */
  18.  
  19.     /* only in ABBREV mode */
  20.     if ((curbp->b_mode & MDABBR) == 0)
  21.         return;
  22.  
  23.     /* is the buffer full? */
  24.     if (ab_pos == ab_end) {
  25.         /* shift all the letters down one */
  26.         s = ab_word;
  27.         while (s < ab_end) {
  28.             *s = *(s+1);
  29.             ++s;
  30.         }
  31.         ab_pos--;
  32.     }
  33.  
  34.     /* add the character */
  35.     *ab_pos++ = c;
  36.     *ab_pos = 0;
  37. }
  38.  
  39. VOID PASCAL NEAR ab_expand()
  40.  
  41. {
  42.     char *exp;    /* expansion of current symbol */
  43.     char c;        /* current character to insert */
  44.     
  45.     /* only in ABBREV mode, never in VIEW mode */
  46.     if ((curbp->b_mode & MDABBR) == 0 ||
  47.         (curbp->b_mode & MDVIEW) == MDVIEW)
  48.         return;
  49.  
  50.     /* is the current buffer a symbol in the abbreviation table? */
  51.     if ((exp = ab_lookup(ab_word)) != NULL) {
  52.  
  53.         /* backwards delete the symbol */
  54.         ldelete(-((long)strlen(ab_word)), FALSE);
  55.  
  56.         /* and insert its expansion */
  57.         while (*exp) {
  58.  
  59.             c = *exp++;
  60.  
  61.             /*
  62.              * If a space was typed, fill column is defined, the
  63.              * argument is non-negative, wrap mode is enabled, and
  64.              * we are now past fill column, perform word wrap.
  65.              */
  66.             if (c == ' ' && (curwp->w_bufp->b_mode & MDWRAP) &&
  67.                 fillcol > 0 &&
  68.                 getccol(FALSE) > fillcol)
  69.                 execkey(&wraphook, FALSE, 1);
  70.  
  71.             linsert(1, c);
  72.         }
  73.  
  74.         /* ring the bell */
  75.         if (ab_bell)
  76.             TTbeep();
  77.     }
  78.  
  79.     /* reset the word buffer */
  80.     ab_pos = ab_word;
  81.     *ab_pos = 0;
  82. }
  83.  
  84. /* add a new abbreviation */
  85.  
  86. int PASCAL NEAR add_abbrev(f, n)
  87.  
  88. int f, n;    /* numeric flag and argument */
  89.  
  90. {
  91.     register int status;    /* status return */
  92.     char sym_name[MAXSYM+1];/* name of symbol to fetch */
  93.     char value[NSTRING];    /* value to set symbol to */
  94.  
  95.     /* first get the symbol name */
  96.     status = mlreply(TEXT231, sym_name, MAXSYM + 1);
  97. /*             "Abbreviation to set: " */
  98.     if (status != TRUE)
  99.         return(status);
  100.  
  101.     /* get the value for that expansion */
  102.     if (f == TRUE)
  103.         strcpy(value, int_asc(n));
  104.     else {
  105.         status = mlreply(TEXT53, &value[0], NSTRING);
  106. /*                 "Value: " */
  107.         if (status == ABORT)
  108.             return(status);
  109.     }
  110.  
  111.     /* and add the abbreviation to the list */
  112.     return(ab_insert(sym_name, value));
  113. }
  114.  
  115. /* Delete a single abbreviation */
  116.  
  117. int PASCAL NEAR del_abbrev(f, n)
  118.  
  119. int f, n;    /* numeric flag and argument */
  120.  
  121. {
  122.     register int status;    /* status return */
  123.     char sym_name[MAXSYM+1];/* name of symbol to fetch */
  124.  
  125.     /* first get the symbol name */
  126.     status = mlreply(TEXT232, sym_name, MAXSYM + 1);
  127. /*             "Abbreviation to delete: " */
  128.     if (status != TRUE)
  129.         return(status);
  130.  
  131.     /* and yank the abbreviation to the list */
  132.     return(ab_delete(sym_name));
  133. }
  134.  
  135. /* Kill all abbreviations */
  136.  
  137. int PASCAL NEAR kill_abbrevs(f, n)
  138.  
  139. int f, n;    /* numeric flag and argument */
  140.  
  141. {
  142.     /* kill them! */
  143.     return(ab_clean());
  144. }
  145.  
  146. int PASCAL NEAR desc_abbrevs(f, n)
  147.  
  148. int f, n;    /* numeric flag and argument */
  149.  
  150. {
  151.     register BUFFER *abbbuf;/* buffer to put abbreviation list into */
  152.     register ABBREV *cur_node;/* ptr to current abbreviation */
  153.     char outseq[NSTRING];    /* output buffer for keystroke sequence */
  154.  
  155.     /* and get a buffer for it */
  156.     abbbuf = bfind(TEXT234, TRUE, BFINVS);
  157. /*           "Abbreviation list" */
  158.     if (abbbuf == NULL || bclear(abbbuf) == FALSE) {
  159.         mlwrite(TEXT235);
  160. /*            "Can not display abbreviation list" */
  161.         return(FALSE);
  162.     }
  163.  
  164.     /* let us know this is in progress */
  165.     mlwrite(TEXT233);
  166. /*        "[Building Abbreviation list]" */
  167.  
  168.     /* build the abbreviation list */
  169.     cur_node = ab_head;
  170.     while (cur_node != (ABBREV *)NULL) {
  171.  
  172.         /* add in the abbreviation symbol name */
  173.         strcpy(outseq, cur_node->ab_sym);
  174.         pad(outseq, 20);
  175.             
  176.         /* add it's expansion */
  177.         strncat(outseq, cur_node->ab_exp, NSTRING - 20);
  178.         outseq[NSTRING - 1] = 0;
  179.  
  180.         /* and add it as a line into the buffer */
  181.         if (addline(abbbuf, outseq) != TRUE)
  182.             return(FALSE);
  183.  
  184.         cur_node = cur_node->ab_next;
  185.     }
  186.  
  187.     /* display the list */
  188.     wpopup(abbbuf);
  189.     mlerase();    /* clear the mode line */
  190.     return(TRUE);
  191. }
  192.  
  193. /* insert a list of all the current abbreviations into the current buffer */
  194.  
  195. int PASCAL NEAR ins_abbrevs(f, n)
  196.  
  197. int f, n;    /* numeric flag and argument */
  198.  
  199. {
  200.     register ABBREV *cur_node;/* ptr to current abbreviation */
  201.  
  202.     /* insert the abbreviation list in the current buffer */
  203.     cur_node = ab_head;
  204.     while (cur_node != (ABBREV *)NULL) {
  205.  
  206.         /* insert the abbreviation symbol as a line */
  207.         if (addline(curbp, cur_node->ab_sym) != TRUE)
  208.             return(FALSE);
  209.             
  210.         /* now a line with the expansion */
  211.         if (addline(curbp, cur_node->ab_exp) != TRUE)
  212.             return(FALSE);
  213.  
  214.         cur_node = cur_node->ab_next;
  215.     }
  216.  
  217.     return(TRUE);
  218. }
  219.  
  220. int PASCAL NEAR def_abbrevs(f, n)
  221.  
  222. int f,n;    /* prefix flag and argument */
  223.  
  224. {
  225.     register BUFFER *bp;    /* ptr to buffer to dump */
  226.     register LINE *lp;    /* ptr to current line in our buffer */
  227.     register llength;    /* length of the current line being examined */
  228.     char cur_sym[MAXSYM+1];    /* current symbol being defined */
  229.     char cur_exp[NSTRING];    /* current expansion */
  230.     
  231.     /* get the buffer to load abbreviations from */
  232.     bp = getdefb();
  233.     bp = getcbuf(TEXT236, bp ? bp->b_bname : mainbuf, TRUE);
  234. /*             "Define Abbreviations in buffer" */
  235.     if (bp == NULL)
  236.         return(ABORT);
  237.  
  238.     /* step throught the buffer */
  239.     lp = lforw(bp->b_linep);
  240.     while (lp != bp->b_linep) {
  241.  
  242.         /* get a symbol name */
  243.         llength = lused(lp);
  244.         if (llength > MAXSYM)
  245.             llength = MAXSYM;
  246.         strncpy(cur_sym, ltext(lp), llength);
  247.         cur_sym[llength] = 0;
  248.  
  249.         /* advance to the next line in the buffer */
  250.         lp = lforw(lp);
  251.         if (lp == bp->b_linep)
  252.             break;
  253.  
  254.         /* and an expansion for that symbol */
  255.         llength = lused(lp);
  256.         if (llength > MAXSYM)
  257.             llength = MAXSYM;
  258.         strncpy(cur_exp, ltext(lp), llength);
  259.         cur_exp[llength] = 0;
  260.  
  261.         /* add it to the current abbreviation list */
  262.         ab_insert(cur_sym, cur_exp);
  263.  
  264.         /* on to the next pair */
  265.         lp = lforw(lp);
  266.     }
  267. }
  268.  
  269. VOID PASCAL NEAR ab_init()
  270.  
  271. {
  272.     ab_head = (ABBREV *)NULL; /* abbreviation list empty */
  273.      ab_bell = FALSE;    /* no ringing please! */
  274.     ab_cap = FALSE;        /* don't match capatilization on expansion */
  275.     ab_quick = FALSE;    /* no aggressive expansion */
  276.     ab_pos = ab_word;    /* no word accumulated yet */
  277.     ab_end = &ab_word[NSTRING - 1];    /* ptr to detect end of this buffer */
  278. }
  279.  
  280. /* ab_insert:    Insert a <sym> in the abbreviation list defined as
  281.         <expansion>
  282. */
  283.  
  284. int PASCAL NEAR ab_insert(sym, expansion)
  285.  
  286. char *sym;        /* symbol to expand */
  287. char *expansion;    /* string to expand to */
  288.  
  289. {
  290.     ABBREV *new_node;    /* pointer to the newly allocated node */
  291.     ABBREV *cur_node;    /* pointer to travel down list */
  292.  
  293.     /* nothing longer than MAXSYM please */
  294.     if (strlen(sym) > MAXSYM)
  295.         sym[MAXSYM + 1] = 0;
  296.  
  297.     /* is this already defined? */
  298.     if (ab_lookup(sym) != NULL)
  299.         ab_delete(sym);
  300.  
  301.     /* allocate a new node to hold abbreviation */
  302.     new_node = (ABBREV *)room(sizeof(ABBREV)+strlen(expansion)+1);
  303.     if (new_node == NULL)
  304.         return(FALSE);
  305.  
  306.     /* copy data to that node */
  307.     strcpy(new_node->ab_sym, sym);
  308.     strcpy(new_node->ab_exp, expansion);
  309.  
  310.     /* do we have an empty list */
  311.     if (ab_head == NULL) {
  312.  
  313.         ab_head = new_node;
  314.         new_node->ab_next = NULL;
  315.  
  316.     } else {
  317.  
  318.         /* does our new node go before the first */
  319.         if (strcmp(sym, ab_head->ab_sym) < 0) {
  320.  
  321.             /* insert the node before the first node */
  322.             new_node->ab_next = ab_head;
  323.             ab_head = new_node;
  324.  
  325.         } else {
  326.  
  327.             /* search for the right place to insert */
  328.             cur_node = ab_head;
  329.             while (cur_node->ab_next != NULL) {
  330.  
  331.                 if (strcmp(sym, cur_node->ab_next->ab_sym) > 0) {
  332.  
  333.                     /* insert after cur_node */
  334.                     new_node->ab_next = cur_node->ab_next;
  335.                     cur_node->ab_next = new_node;
  336.                     return(TRUE);
  337.                 }
  338.  
  339.                 /* step to the next node */
  340.                 cur_node = cur_node->ab_next;
  341.             }
  342.  
  343.             /* insert after the last node */
  344.             cur_node->ab_next = new_node;
  345.             new_node->ab_next = NULL;
  346.         }
  347.     }
  348.  
  349.     return(TRUE);
  350. }
  351.  
  352. /* ab_lookup:    look up and return the expansion of <sym>.
  353.         Return a NULL if it is not in the list
  354. */
  355.  
  356. char *PASCAL NEAR ab_lookup(sym)
  357.  
  358. char *sym;    /* name of the symbol to look up */
  359.  
  360. {
  361.  
  362.     ABBREV *cur_node;    /* ptr to look through list */
  363.  
  364.     /* starting at the head, step through the list */
  365.     cur_node = ab_head;
  366.     while (cur_node != NULL) {
  367.  
  368.         /* if there is a match, return the expansion */
  369.         if (strcmp(sym,cur_node->ab_sym) == 0) {
  370.             return(cur_node->ab_exp);
  371.         }
  372.         cur_node=cur_node->ab_next;
  373.     }
  374.  
  375.     /* at the end, return NULL */
  376.     return(NULL);
  377. }
  378.  
  379. /* ab_delete:    Delete <sym> from the abbreviation list */
  380.  
  381. int PASCAL NEAR ab_delete(sym)
  382.  
  383. char *sym;
  384.  
  385. {
  386.  
  387.     ABBREV *cur_node,*previous;    /* ptr to look through list */
  388.  
  389.     /* start at beginning */
  390.     previous=NULL;
  391.     cur_node=ab_head;
  392.  
  393.     /* step through the list */
  394.     while(cur_node!=NULL) {
  395.  
  396.         /* if there is a match, delete the node */
  397.         if (previous == NULL && strcmp(sym,cur_node->ab_sym) == 0) {
  398.  
  399.             /*important: resets our head pointer*/
  400.             ab_head=cur_node->ab_next;
  401.             free(cur_node);
  402.             return(TRUE);
  403.  
  404.         } else if (strcmp(sym,cur_node->ab_sym) == 0
  405.                 && cur_node != NULL) {
  406.             previous->ab_next=NULL;            
  407.             free(cur_node);
  408.             return(TRUE);
  409.         }
  410.  
  411.         /*makes sure our previous pointer steps with cur_node*/
  412.         previous = cur_node;
  413.         cur_node = cur_node->ab_next;
  414.     }
  415.  
  416.     /* at the end, no match to delete */
  417.     return(FALSE);
  418. }
  419.  
  420. int PASCAL NEAR ab_clean()
  421.  
  422. {
  423.  
  424.     ABBREV *cur_node;    /* ptr to look through list */
  425.     ABBREV *next;        /* ptr to next abbreviation */
  426.  
  427.     /* start at the beginning, */
  428.     cur_node = ab_head;
  429.  
  430.     /* cycle through the list */
  431.     while (cur_node != (ABBREV *)NULL) {
  432.         next = cur_node->ab_next;
  433.         free(cur_node);
  434.         cur_node = next;
  435.     }
  436.  
  437.     /* and re-init the list */
  438.     ab_head = (ABBREV *)NULL;
  439.     return(TRUE);
  440. }
  441.