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