|
|
1.1 ! root 1: /****** KEYFUNCS.C - a collection of routines to service special keys ! 2: * each routine has the name of the key it services ! 3: */ ! 4: ! 5: #include <ctype.h> ! 6: #include <dos.h> ! 7: #include <doscalls.h> ! 8: #include <subcalls.h> ! 9: #include "ssedefs.h" ! 10: #include "keydefs.h" ! 11: ! 12: ! 13: /*** insert(c) - inserts the character c at the current cursor position ! 14: * ! 15: * This routine is called when any regular printable character is hit. ! 16: * ! 17: * insert(c) checks to see if there is room in EditBuff[] to insert the ! 18: * character it is passed by seeing if there is already a printable ! 19: * character in the 80th column. If so, no character can be inserted ! 20: * so we just call badkey(). If there is room, insert the character ! 21: * at the position indicated by CurCol and shift everything past that ! 22: * over one; mark EditBuff[] as dirty. ! 23: * ! 24: * If there is text that has been marked, insert() will call del() to ! 25: * remove it before inserting its character where the marked text was. ! 26: * ! 27: * The character we are passed has already been checked as being a ! 28: * valid printable characters. ! 29: * ! 30: * insert(c) ! 31: * ! 32: * ENTRY: c - the validated character to be inserted ! 33: * ! 34: * EFFECTS: EditBuff[] - changes its contents if successful ! 35: * EditBuffDirty - sets this flag if EditBuff changed ! 36: * LinesMarked - clears this if set ! 37: * CharsMarked - clears this if set ! 38: * CurCol - increments this one ! 39: * ! 40: * The effects of del() should also be considered since it may be ! 41: * called from this function. ! 42: */ ! 43: ! 44: insert(c) ! 45: char c; /* the character we are to insert, already validated */ ! 46: { ! 47: ! 48: register short i; /* indexing variable */ ! 49: ! 50: if (LinesMarked || CharsMarked) /* if there is marked text around, */ ! 51: del(); /* we first want to delete it */ ! 52: ! 53: if ( EditBuff[LINESIZE - 1] == ' ') /* can only insert when there's room */ ! 54: { ! 55: for ( i = (LINESIZE - 1); i > CurCol; i-- ) ! 56: EditBuff[i] = EditBuff[i-1]; /* shift everything over one */ ! 57: EditBuff[CurCol] = c; /* put in the new character */ ! 58: drawline(); ! 59: CurCol += 1; /* update display */ ! 60: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 61: EditBuffDirty = 1; /* mark edit buffer as dirty */ ! 62: } ! 63: ! 64: else badkey(); /* if no room, exit as for invalid key */ ! 65: ! 66: } ! 67: ! 68: ! 69: /*** up() - moves the cursor up one row ! 70: * ! 71: * up() moves the cursor position up one row. If we are at the top of ! 72: * the screen already, up() scrolls the screen down one line. If we ! 73: * are at the top of the file, it does nothing. If there is marked text ! 74: * around, up() will clear it without deleting. Because the current row ! 75: * in the file is changed by up(), EditBuff[] is flushed and refilled ! 76: * and line25() is called to update the line information at the bottom ! 77: * of the screen. ! 78: * ! 79: * EFFECTS: EditBuff[] - flushes its current contents and reloads ! 80: * EditBuffDirty - clears this flag ! 81: * LinesMarked - clears this flag ! 82: * MarkedLine[] - clears all ! 83: * CharsMarked - clears this flag ! 84: * MarkedChar[] - clears all ! 85: * TopRow - if at top of screen, decrements this one ! 86: * CurRow - otherwise, decrements this one ! 87: */ ! 88: ! 89: ! 90: void up() ! 91: { ! 92: ! 93: register short i; /* indexing variable */ ! 94: ! 95: char buff[2]; /* local buffer for scrolling fill character */ ! 96: buff[0] = 32; /* character = 32 = <blank> */ ! 97: buff[1] = ForeNorm; /* attribute = normal */ ! 98: ! 99: if (EditBuffDirty) { /* this call will change */ ! 100: EditBuffDirty = 0; /* cursor line, so flush */ ! 101: flushline((TopRow + CurRow), EditBuff); /* edit buffer if dirty */ ! 102: } ! 103: ! 104: if ( LinesMarked || CharsMarked ) { ! 105: LinesMarked = 0; /* if there's marked text */ ! 106: CharsMarked = 0; /* around, clear it and */ ! 107: for ( i = 0; i < MAXLINES; i++ ) /* redraw the screen */ ! 108: MarkedLine[i] = 0; ! 109: for ( i = 0; i < LINESIZE; i++ ) ! 110: MarkedChar[i] = 0; ! 111: drawscr(TopRow); ! 112: } ! 113: ! 114: if ( (TopRow + CurRow) != 0 ) { /* if top of file, do nothing */ ! 115: if ( CurRow == 0 ) { ! 116: TopRow -= 1; /* if top of screen, scroll down */ ! 117: VIOSCROLLDN( 0, 0, (PageSize - 1), (LINESIZE - 1), 1, ! 118: (char far *)buff, 0); ! 119: getline( (TopRow + CurRow), &EditBuff[0] ); ! 120: drawline(); ! 121: } ! 122: else { ! 123: CurRow -= 1; /* otherwise just move cursor up */ ! 124: getline( (TopRow + CurRow), &EditBuff[0] ); ! 125: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 126: } ! 127: } ! 128: ! 129: line25(); /* reset line numbers on 25th line to reflect change */ ! 130: ! 131: } ! 132: ! 133: ! 134: /*** down() - moves the cursor up one row ! 135: * ! 136: * down() moves the cursor down one row. If we are at the top of ! 137: * the screen already, down() scrolls the screen up one line. If we ! 138: * are at the end of the file, it does nothing. If there is marked text ! 139: * around, down() will clear it without deleting. Because the current row ! 140: * in the file is changed by down(), EditBuff[] is flushed and refilled ! 141: * and line25() is called to update the line information at the bottom ! 142: * of the screen. ! 143: * ! 144: * EFFECTS: EditBuff[] - flushes its current contents and reloads ! 145: * EditBuffDirty - clears this flag ! 146: * LinesMarked - clears this flag ! 147: * MarkedLine[] - clears all ! 148: * CharsMarked - clears this flag ! 149: * MarkedChar[] - clears all ! 150: * TopRow - if at bottom of screen, increments this one ! 151: * CurRow - otherwise, increments this one ! 152: */ ! 153: ! 154: ! 155: void down() ! 156: { ! 157: ! 158: register short i; /* indexing variable */ ! 159: ! 160: char buff[2]; /* local buffer for scrolling fill character */ ! 161: buff[0] = 32; /* character = 32 = <blank> */ ! 162: buff[1] = ForeNorm; /* attribute = normal */ ! 163: ! 164: if (EditBuffDirty) { /* this call will change */ ! 165: EditBuffDirty = 0; /* cursor line, so flush */ ! 166: flushline((TopRow + CurRow), EditBuff); /* edit buffer if dirty */ ! 167: } ! 168: ! 169: if ( LinesMarked || CharsMarked ) { ! 170: LinesMarked = 0; /* if there's marked text */ ! 171: CharsMarked = 0; /* around, clear it and */ ! 172: for ( i = 0; i < MAXLINES; i++ ) /* redraw the screen */ ! 173: MarkedLine[i] = 0; ! 174: for ( i = 0; i < LINESIZE; i++ ) ! 175: MarkedChar[i] = 0; ! 176: drawscr(TopRow); ! 177: } ! 178: ! 179: if ( (TopRow + CurRow) < (TotalLines) ) { /* if EOF, do nothing */ ! 180: if ( CurRow == (PageSize - 1) ) { /* if end of screen, scroll up */ ! 181: TopRow += 1; ! 182: VIOSCROLLUP( 0, 0, CurRow, (LINESIZE - 1), 1, ! 183: (char far *)buff, 0); ! 184: getline( (TopRow + CurRow), &EditBuff[0] ); ! 185: drawline(); ! 186: } ! 187: else { ! 188: CurRow += 1; /* else move cursor down */ ! 189: getline( (TopRow + CurRow), &EditBuff[0] ); ! 190: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 191: } ! 192: } ! 193: ! 194: line25(); /* reset line numbers on 25th line to reflect change */ ! 195: ! 196: } ! 197: ! 198: ! 199: /*** home() - moves the cursor to beginning of the line ! 200: * ! 201: * home() moves the cursor to the position of the first printable character ! 202: * in the current line. If there is marked text, home() will clear it ! 203: * without deleting. We need to be able to get correct information about ! 204: * the length of the current line from LineTable[], so we flush EditBuff[] ! 205: * on entry; but since the current line does not get changed, we do not ! 206: * reload it (current contents remain correct) and we do not call line25(). ! 207: * ! 208: * EFFECTS: EditBuffDirty - clears this flag ! 209: * LinesMarked - clears this flag ! 210: * MarkedLine[] - clears all ! 211: * CharsMarked - clears this flag ! 212: * MarkedChar[] - clears all ! 213: * CurCol - set to position of first printable character ! 214: */ ! 215: ! 216: void home() ! 217: { ! 218: ! 219: register short i, j; /* indexing variables */ ! 220: ! 221: ! 222: if (EditBuffDirty) { /* this call will need to */ ! 223: EditBuffDirty = 0; /* get correct info on */ ! 224: flushline((TopRow + CurRow), EditBuff); /* line length, so flush */ ! 225: } /* edit buffer if dirty */ ! 226: ! 227: if ( LinesMarked || CharsMarked ) { ! 228: LinesMarked = 0; /* if there's marked text */ ! 229: CharsMarked = 0; /* around, clear it and */ ! 230: for ( i = 0; i < MAXLINES; i++ ) /* redraw the screen */ ! 231: MarkedLine[i] = 0; ! 232: for ( i = 0; i < LINESIZE; i++ ) ! 233: MarkedChar[i] = 0; ! 234: drawscr(TopRow); ! 235: } ! 236: ! 237: if( (TopRow + CurRow) < TotalLines ) { ! 238: i = LineTable[TopRow + CurRow]->linelength; /* i is position of */ ! 239: i--; /* last char in line */ ! 240: } ! 241: else i = 0; /* if we're off the end of the file, that's 0... */ ! 242: ! 243: ! 244: for( j = 0; ( j <= i ) && !isgraph(EditBuff[j]); j++ ); ! 245: ! 246: CurCol = j; /* j is position of */ ! 247: VIOSETCURPOS( CurRow, CurCol, 0 ); /* first non-blank */ ! 248: ! 249: } ! 250: ! 251: ! 252: /*** end_() - moves the cursor to one position past the end of the current line ! 253: * ! 254: * end_() moves the cursor to one position beyond the position of the last ! 255: * printable character in the current line. If the last printable character ! 256: * is already in column 80, we just go there. If there is marked text, ! 257: * end_() will clear it without deleting. We need to be able to get correct ! 258: * information about the length of the current line from LineTable[], so ! 259: * we flush EditBuff[] on entry; but since the current line does not get ! 260: * changed, we do not reload it (current contents remain correct) and we ! 261: * do not call line25(). Note that this routine had to be named end_() not ! 262: * end() since that is a reserved word under the compiler used. ! 263: * ! 264: * EFFECTS: EditBuffDirty - clears this flag ! 265: * LinesMarked - clears this flag ! 266: * MarkedLine[] - clears all ! 267: * CharsMarked - clears this flag ! 268: * MarkedChar[] - clears all ! 269: * CurCol - set to position of last printable ! 270: * character, plus one if possible ! 271: */ ! 272: ! 273: void end_() ! 274: { ! 275: ! 276: register short i; /* indexing variable */ ! 277: ! 278: if (EditBuffDirty) { /* this call will need to */ ! 279: EditBuffDirty = 0; /* get correct info on */ ! 280: flushline((TopRow + CurRow), EditBuff); /* line length, so flush */ ! 281: } /* edit buffer if dirty */ ! 282: ! 283: if ( LinesMarked || CharsMarked ) { ! 284: LinesMarked = 0; /* if there's marked text */ ! 285: CharsMarked = 0; /* around, clear it and */ ! 286: for ( i = 0; i < MAXLINES; i++ ) /* redraw the screen */ ! 287: MarkedLine[i] = 0; ! 288: for ( i = 0; i < LINESIZE; i++ ) ! 289: MarkedChar[i] = 0; ! 290: drawscr(TopRow); ! 291: } ! 292: ! 293: if( (TopRow + CurRow) < TotalLines ) { ! 294: i = LineTable[TopRow + CurRow]->linelength; /* i is position of */ ! 295: } /* last char in line */ ! 296: else i = 0; ! 297: ! 298: CurCol = i; ! 299: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 300: ! 301: } ! 302: ! 303: ! 304: /*** pgup() - moves up one screen ! 305: * ! 306: * pgup() subtracts PageSize from the current value of TopRow and then ! 307: * redraws the screen, effectively moving us up one screen. If TopRow ! 308: * is less than PageSize, we just go to the start of the file. The ! 309: * position of the cursor on the screen is not altered. If there is marked ! 310: * text, pgup() will clear it without deleting. Because this call changes ! 311: * the current line, we flush and reload EditBuff[]. ! 312: * ! 313: * EFFECTS: EditBuff[] - flushes and reloads ! 314: * EditBuffDirty - clears this flag ! 315: * LinesMarked - clears this flag ! 316: * MarkedLine[] - clears all ! 317: * CharsMarked - clears this flag ! 318: * MarkedChar[] - clears all ! 319: * TopRow - gets PageSize subtracted from it ! 320: * if possible, otherwise set to 0. ! 321: */ ! 322: ! 323: void pgup() ! 324: { ! 325: ! 326: register short i; /* indexing variable */ ! 327: ! 328: if (EditBuffDirty) { /* this call will change */ ! 329: EditBuffDirty = 0; /* cursor line, so flush */ ! 330: flushline((TopRow + CurRow), EditBuff); /* edit buffer if dirty */ ! 331: } ! 332: ! 333: if ( LinesMarked || CharsMarked ) { ! 334: LinesMarked = 0; /* if there's marked text */ ! 335: CharsMarked = 0; /* around, clear it and */ ! 336: for ( i = 0; i < MAXLINES; i++ ) /* redraw the screen */ ! 337: MarkedLine[i] = 0; ! 338: for ( i = 0; i < LINESIZE; i++ ) ! 339: MarkedChar[i] = 0; ! 340: } ! 341: ! 342: if ( TopRow >= PageSize ) /* go up one page if there's room */ ! 343: TopRow -= PageSize; ! 344: else { ! 345: TopRow = 0; /* otherwise just go to top of file */ ! 346: CurRow = 0; ! 347: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 348: } ! 349: ! 350: drawscr(TopRow); /* redraw screen and */ ! 351: getline( (TopRow + CurRow), &EditBuff[0] ); /* update edit buffer */ ! 352: line25(); /* reset line numbers on 25th line to reflect change */ ! 353: ! 354: } ! 355: ! 356: ! 357: /*** pgdn() - moves down one screen ! 358: * ! 359: * pgdn() adds PageSize to the current value of TopRow and then ! 360: * redraws the screen, effectively moving us down one screen. If the ! 361: * result of adding TopRow and PageSize is greater than TotalLines ! 362: * (in other words, we would be moving off the end of the file), then ! 363: * we just move to one beyond the end of the file. The position of the ! 364: * cursor on the screen is not altered. If there is marked text, ! 365: * pgdn() will clear it without deleting. Because this call changes ! 366: * the current line, we flush and reload EditBuff[]. ! 367: * ! 368: * EFFECTS: EditBuff[] - flushes and reloads ! 369: * EditBuffDirty - clears this flag ! 370: * LinesMarked - clears this flag ! 371: * MarkedLine[] - clears all ! 372: * CharsMarked - clears this flag ! 373: * MarkedChar[] - clears all ! 374: * TopRow - gets PageSize added to it if possible, ! 375: * otherwise set to TotalLines - PageSize - 1. ! 376: */ ! 377: ! 378: void pgdn() ! 379: { ! 380: ! 381: register short i; /* indexing variable */ ! 382: ! 383: if (EditBuffDirty) { /* this call will change */ ! 384: EditBuffDirty = 0; /* cursor line, so flush */ ! 385: flushline((TopRow + CurRow), EditBuff); /* edit buffer if dirty */ ! 386: } ! 387: ! 388: if ( LinesMarked || CharsMarked ) { ! 389: LinesMarked = 0; /* if there's marked text */ ! 390: CharsMarked = 0; /* around, clear it */ ! 391: for ( i = 0; i < MAXLINES; i++ ) ! 392: MarkedLine[i] = 0; ! 393: for ( i = 0; i < LINESIZE; i++ ) ! 394: MarkedChar[i] = 0; ! 395: } ! 396: ! 397: TopRow += PageSize; /* go down one page */ ! 398: if ( TopRow > (TotalLines - (PageSize -1)) ) { /* if there's room, */ ! 399: TopRow = (TotalLines - (PageSize -1)); /* else stop at last */ ! 400: CurRow = (PageSize -1); /* full page */ ! 401: VIOSETCURPOS(CurRow, CurCol, 0); ! 402: } ! 403: ! 404: drawscr(TopRow); /* redraw screen and */ ! 405: getline( (TopRow + CurRow), &EditBuff[0] ); /* update edit buffer */ ! 406: line25(); /* reset line numbers on 25th line to reflect change */ ! 407: ! 408: } ! 409: ! 410: ! 411: /*** bksp() - deletes character to right of the cursor; moves cursor right one ! 412: * ! 413: * bksp() clears any marked text without deleting it, flushes EditBuff[], ! 414: * moves the cursor right one position and calls del(). If we're at the ! 415: * beginning of a line so there's nothing to our right, calls badkey(). ! 416: * ! 417: * EFFECTS: EditBuff[] - flushes and reloads ! 418: * EditBuffDirty - clears this flag ! 419: * LinesMarked - clears this flag ! 420: * MarkedLine[] - clears all ! 421: * CharsMarked - clears this flag ! 422: * MarkedChar[] - clears all ! 423: * CurCol - decrements if possible ! 424: * ! 425: * The effects of del() should also be considered since it may be ! 426: * called from this function. ! 427: */ ! 428: ! 429: void bksp() ! 430: { ! 431: ! 432: register short i; /* indexing variable */ ! 433: ! 434: if ( LinesMarked || CharsMarked ) { ! 435: LinesMarked = 0; /* if there's marked text */ ! 436: CharsMarked = 0; /* around, clear it and */ ! 437: for ( i = 0; i < MAXLINES; i++ ) /* redraw the screen */ ! 438: MarkedLine[i] = 0; ! 439: for ( i = 0; i < LINESIZE; i++ ) ! 440: MarkedChar[i] = 0; ! 441: ! 442: if (EditBuffDirty) { /* flush before redraw */ ! 443: EditBuffDirty = 0; /* to get any changes */ ! 444: flushline((TopRow + CurRow), EditBuff); ! 445: } ! 446: drawscr(TopRow); ! 447: } ! 448: ! 449: if( CurCol == 0 ) /* can't backspace if already at left edge */ ! 450: badkey(); ! 451: else { ! 452: CurCol -= 1; /* otherwise, move left one and del */ ! 453: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 454: del(); ! 455: } ! 456: } ! 457: ! 458: ! 459: /*** del() - deletes all indicated text ! 460: * ! 461: * del() is the function for deleting text. What gets deleted depends on ! 462: * what is marked. If there are marked lines around (as indicated by the ! 463: * LinesMarked flag) then we delete the marked lines, clear all the line ! 464: * marking flags, and adjust LineTable[] to reflect the change. Note that ! 465: * if there are lines marked, there cannot be characters marked too. If ! 466: * there are no lines marked, but characters marked, these characters are ! 467: * deleted and EditBuff[] is adjusted to reflect the change and flagged ! 468: * as dirty. If there are no lines or characters marked, then the character ! 469: * under the cursor is deleted and EditBuff[] is adjusted accordingly and ! 470: * marked as dirty. ! 471: * ! 472: * EFFECTS: EditBuff[] - contents altered if no lines were marked ! 473: * EditBuffDirty - set if no lines were marked ! 474: * LineTable[] - contents altered if lines were marked ! 475: * TotalLines - altered if lines were marked ! 476: * LinesMarked - clears this flag ! 477: * MarkedLine[] - clears all ! 478: * CharsMarked - clears this flag ! 479: * MarkedChar[] - clears all ! 480: * TopRow - may change, depending on what's marked ! 481: * CurRow - may change, depending on what's marked ! 482: * ! 483: */ ! 484: ! 485: void del() ! 486: { ! 487: ! 488: register short i, j; /* indexing variables */ ! 489: ! 490: if (LinesMarked) { /* if lines are marked, do this */ ! 491: for( i = 0; !MarkedLine[i]; i++ ); ! 492: j = i; /* i, j refer to first marked line */ ! 493: if( i <= TopRow ) { ! 494: if( i != 0 ) { ! 495: TopRow = i - 1; /* if first line to be deleted is */ ! 496: CurRow = 1; /* off the top of the screen, then */ ! 497: } /* set TopRow to last unmarked line */ ! 498: else { ! 499: TopRow = 0; /* or if there are no unmarked */ ! 500: CurRow = 0; /* lines ahead of the marked ones, */ ! 501: } /* set TopRow to start of the file */ ! 502: } ! 503: else CurRow = i - TopRow; ! 504: for( ; MarkedLine[i]; i++ ) /* delete all marked lines */ ! 505: deleteline( i ); /* i refers to first unmarked line */ ! 506: for( ; i < TotalLines; i++,j++ ) /* adjust LineTable[] */ ! 507: LineTable[j] = LineTable[i]; ! 508: TotalLines -= ( i - j ); /* adjust TotalLines */ ! 509: LinesMarked = 0; ! 510: for( i = 0; i < MAXLINES; i++ ) /* clear line marking flags */ ! 511: MarkedLine[i] = 0; ! 512: drawscr(TopRow); /* redraw screen */ ! 513: VIOSETCURPOS(CurRow, CurCol, 0); ! 514: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload EditBuff[] */ ! 515: } ! 516: ! 517: else if (CharsMarked) { /* if no lines marked but chars marked, do this */ ! 518: for( i = 0; !MarkedChar[i] & ( i < LINESIZE ); i++ ); ! 519: j = i; /* i, j refer to first marked character */ ! 520: CurCol = j; ! 521: VIOSETCURPOS(CurRow, CurCol, 0); /* adjust cursor position */ ! 522: for( ; MarkedChar[i] & (i < LINESIZE); i++ ); /* i now first unmarked */ ! 523: for( ; i < LINESIZE; i++, j++ ) ! 524: EditBuff[j] = EditBuff[i]; /* remove characters between i and j */ ! 525: for( ; j < LINESIZE; j++ ) ! 526: EditBuff[j] = ' '; /* fill end of line with blanks */ ! 527: CharsMarked = 0; ! 528: for( i = 0; i < LINESIZE; i++ ) /* clear all character marking flags */ ! 529: MarkedChar[i] = 0; ! 530: drawline(); /* redraw line */ ! 531: EditBuffDirty = 1; /* mark EditBuff[] as dirty */ ! 532: } ! 533: ! 534: else { /* if no lines or chars marked, do this */ ! 535: for( i = (CurCol + 1); i < LINESIZE; i++ ) ! 536: EditBuff[i-1] = EditBuff[i]; /* remove character under cursor */ ! 537: EditBuff[LINESIZE-1] = ' '; /* fill end of line with blank */ ! 538: drawline(); /* redraw line */ ! 539: EditBuffDirty = 1; /* mark EditBuff[] as dirty */ ! 540: } ! 541: ! 542: line25(); /* reset line numbers on 25th line to reflect changes */ ! 543: ! 544: } ! 545: ! 546: ! 547: /*** F9() - saves the file being edited and exits ! 548: * ! 549: * F9() save the file being edited with any changes that have been made ! 550: * and exits the editor. The user is given a prompt to be sure they want ! 551: * do quit; hitting carriage return goes ahead with the save-and-quit, ! 552: * while any other key returns you to the editor. ! 553: * ! 554: * EFFECTS: If quit not completed: EditBuff[] - gets flushed ! 555: * EditBuffDirty - gets cleared ! 556: */ ! 557: ! 558: void F9() ! 559: { ! 560: ! 561: static char message[LINESIZE] = "Save file as:"; ! 562: struct KeyData keydata; ! 563: char attrib = Fore25 + Back25; ! 564: int i; ! 565: ! 566: if (EditBuffDirty) { /* flush the edit buffer if dirty */ ! 567: EditBuffDirty = 0; /* so all editting will be saved */ ! 568: flushline((TopRow + CurRow), EditBuff); ! 569: } ! 570: ! 571: for( i = 0; (i < 65) && (fname[i] != 0); message[i + 14] = fname[i], i++ ); ! 572: /* copy filename into prompt message */ ! 573: ! 574: VIOWRTCHARSTRATT( message, 80, PageSize, 0, &attrib, 0 ); ! 575: /* write out message */ ! 576: ! 577: KBDCHARIN( &keydata, 0, 0 ); /* wait for user response */ ! 578: ! 579: if( keydata.char_code == CRETURN_CHAR ) { /* if response was <CR>... */ ! 580: if ( !savefile(fhandle)) { ! 581: freesegs(); ! 582: VIOSETCURPOS( 24, 0, 0 ); /* ... clean up and quit */ ! 583: quit(0); ! 584: } ! 585: else error25(11); ! 586: } ! 587: name25(); /* ... otherwise restore message on */ ! 588: /* 25th line and return to editor */ ! 589: } ! 590: ! 591: ! 592: /*** F10() - exits the editor without saving the file being edited ! 593: * ! 594: * F10() exits from the editor without saving back the file being edited, ! 595: * leaving the file as it was before the editor was invoked. A prompt ! 596: * will be issued to give the user a chance to change their mind before ! 597: * all editing is lost. ! 598: * ! 599: * EFFECTS: If quit not completed: EditBuff[] - gets flushed ! 600: * EditBuffDirty - gets cleared ! 601: */ ! 602: ! 603: ! 604: void F10() ! 605: { ! 606: static char message[51] = "WARNING: Any edits will be lost (y/n)? "; ! 607: struct KeyData keydata; ! 608: char attrib = Fore25 + Back25; /* attributes for message */ ! 609: int row, col; /* to save current cursor position */ ! 610: int done = 0; /* flag to be set when have a valid response */ ! 611: ! 612: if (EditBuffDirty) { /* flush EditBuff[] if dirty */ ! 613: EditBuffDirty = 0; ! 614: flushline((TopRow + CurRow), EditBuff); ! 615: } ! 616: ! 617: VIOWRTCHARSTRATT( message, 51, PageSize, 0, &attrib, 0 ); ! 618: VIOGETCURPOS( &row, &col, 0 ); /* print prompt and set */ ! 619: VIOSETCURPOS( PageSize, 42, 0 ); /* cursor to await reply */ ! 620: ! 621: while( !done ) { ! 622: ! 623: KBDCHARIN( &keydata, 0, 0 ); /* get a character from KBD */ ! 624: ! 625: if( (keydata.char_code == 'y') || (keydata.char_code == 'Y') ) { ! 626: VIOWRTCHARSTRATT( &keydata.char_code, 1, PageSize, 42, &attrib, 0 ); ! 627: freesegs(); ! 628: quit(0); /* if Y, quit without saving */ ! 629: } ! 630: else if( (keydata.char_code == 'n') || (keydata.char_code == 'N') ) { ! 631: VIOSETCURPOS( row, col, 0 ); ! 632: name25(); ! 633: done = 1; /* if N, return to editor */ ! 634: } ! 635: else badkey(); /* otherwise wait for another key */ ! 636: ! 637: } ! 638: ! 639: } ! 640: ! 641: ! 642: /*** ctrl_home() - repositions cursor to upper left hand corner of screen ! 643: * ! 644: * ctrl_home() moves the cursor to the upper left hand corner of the ! 645: * screen, coordinate position (0,0). Since the current cursor line is ! 646: * probably changed, we flush and reload EditBuff[]. If there is any ! 647: * text marked, this call will clear the marking without deleting. ! 648: * Line number information on 25th line is redrawn to reflect changes. ! 649: * The actual content of the screen - i.e. the value of TopRow - is ! 650: * unchanged by this call. ! 651: * ! 652: * EFFECTS: EditBuff[] - flushes and reloads ! 653: * EditBuffDirty - clears this flag ! 654: * LinesMarked - clears this flag ! 655: * MarkedLine[] - clears all ! 656: * CharsMarked - clears this flag ! 657: * MarkedChar[] - clears all ! 658: * CurRow - set to 0 ! 659: * CurCol - set to 0 ! 660: */ ! 661: ! 662: void ctrl_home() ! 663: { ! 664: ! 665: register short i; /* indexing variable */ ! 666: ! 667: if (EditBuffDirty) { /* this call will change */ ! 668: EditBuffDirty = 0; /* cursor line, so flush */ ! 669: flushline((TopRow + CurRow), EditBuff); /* edit buffer if dirty */ ! 670: } ! 671: ! 672: if ( LinesMarked || CharsMarked ) { ! 673: LinesMarked = 0; /* if there's marked text */ ! 674: CharsMarked = 0; /* around, clear it and */ ! 675: for ( i = 0; i < MAXLINES; i++ ) /* redraw the screen */ ! 676: MarkedLine[i] = 0; ! 677: for ( i = 0; i < LINESIZE; i++ ) ! 678: MarkedChar[i] = 0; ! 679: drawscr(TopRow); ! 680: } ! 681: ! 682: if ( CurRow != 0 || CurCol != 0 ) { ! 683: CurRow = 0; /* reposition to (0,0) */ ! 684: CurCol = 0; ! 685: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 686: getline( (TopRow + CurRow), &EditBuff[0] ); ! 687: } ! 688: ! 689: line25(); /* update line numbers on 25th line to reflect changes */ ! 690: ! 691: } ! 692: ! 693: ! 694: /*** ctrl_end() - repositions cursor to lower left hand corner of screen ! 695: * ! 696: * ctrl_end() moves the cursor to the lower left hand corner of the ! 697: * screen. Since the current cursor line is probably changed, we flush ! 698: * and reload EditBuff[]. If there is any text marked, this call will ! 699: * clear the marking without deleting. Line number information on 25th ! 700: * line is redrawn to reflect changes. The actual content of the screen ! 701: * is unchanged by this call. ! 702: * ! 703: * EFFECTS: EditBuff[] - flushes and reloads ! 704: * EditBuffDirty - clears this flag ! 705: * LinesMarked - clears this flag ! 706: * MarkedLine[] - clears all ! 707: * CharsMarked - clears this flag ! 708: * MarkedChar[] - clears all ! 709: * CurRow - set to PAGESIZE - 1 ! 710: * CurCol - set to 0 ! 711: */ ! 712: ! 713: void ctrl_end() ! 714: { ! 715: ! 716: register short i; ! 717: ! 718: if (EditBuffDirty) { /* this call will change */ ! 719: EditBuffDirty = 0; /* cursor line, so flush */ ! 720: flushline((TopRow + CurRow), EditBuff); /* edit buffer if dirty */ ! 721: } ! 722: ! 723: if ( LinesMarked || CharsMarked ) { ! 724: LinesMarked = 0; /* if there's marked text */ ! 725: CharsMarked = 0; /* around, clear it and */ ! 726: for ( i = 0; i < MAXLINES; i++ ) /* redraw the screen */ ! 727: MarkedLine[i] = 0; ! 728: for ( i = 0; i < LINESIZE; i++ ) ! 729: MarkedChar[i] = 0; ! 730: drawscr(TopRow); ! 731: } ! 732: ! 733: if( CurRow != (PageSize - 1) || CurCol != 0 ) { ! 734: CurRow = (PageSize - 1); /* reposition cursor */ ! 735: CurCol = 0; ! 736: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 737: getline( (TopRow + CurRow), &EditBuff[0] ); ! 738: } ! 739: ! 740: line25(); /* update line numbers on 25th line to reflect changes */ ! 741: ! 742: } ! 743: ! 744: ! 745: /*** ctrl_pgup() - repositions cursor to beginning of file ! 746: * ! 747: * ctrl_pgup() redraws the screen with the first screenfull of the file ! 748: * and moves the cursor to the upper left hand corner of the screen, ! 749: * coordinate position (0,0). Since the current cursor line is ! 750: * probably changed, we flush and reload EditBuff[]. If there is any ! 751: * text marked, this call will clear the marking without deleting. ! 752: * Line number information on 25th line is redrawn to reflect changes. ! 753: * ! 754: * EFFECTS: EditBuff[] - flushes and reloads ! 755: * EditBuffDirty - clears this flag ! 756: * LinesMarked - clears this flag ! 757: * MarkedLine[] - clears all ! 758: * CharsMarked - clears this flag ! 759: * MarkedChar[] - clears all ! 760: * TopRow - set to 0 ! 761: * CurRow - set to 0 ! 762: * CurCol - set to 0 ! 763: */ ! 764: ! 765: void ctrl_pgup() ! 766: { ! 767: ! 768: register short i; /* indexing variable */ ! 769: ! 770: if (EditBuffDirty) { /* this call will change */ ! 771: EditBuffDirty = 0; /* cursor line, so flush */ ! 772: flushline((TopRow + CurRow), EditBuff); /* edit buffer if dirty */ ! 773: } ! 774: ! 775: if ( LinesMarked || CharsMarked ) { ! 776: LinesMarked = 0; /* if there's marked text */ ! 777: CharsMarked = 0; /* around, clear it - no */ ! 778: for ( i = 0; i < MAXLINES; i++ ) /* need to redraw screen */ ! 779: MarkedLine[i] = 0; ! 780: for ( i = 0; i < LINESIZE; i++ ) ! 781: MarkedChar[i] = 0; ! 782: } ! 783: ! 784: TopRow = 0; ! 785: CurRow = 0; /* reposition and redraw */ ! 786: CurCol = 0; ! 787: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 788: drawscr(TopRow); ! 789: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload EditBuff[] */ ! 790: line25(); /* update 25th line */ ! 791: ! 792: } ! 793: ! 794: ! 795: /*** ctrl_pgdn() - repositions cursor to beginning of file ! 796: * ! 797: * ctrl_pgdn() redraws the screen with the last screenfull of the file ! 798: * and moves the cursor to the lower left hand corner of the screen, ! 799: * one line past the end of the file. Since the current cursor line is ! 800: * probably changed, we flush and reload EditBuff[]. If there is any ! 801: * text marked, this call will clear the marking without deleting. ! 802: * Line number information on 25th line is redrawn to reflect changes. ! 803: * ! 804: * EFFECTS: EditBuff[] - flushes and reloads ! 805: * EditBuffDirty - clears this flag ! 806: * LinesMarked - clears this flag ! 807: * MarkedLine[] - clears all ! 808: * CharsMarked - clears this flag ! 809: * MarkedChar[] - clears all ! 810: * TopRow - set to TotalLines - (PageSize - 1) ! 811: * CurRow - set to end of file + 1 ! 812: * CurCol - set to 0 ! 813: */ ! 814: ! 815: void ctrl_pgdn() ! 816: { ! 817: register short i; /* indexing variable */ ! 818: ! 819: if (EditBuffDirty) { /* this call will change */ ! 820: EditBuffDirty = 0; /* cursor line, so flush */ ! 821: flushline((TopRow + CurRow), EditBuff); /* edit buffer if dirty */ ! 822: } ! 823: ! 824: if ( LinesMarked || CharsMarked ) { ! 825: LinesMarked = 0; /* if there's marked text */ ! 826: CharsMarked = 0; /* around, clear it - no */ ! 827: for ( i = 0; i < MAXLINES; i++ ) /* need to redraw screen */ ! 828: MarkedLine[i] = 0; /* as it gets done later */ ! 829: for ( i = 0; i < LINESIZE; i++ ) ! 830: MarkedChar[i] = 0; ! 831: } ! 832: if (TotalLines > (PageSize - 1)) ! 833: TopRow = TotalLines - (PageSize - 1); /* recalculate TopRow */ ! 834: else TopRow = 0; ! 835: CurRow = TotalLines - TopRow; /* set cursor row and column */ ! 836: CurCol = 0; ! 837: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 838: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload EditBuff[] */ ! 839: drawscr(TopRow); /* redraw screen */ ! 840: line25(); /* update 25th line */ ! 841: ! 842: } ! 843: ! 844: ! 845: /*** shift_left() - moves cursor left one and marks that character for deletion. ! 846: * ! 847: * shift_left() moves the cursor one position to the left. If we are on ! 848: * a line that is already marked, that's all it does - just like regular ! 849: * left, but markings are not cleared. If we are not on a marked line, ! 850: * then the character we just moved to is marked for deletion. Unless it ! 851: * already was marked for deletion, in which case it gets un-marked. ! 852: * ! 853: * EFFECTS: CharsMarked - sets this flag if LinesMarked not set ! 854: * MarkedChar[] - sets this for the character we just moved to ! 855: * CurCol - decremented one ! 856: */ ! 857: ! 858: void shift_left() ! 859: { ! 860: ! 861: if ( LinesMarked ) { /* if this line is marked, just move left */ ! 862: if ( CurCol > 0 ) { ! 863: CurCol -= 1; ! 864: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 865: } ! 866: } ! 867: else if( CurCol > 0 ) { /* otherwise, see if there's room... */ ! 868: CurCol -= 1; ! 869: VIOSETCURPOS( CurRow, CurCol, 0 ); /* ...if so move left */ ! 870: CharsMarked = 1; ! 871: if (MarkedChar[CurCol]) ! 872: MarkedChar[CurCol] = 0; /* and set marking for that character */ ! 873: else MarkedChar[CurCol] = 1; ! 874: drawline(); /* redraw line to update markings */ ! 875: } ! 876: ! 877: } ! 878: ! 879: ! 880: /*** shift_right() - moves cursor right one and marks the character ! 881: * we were previously on for deletion. ! 882: * ! 883: * shift_right() moves the cursor one position to the right. If we are on ! 884: * a line that is already marked, that's all it does - just like regular ! 885: * right, but markings are not cleared. If we are not on a marked line, ! 886: * then the character we just moved from is marked for deletion. Unless it ! 887: * already was marked for deletion, in which case it gets un-marked. ! 888: * ! 889: * EFFECTS: CharsMarked - sets this flag if LinesMarked not set ! 890: * MarkedChar[] - sets this for the character we just left ! 891: * CurCol - incremented one ! 892: */ ! 893: ! 894: void shift_right() ! 895: { ! 896: ! 897: if ( LinesMarked ) { /* if this line marked, just move right */ ! 898: if (CurCol < (LINESIZE - 1)) { ! 899: CurCol += 1; ! 900: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 901: } ! 902: } ! 903: else if( CurCol < (LINESIZE - 1)) { /* otherwise, see if there's room.. */ ! 904: CharsMarked = 1; ! 905: if (MarkedChar[CurCol]) /* if so, mark character we're on */ ! 906: MarkedChar[CurCol] = 0; ! 907: else MarkedChar[CurCol] = 1; ! 908: CurCol += 1; /* then move right one */ ! 909: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 910: drawline(); /* and redraw line */ ! 911: } ! 912: ! 913: } ! 914: ! 915: ! 916: /*** shift_up() - moves cursor up one line and marks lines for deletion ! 917: * ! 918: * shift_up() moves the cursor one line up. If no lines are marked, then ! 919: * both the previous line and the line moved to get marked for deletion. ! 920: * If lines are already marked, and were marked starting with another ! 921: * shift_up, then only the line we move to gets marked (the one we just ! 922: * left would already be marked). If there are lines marked but they ! 923: * were marked starting with a shift_down, then we un-mark the line we ! 924: * just left and do nothing to the line moved to. Unless the line moved ! 925: * to is the last one marked, in which case we un-mark it also to clear all ! 926: * markings. To determine how lines first got marked - by a shift_up or ! 927: * shift_down - we give the flag LinesMarked two different TRUE values, ! 928: * 1 or 2 respectively. ! 929: * ! 930: * EFFECTS: EditBuff[] - flushes and reloads ! 931: * EditBuffDirty - clears ! 932: * LinesMarked - sets this flag, unless un-marking only ! 933: * marked line present, in which case clears it ! 934: * MarkedLine[] - may set or clear this ! 935: * CharsMarked - clears this flag as we now have marked lines ! 936: * MarkedChar[] - clears all ! 937: * TopRow - decremented one if at top of page ! 938: * CurRow - decremented one if not at top of page ! 939: */ ! 940: ! 941: void shift_up() ! 942: { ! 943: register short i; /* indexing variable */ ! 944: ! 945: char buff[2]; /* local buffer for scrolling fill character */ ! 946: buff[0] = 32; /* character = 32 = <blank> */ ! 947: buff[1] = ForeHilite + BackHilite; /* attribute = highlighted */ ! 948: ! 949: if (EditBuffDirty) { /* this call will change */ ! 950: EditBuffDirty = 0; /* cursor line, so flush */ ! 951: flushline((TopRow + CurRow), EditBuff); /* edit buffer if dirty */ ! 952: } ! 953: ! 954: if ( CharsMarked ) { /* clear CharsMarked flags */ ! 955: CharsMarked = 0; /* since we now will have */ ! 956: for ( i = 0; i < LINESIZE; i++ ) /* the whole line marked. */ ! 957: MarkedChar[i] = 0; ! 958: } ! 959: ! 960: /* if no lines currently marked, do this */ ! 961: if( !LinesMarked ) { ! 962: LinesMarked = 1; /* set flag to indicate marking started UP */ ! 963: MarkedLine[ TopRow + CurRow ] = 1; /* mark line */ ! 964: drawline(); /* redraw it */ ! 965: if ( (TopRow + CurRow) != 0 ) { /* if there's room, */ ! 966: MarkedLine[ TopRow + CurRow - 1 ] = 1; /* mark line above */ ! 967: if ( CurRow == 0 ) { ! 968: TopRow -= 1; /* ...may have to scroll */ ! 969: VIOSCROLLDN( 0, 0, (PageSize - 1), (LINESIZE - 1), 1, ! 970: (char far *)buff, 0); ! 971: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 972: } ! 973: else { /* ...or may not have to scroll */ ! 974: CurRow -= 1; ! 975: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 976: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 977: } ! 978: drawline(); /* redraw new line */ ! 979: } ! 980: } ! 981: ! 982: /* if lines marked, and shift_up started marking, do this */ ! 983: else if( LinesMarked == 1 ) { ! 984: if ( (TopRow + CurRow) != 0 ) { /* if not at top of screen, */ ! 985: MarkedLine[ TopRow + CurRow - 1 ] = 1; /* mark next line up */ ! 986: if ( CurRow == 0 ) { ! 987: TopRow -= 1; /* ...may have to scroll */ ! 988: VIOSCROLLDN( 0, 0, (PageSize - 1), (LINESIZE - 1), 1, ! 989: (char far *)buff, 0); ! 990: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 991: } ! 992: else { ! 993: CurRow -= 1; /* ...or may not have to scroll */ ! 994: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 995: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 996: } ! 997: drawline(); /* redraw line move to */ ! 998: } ! 999: } ! 1000: ! 1001: /* if lines marked, and shift_down started marking, do this */ ! 1002: else if( LinesMarked == 2 ) { ! 1003: MarkedLine[ TopRow + CurRow ] = 0; /* un-mark current line */ ! 1004: drawline(); /* redraw it */ ! 1005: if( (TopRow + CurRow) != 0 ) { ! 1006: if( CurRow == 0 ) { /* ...may have to scroll down */ ! 1007: TopRow -= 1; ! 1008: VIOSCROLLDN( 0, 0, (PageSize - 1), (LINESIZE - 1), 1, ! 1009: (char far *)buff, 0); ! 1010: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 1011: } ! 1012: else { /* or may not have to scroll down */ ! 1013: CurRow -= 1; ! 1014: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 1015: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 1016: } ! 1017: if( !MarkedLine[ TopRow + CurRow - 1 ] ) { /* if line moved to */ ! 1018: MarkedLine[ TopRow + CurRow ] = 0; /* is last marked, */ ! 1019: LinesMarked = 0; /* clear it too */ ! 1020: drawline(); ! 1021: } ! 1022: } ! 1023: } ! 1024: ! 1025: line25(); /* update line numbers on 25th line to reflect changes */ ! 1026: ! 1027: } ! 1028: ! 1029: ! 1030: /*** shift_down() - moves cursor down one line and marks lines for deletion ! 1031: * ! 1032: * shift_down() moves the cursor one line down. If no lines are marked, then ! 1033: * both the previous line and the line moved to get marked for deletion. ! 1034: * If lines are already marked, and were marked starting with another ! 1035: * shift_down, then only the line we move to gets marked (the one we just ! 1036: * left would already be marked). If there are lines marked but they ! 1037: * were marked starting with a shift_up, then we un-mark the line we ! 1038: * just left and do nothing to the line moved to. Unless the line moved ! 1039: * to is the last one marked, in which case we un-mark it also to clear all ! 1040: * markings. To determine how lines first got marked - by a shift_up or ! 1041: * shift_down - we give the flag LinesMarked two different TRUE values, ! 1042: * 1 or 2 respectively. ! 1043: * ! 1044: * EFFECTS: EditBuff[] - flushes and reloads ! 1045: * EditBuffDirty - clears ! 1046: * LinesMarked - sets this flag, unless un-marking only ! 1047: * marked line present, in which case clears it ! 1048: * MarkedLine[] - may set or clear this ! 1049: * CharsMarked - clears this flag as we now have marked lines ! 1050: * MarkedChar[] - clears all ! 1051: * TopRow - incremented one if at bottom of page ! 1052: * CurRow - incremented one if not at bottom of page ! 1053: */ ! 1054: ! 1055: void shift_down() ! 1056: { ! 1057: register short i; /* indexing variable */ ! 1058: ! 1059: char buff[2]; /* local buffer for fill character */ ! 1060: buff[0] = 32; /* character = 32 = <blank> */ ! 1061: buff[1] = ForeHilite + BackHilite; /* attribute = highlighted */ ! 1062: ! 1063: if (EditBuffDirty) { /* this call will change */ ! 1064: EditBuffDirty = 0; /* cursor line, so flush */ ! 1065: flushline((TopRow + CurRow), EditBuff); /* edit buffer if dirty */ ! 1066: } ! 1067: ! 1068: if ( CharsMarked ) { /* clear all character */ ! 1069: CharsMarked = 0; /* markings, since line */ ! 1070: for ( i = 0; i < LINESIZE; i++ ) /* is now marked. */ ! 1071: MarkedChar[i] = 0; ! 1072: } ! 1073: ! 1074: /* if no lines are currently marked, do this */ ! 1075: if( !LinesMarked ) { ! 1076: LinesMarked = 2; /* set flag to show marking started with DOWN */ ! 1077: MarkedLine[ TopRow + CurRow ] = 1; /* mark current line */ ! 1078: drawline(); /* and redraw it */ ! 1079: if( ( TopRow + CurRow ) < TotalLines ) { /* if room to move down, */ ! 1080: MarkedLine[ TopRow + CurRow + 1 ] = 1; /* mark line below */ ! 1081: if ( CurRow == (PageSize - 1) ) { ! 1082: TopRow += 1; /* ...may have to scroll */ ! 1083: VIOSCROLLUP( 0, 0, CurRow, (LINESIZE - 1), 1, ! 1084: (char far *)buff, 0); ! 1085: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 1086: } ! 1087: else { /* ...or may not have to scroll */ ! 1088: CurRow += 1; ! 1089: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 1090: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 1091: } ! 1092: drawline(); /* redraw new line */ ! 1093: } ! 1094: } ! 1095: ! 1096: /* if lines are marked, and first marking was another shift_down, do this */ ! 1097: else if( LinesMarked == 2 ) { ! 1098: if ( (TopRow + CurRow) < TotalLines ) { /* if room to move down */ ! 1099: MarkedLine[ TopRow + CurRow + 1 ] = 1; /* mark line below */ ! 1100: if ( CurRow == (PageSize - 1) ) { ! 1101: TopRow += 1; /* ...may have to scroll */ ! 1102: VIOSCROLLUP( 0, 0, CurRow, (LINESIZE - 1), 1, ! 1103: (char far *)buff, 0); ! 1104: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 1105: } ! 1106: else { /* ...or may not have to scroll */ ! 1107: CurRow += 1; ! 1108: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 1109: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 1110: } ! 1111: drawline(); /* redraw the current line to show markings */ ! 1112: } ! 1113: } ! 1114: ! 1115: /* if lines are marked, and first marking was a shift_up, do this */ ! 1116: else if( LinesMarked == 1 ) { ! 1117: MarkedLine[ TopRow + CurRow ] = 0; /* un-mark current line */ ! 1118: drawline(); /* and redraw it */ ! 1119: if ( (TopRow + CurRow) < TotalLines ) { ! 1120: if ( CurRow == (PageSize - 1) ) { ! 1121: TopRow += 1; /* ...may have to scroll */ ! 1122: VIOSCROLLUP( 0, 0, CurRow, (LINESIZE - 1), 1, ! 1123: (char far *)buff, 0); ! 1124: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 1125: } ! 1126: else { /* ...or may not have to scroll */ ! 1127: CurRow += 1; ! 1128: getline( (TopRow + CurRow), &EditBuff[0] ); /* reload */ ! 1129: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 1130: } ! 1131: } ! 1132: if( (TopRow + CurRow) < TotalLines ) { ! 1133: if( !MarkedLine[ TopRow + CurRow + 1 ] ) { ! 1134: MarkedLine[ TopRow + CurRow ] = 0; ! 1135: LinesMarked = 0; /* if only 1 line left */ ! 1136: } /* marked, un-mark it too */ ! 1137: } ! 1138: drawline(); /* redraw line to reflect markings */ ! 1139: ! 1140: } ! 1141: ! 1142: line25(); /* update line info on bottom line to show changes */ ! 1143: ! 1144: } ! 1145: ! 1146: ! 1147: /*** shift_home() - moves cursor to first character in current line and ! 1148: * marks all characters in between for deletion ! 1149: * ! 1150: * shift_down() moves the cursor to the first printable character in the ! 1151: * current line. If the line is already marked, that's all it does, just ! 1152: * like a regular home except markings are not cleared. Otherwise, all ! 1153: * characters between the cursor position when the function is called and ! 1154: * the first character in the line get their markings toggled - that is, if ! 1155: * they are not marked they get marked, if they are already marked they ! 1156: * get un-marked. ! 1157: * ! 1158: * EFFECTS: EditBuff[] - flushes and reloads ! 1159: * EditBuffDirty - clears ! 1160: * CharsMarked - sets this flag unless line is marked ! 1161: * MarkedChar[] - sets for all appropriate characters ! 1162: * CurCol - set to position of first printable character ! 1163: */ ! 1164: ! 1165: void shift_home() ! 1166: { ! 1167: ! 1168: register short i, j; /* indexing variables */ ! 1169: ! 1170: if (EditBuffDirty) { /* this call will need to */ ! 1171: EditBuffDirty = 0; /* get correct info on */ ! 1172: flushline((TopRow + CurRow), EditBuff); /* line length, so flush */ ! 1173: } /* edit buffer if dirty */ ! 1174: ! 1175: if( (TopRow + CurRow) < TotalLines ) { ! 1176: i = LineTable[TopRow + CurRow]->linelength; /* i is position + 1 */ ! 1177: } /* last char in line */ ! 1178: else i = 0; ! 1179: ! 1180: for( j = 0; ( j < i ) && !isgraph(EditBuff[j]); j++ ); ! 1181: /* j is position of */ ! 1182: /* first non-blank */ ! 1183: if( !LinesMarked ) { /* if no lines marked, */ ! 1184: if( j < CurCol ) { /* flag everything between */ ! 1185: CharsMarked = 1; /* CurCol and j as Marked */ ! 1186: for( i = j; i < CurCol; i++ ) { ! 1187: if( !MarkedChar[i] ) ! 1188: MarkedChar[i] = 1; /* may be moving forward... */ ! 1189: else MarkedChar[i] = 0; ! 1190: } ! 1191: } ! 1192: else if( j > CurCol ) { ! 1193: CharsMarked = 1; ! 1194: for( i = CurCol; i < j; i++ ) { /* ... or backward */ ! 1195: if( !MarkedChar[i] ) ! 1196: MarkedChar[i] = 1; ! 1197: else MarkedChar[i] = 0; ! 1198: } ! 1199: } ! 1200: } ! 1201: ! 1202: CurCol = j; /* if lines are marked, just move */ ! 1203: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 1204: drawline(); /* redraw line to show markings */ ! 1205: ! 1206: } ! 1207: ! 1208: ! 1209: /*** shift_end() - moves cursor to one beyond last character in current line ! 1210: * and marks all characters in between for deletion ! 1211: * ! 1212: * shift_down() moves the cursor to one position beyond the last printable ! 1213: * character in the current line. If the line is already marked, that's all ! 1214: * it does, just like a regular end_ except markings are not cleared. ! 1215: * Otherwise, all characters between the cursor position when the function ! 1216: * is called and the final cursor position get their markings toggled - that ! 1217: * is, if they are not marked they get marked, if they are already marked ! 1218: * they get un-marked. ! 1219: * ! 1220: * EFFECTS: EditBuff[] - flushes and reloads ! 1221: * EditBuffDirty - clears ! 1222: * CharsMarked - sets this flag unless line is marked ! 1223: * MarkedChar[] - sets for all appropriate characters ! 1224: * CurCol - set to one beyond position of ! 1225: * last printable character ! 1226: */ ! 1227: ! 1228: void shift_end() ! 1229: { ! 1230: ! 1231: register short i, j; /* indexing variables */ ! 1232: ! 1233: if (EditBuffDirty) { /* this call will need to */ ! 1234: EditBuffDirty = 0; /* get correct info on */ ! 1235: flushline((TopRow + CurRow), EditBuff); /* line length, so flush */ ! 1236: } /* edit buffer if dirty */ ! 1237: ! 1238: if( (TopRow + CurRow) < TotalLines ) { ! 1239: i = LineTable[TopRow + CurRow]->linelength; /* i is position + 1 */ ! 1240: } /* last char in line */ ! 1241: else i = 0; ! 1242: ! 1243: if( !LinesMarked ) { /* if no lines marked, */ ! 1244: if( i < CurCol ) { /* flag everything between */ ! 1245: CharsMarked = 1; /* CurCol and i as Marked */ ! 1246: for( j = i; j < CurCol; j++ ) { ! 1247: if( !MarkedChar[j] ) /* may move forwards... */ ! 1248: MarkedChar[j] = 1; ! 1249: else MarkedChar[j] = 0; ! 1250: } ! 1251: } ! 1252: else if( i > CurCol ) { ! 1253: CharsMarked = 1; /* ... or backwards */ ! 1254: for( j = CurCol; j < i; j++ ) { ! 1255: if( !MarkedChar[j] ) ! 1256: MarkedChar[j] = 1; ! 1257: else MarkedChar[j] = 0; ! 1258: } ! 1259: } ! 1260: } ! 1261: ! 1262: CurCol = i; /* if line is marked, just move */ ! 1263: VIOSETCURPOS( CurRow, CurCol, 0 ); ! 1264: drawline(); /* redraw */ ! 1265: ! 1266: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.