home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / jove-4.16-src.tgz / tar.out / bsd / jove / abbrev.c next >
C/C++ Source or Header  |  1996-09-28  |  6KB  |  306 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986-1996 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    /* the body is the rest of this file */
  11.  
  12. #include "fp.h"
  13. #include "jctype.h"
  14. #include "abbrev.h"
  15. #include "ask.h"
  16. #include "commands.h"    /* for ExecCmd() */
  17. #include "delete.h"
  18. #include "insert.h"
  19. #include "disp.h"
  20. #include "fmt.h"
  21. #include "move.h"
  22. #include "wind.h"
  23.  
  24. #ifdef MSFILESYSTEM
  25. # include <io.h>
  26. #endif
  27. #define HASHSIZE    20
  28.  
  29. struct abbrev {
  30.     unsigned int    a_hash;
  31.     char    *a_abbrev,
  32.         *a_phrase;
  33.     struct abbrev    *a_next;
  34.     data_obj    *a_cmdhook;
  35. };
  36.  
  37. private    void
  38.     define proto((struct abbrev **, char *, char *));
  39.  
  40. #define GLOBAL    NMAJORS
  41. private struct abbrev    *A_tables[NMAJORS + 1][HASHSIZE];    /* Must be zeroed! */
  42.  
  43. bool AutoCaseAbbrev = YES;    /* VAR: automatically do case on abbreviations */
  44.  
  45. private unsigned int
  46. hash(a)
  47. register char    *a;
  48. {
  49.     register unsigned int    hashval = 0;
  50.     register char    c;
  51.  
  52.     while ((c = *a++) != '\0')
  53.         hashval = (hashval << 2) + c;
  54.  
  55.     return hashval;
  56. }
  57.  
  58. private void
  59. def_abbrev(table)
  60. struct abbrev    *table[HASHSIZE];
  61. {
  62.     char    abbrev[100],
  63.         phrase[100];
  64.  
  65.     null_ncpy(abbrev, ask((char *)NULL, "abbrev: "), sizeof(abbrev)-1);
  66.     null_ncpy(phrase, ask((char *)NULL, "abbrev: %s phrase: ", abbrev),
  67.         sizeof(phrase)-1);
  68.     define(table, abbrev, phrase);
  69. }
  70.  
  71. private struct abbrev *
  72. lookup_abbrev(table, abbrev)
  73. register struct abbrev    *table[HASHSIZE];
  74. register char    *abbrev;
  75. {
  76.     register struct abbrev    *ap;
  77.     unsigned int    h;
  78.  
  79.     h = hash(abbrev);
  80.     for (ap = table[h % HASHSIZE]; ap; ap = ap->a_next)
  81.         if (ap->a_hash == h && strcmp(ap->a_abbrev, abbrev) == 0)
  82.             break;
  83.     return ap;
  84. }
  85.  
  86. private void
  87. define(table, abbrev, phrase)
  88. register struct abbrev    *table[HASHSIZE];
  89. char    *abbrev,
  90.     *phrase;
  91. {
  92.     register struct abbrev    *ap;
  93.  
  94.     ap = lookup_abbrev(table, abbrev);
  95.     if (ap == NULL) {
  96.         register unsigned int    h = hash(abbrev);
  97.  
  98.         ap = (struct abbrev *) emalloc(sizeof *ap);
  99.         ap->a_hash = h;
  100.         ap->a_abbrev = copystr(abbrev);
  101.         h %= HASHSIZE;
  102.         ap->a_next = table[h];
  103.         ap->a_cmdhook = NULL;
  104.         table[h] = ap;
  105.     } else
  106.         free((UnivPtr) ap->a_phrase);
  107.     ap->a_phrase = copystr(phrase);
  108. }
  109.  
  110. void
  111. AbbrevExpand()
  112. {
  113.     char    wordbuf[100];
  114.     register char
  115.         *wp = wordbuf,
  116.         *cp;
  117.     int    col;
  118.     register char    c;
  119.     int    UC_count = 0;
  120.     struct abbrev    *ap;
  121.  
  122.     col = curchar;
  123.     while (col != 0 && jisident(linebuf[col - 1]))
  124.         col -= 1;
  125.     if (curchar-col >= (int)sizeof(wordbuf))
  126.         return;    /* too long for us -- ignore it */
  127.  
  128.     while (col < curchar) {
  129.         c = linebuf[col];
  130.         if (AutoCaseAbbrev && jisupper(c)) {
  131.             UC_count += 1;
  132.             c = CharDowncase(c);
  133.         }
  134.         *wp++ = c;
  135.         col += 1;
  136.     }
  137.     *wp = '\0';
  138.  
  139.     if ((ap = lookup_abbrev(A_tables[curbuf->b_major], wordbuf)) != NULL
  140.     || (ap = lookup_abbrev(A_tables[GLOBAL], wordbuf)) != NULL)
  141.     {
  142.         del_char(BACKWARD, (wp - wordbuf), NO);
  143.  
  144.         for (cp = ap->a_phrase; (c = *cp) != '\0'; ) {
  145.             if (UC_count > 0 && jislower(c)
  146.             && (cp == ap->a_phrase
  147.                || (UC_count > 1 && (jiswhite(cp[-1]) || cp[-1] == '-'))))
  148.                 c = CharUpcase(c);
  149.             insert_c(c, 1);
  150.             cp += 1;
  151.         }
  152.         if (ap->a_cmdhook != NULL)
  153.             ExecCmd(ap->a_cmdhook);
  154.     }
  155. }
  156.  
  157. private char    *mode_names[NMAJORS + 1] = {
  158.     "Fundamental Mode",
  159.     "Text Mode",
  160.     "C Mode",
  161. #ifdef LISP
  162.     "Lisp Mode",
  163. #endif
  164.     "Global"
  165. };
  166.  
  167. private void
  168. save_abbrevs(file)
  169. char    *file;
  170. {
  171.     File    *fp;
  172.     struct abbrev    *ap,
  173.             **tp;
  174.     char    buf[LBSIZE];
  175.     int    i,
  176.         count = 0;
  177.  
  178.     fp = open_file(file, buf, F_WRITE, YES);
  179.     for (i = 0; i <= GLOBAL; i++) {
  180.         fwritef(fp, "------%s abbrevs------\n", mode_names[i]);
  181.         for (tp = A_tables[i]; tp < &A_tables[i][HASHSIZE]; tp++)
  182.             for (ap = *tp; ap; ap = ap->a_next) {
  183.                 fwritef(fp, "%s:%s\n",
  184.                     ap->a_abbrev,
  185.                     ap->a_phrase);
  186.                 count += 1;
  187.             }
  188.     }
  189.     f_close(fp);
  190.     add_mess(" %d written.", count);
  191. }
  192.  
  193. private void
  194. rest_abbrevs(file)
  195. char    *file;
  196. {
  197.     int
  198.         mode = -1,    /* Should be ++'d immediately */
  199.         lnum = 0;
  200.     char    *phrase_p;
  201.     File    *fp;
  202.     char    buf[LBSIZE];
  203.  
  204.     fp = open_file(file, buf, F_READ, YES);
  205.     while (mode<=GLOBAL && !f_gets(fp, genbuf, (size_t) LBSIZE)
  206.         && !genbuf[0] == '\0')
  207.     {
  208.         static const char    sep[] = "------";
  209.  
  210.         lnum += 1;
  211.         if (strncmp(genbuf, sep, sizeof(sep)-1) == 0) {
  212.             mode += 1;
  213.         } else if (mode == -1 || (phrase_p = strchr(genbuf, ':')) == NULL) {
  214.             complain("Abbrev. format error, line %d.", file, lnum);
  215.             /* NOTREACHED */
  216.         } else {
  217.             *phrase_p++ = '\0';    /* Null terminate the abbrev. */
  218.             define(A_tables[mode], genbuf, phrase_p);
  219.         }
  220.     }
  221.     f_close(fp);
  222.     message(NullStr);
  223. }
  224.  
  225. void
  226. DefGAbbrev()
  227. {
  228.     def_abbrev(A_tables[GLOBAL]);
  229. }
  230.  
  231. void
  232. DefMAbbrev()
  233. {
  234.     def_abbrev(A_tables[curbuf->b_major]);
  235. }
  236.  
  237. void
  238. SaveAbbrevs()
  239. {
  240.     char    filebuf[FILESIZE];
  241.  
  242.     save_abbrevs(ask_file((char *)NULL, (char *)NULL, filebuf));
  243. }
  244.  
  245. void
  246. RestAbbrevs()
  247. {
  248.     char    filebuf[FILESIZE];
  249.  
  250.     rest_abbrevs(ask_file((char *)NULL, (char *)NULL, filebuf));
  251. }
  252.  
  253. void
  254. EditAbbrevs()
  255. {
  256.     char    tname[128],
  257.         *EditName = "Abbreviation Edit";
  258.     Buffer    *obuf = curbuf,
  259.         *ebuf;
  260.  
  261.     if ((ebuf = buf_exists(EditName)) != NULL) {
  262.         if (ebuf->b_type != B_SCRATCH)
  263.             confirm("Over-write buffer %b? ", ebuf);
  264.     }
  265.     SetBuf(ebuf = do_select(curwind, EditName));
  266.     ebuf->b_type = B_SCRATCH;
  267.     buf_clear(ebuf);
  268.     /* Empty buffer.  Save the definitions to a tmp file
  269.        and read them into this buffer so we can edit them. */
  270.     swritef(tname, sizeof(tname), "%s/%s", TmpDir,
  271. #ifdef MAC
  272.         ".jabbXXX"    /* must match string in mac.c:Ffilter() */
  273. #else
  274.         "jabbXXXXXX"
  275. #endif
  276.         );
  277.     (void) mktemp(tname);
  278.     save_abbrevs(tname);
  279.     setfname(ebuf, tname);
  280.     read_file(tname, NO);
  281.     message("[Edit definitions and then type ^X ^C]");
  282.     Recur();        /* We edit them ... now */
  283.     if (IsModified(ebuf)) {
  284.         file_write(tname, NO);
  285.         rest_abbrevs(tname);
  286.     }
  287.     (void) unlink(tname);
  288.     if (valid_bp(obuf))
  289.         SetBuf(do_select(curwind, obuf->b_name));
  290. }
  291.  
  292. void
  293. BindMtoW()
  294. {
  295.     struct abbrev    *ap;
  296.     char    *word = ask((char *)NULL, "Word: ");
  297.  
  298.     if ((ap = lookup_abbrev(A_tables[curbuf->b_major], word)) == NULL
  299.     && (ap = lookup_abbrev(A_tables[GLOBAL], word)) == NULL)
  300.         complain("%s: unknown abbrev.", word);
  301.  
  302.     ap->a_cmdhook = findmac("Macro: ");
  303. }
  304.  
  305. #endif /* ABBREV */
  306.