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