|
|
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.