home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / jove / part01 / abbrev.c next >
Encoding:
C/C++ Source or Header  |  1987-02-02  |  5.6 KB  |  289 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  3.  * provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is *
  5.  * included in all the files.                                           *
  6.  ************************************************************************/
  7.  
  8. #include "jove.h"
  9.  
  10. #ifdef ABBREV
  11.  
  12. #include "io.h"
  13. #include "ctype.h"
  14.  
  15. #define HASHSIZE    20
  16.  
  17. struct abbrev {
  18.     unsigned int    a_hash;
  19.     char    *a_abbrev,
  20.         *a_phrase;
  21.     struct abbrev    *a_next;
  22.     data_obj    *a_cmdhook;
  23. };
  24.  
  25. #define GLOBAL    NMAJORS
  26. static struct abbrev    *A_tables[NMAJORS + 1][HASHSIZE] = {0};
  27.  
  28. int AutoCaseAbbrev = 1;
  29.  
  30. static unsigned int
  31. hash(a)
  32. register char    *a;
  33. {
  34.     register unsigned int    hashval = 0;
  35.     register int    c;
  36.  
  37.     while (c = *a++)
  38.         hashval = (hashval << 2) + c;
  39.  
  40.     return hashval;
  41. }
  42.  
  43. static
  44. def_abbrev(table)
  45. struct abbrev    *table[HASHSIZE];
  46. {
  47.     char    abbrev[100],
  48.         phrase[100];
  49.  
  50.     strcpy(abbrev, ask((char *) 0, "abbrev: "));
  51.     strcpy(phrase, ask((char *) 0, "abbrev: %s phrase: ", abbrev));
  52.     define(table, abbrev, phrase);
  53. }
  54.  
  55. static struct abbrev *
  56. lookup(table, abbrev)
  57. register struct abbrev    *table[HASHSIZE];
  58. register char    *abbrev;
  59. {
  60.     register struct abbrev    *ap;
  61.     unsigned int    h;
  62.  
  63.     h = hash(abbrev);
  64.     for (ap = table[h % HASHSIZE]; ap; ap = ap->a_next)
  65.         if (ap->a_hash == h && strcmp(ap->a_abbrev, abbrev) == 0)
  66.             break;
  67.     return ap;
  68. }
  69.  
  70. static
  71. define(table, abbrev, phrase)
  72. register struct abbrev    *table[HASHSIZE];
  73. char    *abbrev,
  74.     *phrase;
  75. {
  76.     register struct abbrev    *ap;
  77.  
  78.     ap = lookup(table, abbrev);
  79.     if (ap == 0) {
  80.         register unsigned int    h = hash(abbrev);
  81.  
  82.         ap = (struct abbrev *) emalloc(sizeof *ap);
  83.         ap->a_hash = h;
  84.         ap->a_abbrev = copystr(abbrev);
  85.         h %= HASHSIZE;
  86.         ap->a_next = table[h];
  87.         ap->a_cmdhook = 0;
  88.         table[h] = ap;
  89.     } else
  90.         free(ap->a_phrase);
  91.     ap->a_phrase = copystr(phrase);
  92. }
  93.  
  94. AbbrevExpand()
  95. {
  96.     Bufpos    point;
  97.     char    wordbuf[100];
  98.     register char    *wp = wordbuf,
  99.             *cp;
  100.     register int    c;
  101.     int    UC_count = 0;
  102.     struct abbrev    *ap;
  103.  
  104.     DOTsave(&point);
  105.     exp = 1;
  106.     WITH_TABLE(curbuf->b_major)
  107.     BackWord();
  108.     while (curchar < point.p_char && ismword(c = linebuf[curchar])) {
  109.         if (AutoCaseAbbrev) {
  110.             if (isupper(c)) {
  111.                 UC_count++;
  112.                 c = tolower(c);
  113.             }
  114.         }
  115.  
  116.         *wp++ = c;
  117.         curchar++;
  118.     }
  119.     *wp = '\0';
  120.     END_TABLE();
  121.  
  122.     if ((ap = lookup(A_tables[curbuf->b_major], wordbuf)) == 0 &&
  123.         (ap = lookup(A_tables[GLOBAL], wordbuf)) == 0) {
  124.         SetDot(&point);
  125.         return;
  126.     }
  127.     DoTimes(DelPChar(), (wp - wordbuf));
  128.  
  129.     for (cp = ap->a_phrase; c = *cp; ) {
  130.         if (AutoCaseAbbrev) {
  131.             Insert(islower(c) && UC_count &&
  132.                    (cp == ap->a_phrase || (UC_count > 1 && (*(cp - 1) == ' '))) ?
  133.                 toupper(c) : c);
  134.         }
  135.         else {
  136.             Insert(c);
  137.         }
  138.         cp++;
  139.     }
  140.  
  141.     if (ap->a_cmdhook != 0)
  142.         ExecCmd(ap->a_cmdhook);
  143. }
  144.  
  145. static char    *mode_names[NMAJORS + 1] = {
  146.     "Fundamental",
  147.     "Text Mode",
  148.     "C Mode",
  149. #ifdef LISP
  150.     "Lisp Mode",
  151. #endif
  152.     "Global"
  153. };
  154.  
  155. static
  156. save_abbrevs(file)
  157. char    *file;
  158. {
  159.     File    *fp;
  160.     struct abbrev    *ap,
  161.             **tp;
  162.     char    buf[LBSIZE];
  163.     int    i,
  164.         count = 0;
  165.  
  166.     fp = open_file(file, buf, F_WRITE, COMPLAIN, QUIET);
  167.     for (i = 0; i <= GLOBAL; i++) {
  168.         fprintf(fp, "------%s abbrevs------\n", mode_names[i]);
  169.         for (tp = A_tables[i]; tp < &A_tables[i][HASHSIZE]; tp++)
  170.             for (ap = *tp; ap; ap = ap->a_next) {
  171.                 fprintf(fp, "%s:%s\n",
  172.                     ap->a_abbrev,
  173.                     ap->a_phrase);
  174.                 count++;
  175.             }
  176.     }
  177.     f_close(fp);
  178.     add_mess(" %d written.", count);
  179. }
  180.  
  181. static
  182. rest_abbrevs(file)
  183. char    *file;
  184. {
  185.     int    eof = 0,
  186.         mode = -1,    /* Will be ++'d immediately */
  187.         lnum = 0;
  188.     char    *phrase_p;
  189.     File    *fp;
  190.     char    buf[LBSIZE];
  191.  
  192.     fp = open_file(file, buf, F_READ, COMPLAIN, QUIET);
  193.     while (mode <= GLOBAL) {
  194.         eof = f_gets(fp, genbuf, LBSIZE);
  195.         if (eof || genbuf[0] == '\0')
  196.             break;
  197.         lnum++;
  198.         if (strncmp(genbuf, "------", 6) == 0) {
  199.             mode++;
  200.             continue;
  201.         }
  202.         if (mode == -1)
  203. fmterr:            complain("Abbrev. format error, line %d.", file, lnum);
  204.         phrase_p = index(genbuf, ':');
  205.         if (phrase_p == 0)
  206.             goto fmterr;
  207.         *phrase_p++ = '\0';    /* Null terminate the abbrev. */
  208.         define(A_tables[mode], genbuf, phrase_p);
  209.     }
  210.     f_close(fp);
  211.     message(NullStr);
  212. }
  213.  
  214. DefGAbbrev()
  215. {
  216.     def_abbrev(A_tables[GLOBAL]);
  217. }
  218.  
  219. DefMAbbrev()
  220. {
  221.     def_abbrev(A_tables[curbuf->b_major]);
  222. }
  223.  
  224. SaveAbbrevs()
  225. {
  226.     char    filebuf[FILESIZE];
  227.  
  228.     save_abbrevs(ask_file((char *) 0, (char *) 0, filebuf));
  229. }
  230.  
  231. RestAbbrevs()
  232. {
  233.     char    filebuf[FILESIZE];
  234.  
  235.     rest_abbrevs(ask_file((char *) 0, (char *) 0, filebuf));
  236. }
  237.  
  238. EditAbbrevs()
  239. {
  240.     char    *tname = "jove_wam.$$$",
  241.         *EditName = "Abbreviation Edit";
  242.     Buffer    *obuf = curbuf,
  243.         *ebuf;
  244.  
  245.     if (ebuf = buf_exists(EditName)) {
  246.         if (ebuf->b_type != B_SCRATCH)
  247.             confirm("Over-write buffer %b?", ebuf);
  248.     }
  249.     SetBuf(ebuf = do_select(curwind, EditName));
  250.     ebuf->b_type = B_SCRATCH;
  251.     initlist(ebuf);
  252.     /* Empty buffer.  Save the definitions to a tmp file
  253.        and read them into this buffer so we can edit them. */
  254.     save_abbrevs(tname);
  255.     read_file(tname, NO);
  256.     message("[Edit definitions and then type C-X C-C]");
  257.     Recur();        /* We edit them ... now */
  258.     /* RESetBuf in case we deleted the buffer while we were editing. */
  259.     SetBuf(ebuf = do_select(curwind, EditName));
  260.     if (IsModified(ebuf)) {
  261.         SetBuf(ebuf);
  262.         file_write(tname, 0);
  263.         rest_abbrevs(tname);
  264.         unmodify();
  265.     }
  266.     (void) unlink(tname);
  267.     SetBuf(do_select(curwind, obuf->b_name));
  268. }
  269.  
  270. BindMtoW()
  271. {
  272.     struct abbrev    *ap;
  273.     char    *word;
  274.     data_obj    *hook;
  275.  
  276.     word = ask((char *) 0, "Word: ");
  277.  
  278.     if ((ap = lookup(A_tables[curbuf->b_major], word)) == 0 &&
  279.         (ap = lookup(A_tables[GLOBAL], word)) == 0)
  280.             complain("%s: unknown abbrev.", word);
  281.  
  282.     hook = findmac("Macro: ");
  283.     if (hook == 0)
  284.         complain("[Undefined macro]");
  285.     ap->a_cmdhook = hook;
  286. }
  287.  
  288. #endif ABBREV
  289.