home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / jove4.9 / part03 / abbrev.c next >
Encoding:
C/C++ Source or Header  |  1988-04-25  |  6.4 KB  |  332 lines

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