|
|
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: #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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.