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