|
|
1.1 ! root 1: /* input.c */ ! 2: ! 3: /* Author: ! 4: * Steve Kirkendall ! 5: * 14407 SW Teal Blvd. #C ! 6: * Beaverton, OR 97005 ! 7: * [email protected] ! 8: */ ! 9: ! 10: ! 11: /* This file contains the input() function, which implements vi's INPUT mode. ! 12: * It also contains the code that supports digraphs. ! 13: */ ! 14: ! 15: #include "config.h" ! 16: #include "ctype.h" ! 17: #include "vi.h" ! 18: ! 19: ! 20: #ifndef NO_DIGRAPH ! 21: static struct _DIG ! 22: { ! 23: struct _DIG *next; ! 24: char key1; ! 25: char key2; ! 26: char dig; ! 27: char save; ! 28: } *digs; ! 29: ! 30: char digraph(key1, key2) ! 31: int key1; /* the underlying character */ ! 32: int key2; /* the second character */ ! 33: { ! 34: int newkey; ! 35: REG struct _DIG *dp; ! 36: ! 37: /* if digraphs are disabled, then just return the new char */ ! 38: if (!*o_digraph) ! 39: { ! 40: return key2; ! 41: } ! 42: ! 43: /* remember the new key, so we can return it if this isn't a digraph */ ! 44: newkey = key2; ! 45: ! 46: /* sort key1 and key2, so that their original order won't matter */ ! 47: if (key1 > key2) ! 48: { ! 49: key2 = key1; ! 50: key1 = newkey; ! 51: } ! 52: ! 53: /* scan through the digraph chart */ ! 54: for (dp = digs; ! 55: dp && (dp->key1 != key1 || dp->key2 != key2); ! 56: dp = dp->next) ! 57: { ! 58: } ! 59: ! 60: /* if this combination isn't in there, just use the new key */ ! 61: if (!dp) ! 62: { ! 63: return newkey; ! 64: } ! 65: ! 66: /* else use the digraph key */ ! 67: return dp->dig; ! 68: } ! 69: ! 70: /* this function lists or defines digraphs */ ! 71: void do_digraph(bang, extra) ! 72: int bang; ! 73: char extra[]; ! 74: { ! 75: int dig; ! 76: REG struct _DIG *dp; ! 77: struct _DIG *prev; ! 78: static int user_defined = FALSE; /* boolean: are all later digraphs user-defined? */ ! 79: char listbuf[8]; ! 80: ! 81: /* if "extra" is NULL, then we've reached the end of the built-ins */ ! 82: if (!extra) ! 83: { ! 84: user_defined = TRUE; ! 85: return; ! 86: } ! 87: ! 88: /* if no args, then display the existing digraphs */ ! 89: if (*extra < ' ') ! 90: { ! 91: listbuf[0] = listbuf[1] = listbuf[2] = listbuf[5] = ' '; ! 92: listbuf[7] = '\0'; ! 93: for (dig = 0, dp = digs; dp; dp = dp->next) ! 94: { ! 95: if (dp->save || bang) ! 96: { ! 97: dig += 7; ! 98: if (dig >= COLS) ! 99: { ! 100: addch('\n'); ! 101: exrefresh(); ! 102: dig = 7; ! 103: } ! 104: listbuf[3] = dp->key1; ! 105: listbuf[4] = dp->key2; ! 106: listbuf[6] = dp->dig; ! 107: qaddstr(listbuf); ! 108: } ! 109: } ! 110: addch('\n'); ! 111: exrefresh(); ! 112: return; ! 113: } ! 114: ! 115: /* make sure we have at least two characters */ ! 116: if (!extra[1]) ! 117: { ! 118: msg("Digraphs must be composed of two characters"); ! 119: return; ! 120: } ! 121: ! 122: /* sort key1 and key2, so that their original order won't matter */ ! 123: if (extra[0] > extra[1]) ! 124: { ! 125: dig = extra[0]; ! 126: extra[0] = extra[1]; ! 127: extra[1] = dig; ! 128: } ! 129: ! 130: /* locate the new digraph character */ ! 131: for (dig = 2; extra[dig] == ' ' || extra[dig] == '\t'; dig++) ! 132: { ! 133: } ! 134: dig = extra[dig]; ! 135: if (!bang && dig) ! 136: { ! 137: dig |= 0x80; ! 138: } ! 139: ! 140: /* search for the digraph */ ! 141: for (prev = (struct _DIG *)0, dp = digs; ! 142: dp && (dp->key1 != extra[0] || dp->key2 != extra[1]); ! 143: prev = dp, dp = dp->next) ! 144: { ! 145: } ! 146: ! 147: /* deleting the digraph? */ ! 148: if (!dig) ! 149: { ! 150: if (!dp) ! 151: { ! 152: #ifndef CRUNCH ! 153: msg("%c%c not a digraph", extra[0], extra[1]); ! 154: #endif ! 155: return; ! 156: } ! 157: if (prev) ! 158: prev->next = dp->next; ! 159: else ! 160: digs = dp->next; ! 161: _free_(dp); ! 162: return; ! 163: } ! 164: ! 165: /* if necessary, create a new digraph struct for the new digraph */ ! 166: if (dig && !dp) ! 167: { ! 168: dp = (struct _DIG *)malloc(sizeof *dp); ! 169: if (!dp) ! 170: { ! 171: msg("Out of space in the digraph table"); ! 172: return; ! 173: } ! 174: if (prev) ! 175: prev->next = dp; ! 176: else ! 177: digs = dp; ! 178: dp->next = (struct _DIG *)0; ! 179: } ! 180: ! 181: /* assign it the new digraph value */ ! 182: dp->key1 = extra[0]; ! 183: dp->key2 = extra[1]; ! 184: dp->dig = dig; ! 185: dp->save = user_defined; ! 186: } ! 187: ! 188: # ifndef NO_MKEXRC ! 189: void savedigs(fd) ! 190: int fd; ! 191: { ! 192: static char buf[] = "digraph! XX Y\n"; ! 193: REG struct _DIG *dp; ! 194: ! 195: for (dp = digs; dp; dp = dp->next) ! 196: { ! 197: if (dp->save) ! 198: { ! 199: buf[9] = dp->key1; ! 200: buf[10] = dp->key2; ! 201: buf[12] = dp->dig; ! 202: write(fd, buf, (unsigned)14); ! 203: } ! 204: } ! 205: } ! 206: # endif ! 207: #endif ! 208: ! 209: ! 210: /* This function allows the user to replace an existing (possibly zero-length) ! 211: * chunk of text with typed-in text. It returns the MARK of the last character ! 212: * that the user typed in. ! 213: */ ! 214: MARK input(from, to, when, delta) ! 215: MARK from; /* where to start inserting text */ ! 216: MARK to; /* extent of text to delete */ ! 217: int when; /* either WHEN_VIINP or WHEN_VIREP */ ! 218: int delta; /* 1 to take indent from lower line, -1 for upper, 0 for none */ ! 219: { ! 220: char key[2]; /* key char followed by '\0' char */ ! 221: char *build; /* used in building a newline+indent string */ ! 222: char *scan; /* used while looking at the indent chars of a line */ ! 223: MARK m; /* some place in the text */ ! 224: #ifndef NO_EXTENSIONS ! 225: int quit = FALSE; /* boolean: are we exiting after this? */ ! 226: int inchg; /* boolean: have we done a "beforedo()" yet? */ ! 227: #endif ! 228: ! 229: #ifdef DEBUG ! 230: /* if "from" and "to" are reversed, complain */ ! 231: if (from > to) ! 232: { ! 233: msg("ERROR: input(%ld:%d, %ld:%d)", ! 234: markline(from), markidx(from), ! 235: markline(to), markidx(to)); ! 236: return MARK_UNSET; ! 237: } ! 238: #endif ! 239: ! 240: key[1] = 0; ! 241: ! 242: /* if we're replacing text with new text, save the old stuff */ ! 243: /* (Alas, there is no easy way to save text for replace mode) */ ! 244: if (from != to) ! 245: { ! 246: cut(from, to); ! 247: } ! 248: ! 249: /* if doing a dot command, then reuse the previous text */ ! 250: if (doingdot) ! 251: { ! 252: ChangeText ! 253: { ! 254: /* delete the text that's there now */ ! 255: if (from != to) ! 256: { ! 257: delete(from, to); ! 258: } ! 259: ! 260: /* insert the previous text */ ! 261: cutname('.'); ! 262: cursor = paste(from, FALSE, TRUE) + 1L; ! 263: } ! 264: } ! 265: else /* interactive version */ ! 266: { ! 267: /* assume that whoever called this already did a beforedo() */ ! 268: #ifndef NO_EXTENSIONS ! 269: inchg = TRUE; ! 270: #endif ! 271: ! 272: /* if doing a change within the line... */ ! 273: if (from != to && markline(from) == markline(to)) ! 274: { ! 275: /* mark the end of the text with a "$" */ ! 276: change(to - 1, to, "$"); ! 277: } ! 278: else ! 279: { ! 280: /* delete the old text right off */ ! 281: if (from != to) ! 282: { ! 283: delete(from, to); ! 284: } ! 285: to = from; ! 286: } ! 287: ! 288: /* handle autoindent of the first line, maybe */ ! 289: cursor = from; ! 290: m = cursor + MARK_AT_LINE(delta); ! 291: if (delta != 0 && *o_autoindent && markidx(m) == 0 ! 292: && markline(m) >= 1L && markline(m) <= nlines) ! 293: { ! 294: /* Only autoindent blank lines. */ ! 295: pfetch(markline(cursor)); ! 296: if (plen == 0) ! 297: { ! 298: /* Okay, we really want to autoindent */ ! 299: pfetch(markline(m)); ! 300: for (scan = ptext, build = tmpblk.c; ! 301: *scan == ' ' || *scan == '\t'; ! 302: ) ! 303: { ! 304: *build++ = *scan++; ! 305: } ! 306: if (build > tmpblk.c) ! 307: { ! 308: *build = '\0'; ! 309: add(cursor, tmpblk.c); ! 310: cursor += (int)(build - tmpblk.c); ! 311: if (cursor > to) ! 312: to = cursor; ! 313: } ! 314: } ! 315: } ! 316: ! 317: /* repeatedly add characters from the user */ ! 318: for (;;) ! 319: { ! 320: /* Get a character */ ! 321: redraw(cursor, TRUE); ! 322: #ifdef DEBUG2 ! 323: msg("cursor=%ld.%d, to=%ld.%d", ! 324: markline(cursor), markidx(cursor), ! 325: markline(to), markidx(to)); ! 326: #endif ! 327: #ifndef NO_ABBR ! 328: pfetch(markline(cursor)); ! 329: build = ptext; ! 330: if (pline == markline(from)) ! 331: build += markidx(from); ! 332: for (scan = ptext + markidx(cursor); --scan >= build && isalnum(*scan); ) ! 333: { ! 334: } ! 335: scan++; ! 336: key[0] = getabkey(when, scan, (int)(ptext + markidx(cursor) - scan)); ! 337: #else ! 338: key[0] = getkey(when); ! 339: #endif ! 340: #ifndef NO_VISIBLE ! 341: if (key[0] != '\0' && V_from != MARK_UNSET) ! 342: { ! 343: msg("Can't modify text during a selection"); ! 344: beep(); ! 345: continue; ! 346: } ! 347: #endif ! 348: ! 349: #ifndef NO_EXTENSIONS ! 350: if (key[0] == ctrl('O')) ! 351: { ! 352: if (inchg) ! 353: { ! 354: if (cursor < to) ! 355: { ! 356: delete(cursor, to); ! 357: redraw(cursor, TRUE); ! 358: } ! 359: afterdo(); ! 360: inchg = FALSE; ! 361: } ! 362: } ! 363: else if (key[0] != ctrl('[')) ! 364: { ! 365: if (!inchg) ! 366: { ! 367: beforedo(FALSE); ! 368: inchg = TRUE; ! 369: } ! 370: } ! 371: #endif ! 372: ! 373: #ifndef CRUNCH ! 374: /* if wrapmargin is set & we're past the ! 375: * warpmargin, then change the last whitespace ! 376: * characters on line into a newline ! 377: */ ! 378: if (*o_wrapmargin != 0) ! 379: { ! 380: pfetch(markline(cursor)); ! 381: if (plen == idx2col(cursor, ptext, TRUE) ! 382: && plen > COLS - (*o_wrapmargin & 0xff)) ! 383: { ! 384: build = tmpblk.c; ! 385: *build++ = '\n'; ! 386: if (*o_autoindent) ! 387: { ! 388: /* figure out indent for next line */ ! 389: for (scan = ptext; *scan == ' ' || *scan == '\t'; ) ! 390: { ! 391: *build++ = *scan++; ! 392: } ! 393: } ! 394: *build = '\0'; ! 395: ! 396: scan = ptext + plen; ! 397: m = cursor & ~(BLKSIZE - 1); ! 398: while (ptext < scan) ! 399: { ! 400: scan--; ! 401: if (*scan != ' ' && *scan != '\t') ! 402: continue; ! 403: ! 404: /*break up line, and we do autoindent if needed*/ ! 405: change(m + (int)(scan - ptext), m + (int)(scan - ptext) + 1, tmpblk.c); ! 406: ! 407: /* NOTE: for some reason, MSC 5.10 doesn't ! 408: * like for these lines to be combined!!! ! 409: */ ! 410: cursor = (cursor & ~(BLKSIZE - 1)); ! 411: cursor += BLKSIZE; ! 412: cursor += strlen(tmpblk.c) - 1; ! 413: cursor += plen - (int)(scan - ptext) - 1; ! 414: ! 415: /*remove trailing spaces on previous line*/ ! 416: pfetch(markline(m)); ! 417: scan = ptext + plen; ! 418: while (ptext < scan) ! 419: { ! 420: scan--; ! 421: if (*scan != ' ' && *scan != '\t') ! 422: break; ! 423: } ! 424: delete(m + (int)(scan - ptext) + 1, m + plen); ! 425: ! 426: break; ! 427: } ! 428: } ! 429: } ! 430: #endif /* !CRUNCH */ ! 431: ! 432: /* process it */ ! 433: switch (*key) ! 434: { ! 435: #ifndef NO_EXTENSIONS ! 436: case ctrl('O'): /* special movement mapped keys */ ! 437: *key = getkey(0); ! 438: switch (*key) ! 439: { ! 440: case 'h': m = m_left(cursor, 0L); break; ! 441: case 'j': ! 442: case 'k': m = m_updnto(cursor, 0L, *key); break; ! 443: case 'l': m = cursor + 1; break; ! 444: case 'B': ! 445: case 'b': m = m_bword(cursor, 0L, *key); break; ! 446: case 'W': ! 447: case 'w': m = m_fword(cursor, 0L, *key, '\0'); break; ! 448: case '^': m = m_front(cursor, 0L); break; ! 449: case '$': m = m_rear(cursor, 0L); break; ! 450: case ctrl('B'): ! 451: case ctrl('F'): ! 452: m = m_scroll(cursor, 0L, *key); break; ! 453: case 'x': ! 454: #ifndef NO_VISIBLE ! 455: if (V_from) ! 456: beep(); ! 457: else ! 458: #endif ! 459: ChangeText ! 460: { ! 461: m = v_xchar(cursor, 0L, 'x'); ! 462: } ! 463: break; ! 464: case 'i': m = to = from = cursor; ! 465: when = WHEN_VIINP + WHEN_VIREP - when; ! 466: break; ! 467: case 'K': ! 468: pfetch(markline(cursor)); ! 469: changes++; /* <- after this, we can alter ptext */ ! 470: ptext[markidx(cursor)] = 0; ! 471: for (scan = ptext + markidx(cursor) - 1; ! 472: scan >= ptext && isalnum(*scan); ! 473: scan--) ! 474: { ! 475: } ! 476: scan++; ! 477: m = (*scan ? v_keyword(scan, cursor, 0L) : cursor); ! 478: break; ! 479: ! 480: # ifndef NO_VISIBLE ! 481: case 'v': ! 482: case 'V': ! 483: if (V_from) ! 484: V_from = MARK_UNSET; ! 485: else ! 486: V_from = cursor; ! 487: m = from = to = cursor; ! 488: V_linemd = (*key == 'V'); ! 489: break; ! 490: ! 491: case 'd': ! 492: case 'y': ! 493: case '\\': ! 494: /* do nothing if unmarked */ ! 495: if (!V_from) ! 496: { ! 497: msg("You must mark the text first"); ! 498: beep(); ! 499: break; ! 500: } ! 501: ! 502: /* "from" must come before "to" */ ! 503: if (V_from < cursor) ! 504: { ! 505: from = V_from; ! 506: to = cursor; ! 507: } ! 508: else ! 509: { ! 510: from = cursor; ! 511: to = V_from; ! 512: } ! 513: ! 514: /* we don't need V_from anymore */ ! 515: V_from = MARK_UNSET; ! 516: ! 517: if (V_linemd) ! 518: { ! 519: /* adjust for line mode */ ! 520: from &= ~(BLKSIZE - 1); ! 521: to |= (BLKSIZE - 1); ! 522: } ! 523: else ! 524: { ! 525: /* in character mode, we must ! 526: * worry about deleting the newline ! 527: * at the end of the last line ! 528: */ ! 529: pfetch(markline(to)); ! 530: if (markidx(to) == plen) ! 531: to |= (BLKSIZE - 1); ! 532: } ! 533: to++; ! 534: ! 535: switch (*key) ! 536: { ! 537: case 'y': ! 538: cut(from, to); ! 539: break; ! 540: ! 541: case 'd': ! 542: ChangeText ! 543: { ! 544: cut(from, to); ! 545: delete(from, to); ! 546: } ! 547: cursor = from; ! 548: break; ! 549: ! 550: #ifndef NO_POPUP ! 551: case '\\': ! 552: ChangeText ! 553: { ! 554: cursor = v_popup(from, to); ! 555: } ! 556: break; ! 557: #endif ! 558: } ! 559: m = from = to = cursor; ! 560: break; ! 561: ! 562: case 'p': ! 563: case 'P': ! 564: V_from = MARK_UNSET; ! 565: ChangeText ! 566: { ! 567: m = from = to = cursor = paste(cursor, (*key == 'p'), FALSE); ! 568: } ! 569: break; ! 570: # endif /* !NO_VISIBLE */ ! 571: default: m = MARK_UNSET; ! 572: } ! 573: ! 574: /* adjust the moved cursor */ ! 575: if (m != cursor) ! 576: { ! 577: m = adjmove(cursor, m, (*key == 'j' || *key == 'k' ? NCOL|FINL : FINL)); ! 578: if (*key == '$' || (*key == 'l' && m <= cursor)) ! 579: { ! 580: m++; ! 581: } ! 582: } ! 583: ! 584: /* if the cursor is reasonable, use it */ ! 585: if (m == MARK_UNSET) ! 586: { ! 587: beep(); ! 588: } ! 589: else ! 590: { ! 591: from = to = cursor = m; ! 592: } ! 593: break; ! 594: ! 595: case ctrl('Z'): ! 596: if (getkey(0) == ctrl('Z')) ! 597: { ! 598: quit = TRUE; ! 599: goto BreakBreak; ! 600: } ! 601: break; ! 602: #endif ! 603: ! 604: case ctrl('['): ! 605: /* if last line contains only whitespace, then remove whitespace */ ! 606: if (*o_autoindent) ! 607: { ! 608: pfetch(markline(cursor)); ! 609: for (scan = ptext; isspace(*scan); scan++) ! 610: { ! 611: } ! 612: if (scan > ptext && !*scan) ! 613: { ! 614: cursor &= ~(BLKSIZE - 1L); ! 615: if (to < cursor + plen) ! 616: { ! 617: to = cursor + plen; ! 618: } ! 619: } ! 620: } ! 621: goto BreakBreak; ! 622: ! 623: case ctrl('U'): ! 624: if (markline(cursor) == markline(from)) ! 625: { ! 626: cursor = from; ! 627: } ! 628: else ! 629: { ! 630: cursor &= ~(BLKSIZE - 1); ! 631: } ! 632: break; ! 633: ! 634: case ctrl('D'): ! 635: case ctrl('T'): ! 636: if (to > cursor) ! 637: { ! 638: delete(cursor, to); ! 639: } ! 640: mark[27] = cursor; ! 641: cmd_shift(cursor, cursor, *key == ctrl('D') ? CMD_SHIFTL : CMD_SHIFTR, TRUE, ""); ! 642: if (mark[27]) ! 643: { ! 644: cursor = mark[27]; ! 645: } ! 646: else ! 647: { ! 648: cursor = m_front(cursor, 0L); ! 649: } ! 650: to = cursor; ! 651: break; ! 652: ! 653: case '\b': ! 654: if (cursor <= from) ! 655: { ! 656: beep(); ! 657: } ! 658: else if (markidx(cursor) == 0) ! 659: { ! 660: cursor -= BLKSIZE; ! 661: pfetch(markline(cursor)); ! 662: cursor += plen; ! 663: } ! 664: else ! 665: { ! 666: cursor--; ! 667: } ! 668: break; ! 669: ! 670: case ctrl('W'): ! 671: m = m_bword(cursor, 1L, 'b'); ! 672: if (markline(m) == markline(cursor) && m >= from) ! 673: { ! 674: cursor = m; ! 675: if (from > cursor) ! 676: { ! 677: from = cursor; ! 678: } ! 679: } ! 680: else ! 681: { ! 682: beep(); ! 683: } ! 684: break; ! 685: ! 686: case '\n': ! 687: #if OSK ! 688: case '\l': ! 689: #else ! 690: case '\r': ! 691: #endif ! 692: build = tmpblk.c; ! 693: *build++ = '\n'; ! 694: if (*o_autoindent) ! 695: { ! 696: /* figure out indent for next line */ ! 697: pfetch(markline(cursor)); ! 698: for (scan = ptext; *scan == ' ' || *scan == '\t'; ) ! 699: { ! 700: *build++ = *scan++; ! 701: } ! 702: ! 703: /* remove indent from this line, if blank */ ! 704: if ((int)(scan - ptext) >= markidx(cursor) && plen > 0) ! 705: { ! 706: to = cursor &= ~(BLKSIZE - 1); ! 707: delete(cursor, cursor + (int)(scan - ptext)); ! 708: } ! 709: } ! 710: *build = 0; ! 711: if (cursor >= to && when != WHEN_VIREP) ! 712: { ! 713: add(cursor, tmpblk.c); ! 714: } ! 715: else ! 716: { ! 717: change(cursor, to, tmpblk.c); ! 718: } ! 719: redraw(cursor, TRUE); ! 720: to = cursor = (cursor & ~(BLKSIZE - 1)) ! 721: + BLKSIZE ! 722: + (int)(build - tmpblk.c) - 1; ! 723: break; ! 724: ! 725: case ctrl('A'): ! 726: case ctrl('P'): ! 727: if (cursor < to) ! 728: { ! 729: delete(cursor, to); ! 730: } ! 731: if (*key == ctrl('A')) ! 732: { ! 733: cutname('.'); ! 734: } ! 735: to = cursor = paste(cursor, FALSE, TRUE) + 1L; ! 736: break; ! 737: ! 738: case ctrl('V'): ! 739: if (cursor >= to && when != WHEN_VIREP) ! 740: { ! 741: add(cursor, "^"); ! 742: } ! 743: else ! 744: { ! 745: change(cursor, to, "^"); ! 746: to = cursor + 1; ! 747: } ! 748: redraw(cursor, TRUE); ! 749: *key = getkey(0); ! 750: if (*key == '\n') ! 751: { ! 752: /* '\n' too hard to handle */ ! 753: #if OSK ! 754: *key = '\l'; ! 755: #else ! 756: *key = '\r'; ! 757: #endif ! 758: } ! 759: change(cursor, cursor + 1, key); ! 760: cursor++; ! 761: if (cursor > to) ! 762: { ! 763: to = cursor; ! 764: } ! 765: break; ! 766: ! 767: case ctrl('L'): ! 768: case ctrl('R'): ! 769: redraw(MARK_UNSET, FALSE); ! 770: break; ! 771: ! 772: default: ! 773: if (cursor >= to && when != WHEN_VIREP) ! 774: { ! 775: add(cursor, key); ! 776: cursor++; ! 777: to = cursor; ! 778: } ! 779: else ! 780: { ! 781: pfetch(markline(cursor)); ! 782: if (markidx(cursor) == plen) ! 783: { ! 784: add(cursor, key); ! 785: } ! 786: else ! 787: { ! 788: #ifndef NO_DIGRAPH ! 789: *key = digraph(ptext[markidx(cursor)], *key); ! 790: #endif ! 791: change(cursor, cursor + 1, key); ! 792: } ! 793: cursor++; ! 794: } ! 795: #ifndef NO_SHOWMATCH ! 796: /* show matching "({[" if necessary */ ! 797: if (*o_showmatch && strchr(")}]", *key)) ! 798: { ! 799: redraw(cursor, TRUE); ! 800: m = m_match(cursor - 1, 0L); ! 801: if (markline(m) >= topline ! 802: && markline(m) <= botline) ! 803: { ! 804: redraw(m, TRUE); ! 805: refresh(); ! 806: sleep(1); ! 807: } ! 808: } ! 809: #endif ! 810: } /* end switch(*key) */ ! 811: } /* end for(;;) */ ! 812: BreakBreak:; ! 813: /* delete any excess characters */ ! 814: if (cursor < to) ! 815: { ! 816: #ifndef NO_EXTENSIONS ! 817: /* if we aren't in the middle of a change, start one! */ ! 818: if (!inchg) ! 819: { ! 820: beforedo(FALSE); ! 821: inchg = TRUE; ! 822: } ! 823: #endif ! 824: delete(cursor, to); ! 825: } ! 826: ! 827: } /* end if doingdot else */ ! 828: ! 829: /* put the new text into a cut buffer for possible reuse */ ! 830: if (!doingdot) ! 831: { ! 832: blksync(); ! 833: cutname('.'); ! 834: cut(from, cursor); ! 835: } ! 836: ! 837: /* move to last char that we inputted, unless it was newline */ ! 838: if (markidx(cursor) != 0) ! 839: { ! 840: cursor--; ! 841: } ! 842: redraw(cursor, FALSE); ! 843: ! 844: #ifndef NO_EXTENSIONS ! 845: if (quit) ! 846: { ! 847: /* if this is a nested "do", then cut it short */ ! 848: abortdo(); ! 849: ! 850: /* exit, unless we can't write out the file */ ! 851: cursor = v_xit(cursor, 0L, 'Z'); ! 852: } ! 853: #endif ! 854: ! 855: rptlines = 0L; ! 856: return cursor; ! 857: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.