/* * STEVIE - Simply Try this Editor for VI Enthusiasts * * Code Contributions By : Tim Thompson twitch!tjt * Tony Andrews onecom!wldrdg!tony * G. R. (Fred) Walter watmath!watcgl!grwalter */ #include "stevie.h" /* * updateNextscreen() * * Based on the current value of Topchar, transfer a screenfull of stuff from * Filemem to Nextscreen, and update Botchar. */ void updateNextscreen(type) int type; { register char *ptr; register char c; register int row; register int col; register char *screenp; register char *endscreen; register char *nextrow; LPtr start; LINE *memp; LINE *save; /* save pos. in case line won't fit */ char extra[16]; char *p_extra; int n_extra; bool_t done; /* if TRUE, we hit the end of the file */ bool_t didline; /* if TRUE, we finished the last line */ int srow; /* starting row of the current line */ int lno; /* number of the line we're doing */ int coff; /* column offset */ int idx; int i; int j; char lines; if (NumLineSizes == 0) type = NOT_VALID; MustRedrawLine = FALSE; MustRedrawScreen = TRUE; idx = 0; row = 0; start.linep = Topchar->linep; screenp = Nextscreen; /* The number of rows shown is Rows-1. */ /* The last line is the status/command line. */ endscreen = Nextscreen + (Rows - 1) * Columns; if ((type == VALID) || (type == VALID_TO_CURSCHAR)) { j = -1; for (i = 0; i < NumLineSizes; i++) { if (LinePointers[i] == Topchar->linep) { j = i; break; } row += LineSizes[i]; } if (j == -1) { /* Are we off the top of the screen by one line ? */ if (Topchar->linep->next == LinePointers[0]) { i = plines(Topchar); if (i < (Rows - 1)) { screenp = endscreen - (i * Columns); while (screenp > Nextscreen) *(--endscreen) = *(--screenp); endscreen = Nextscreen + (i * Columns); for(idx = NumLineSizes; idx > 0; idx--) { LinePointers[idx] = LinePointers[idx - 1]; LineSizes[idx] = LineSizes[idx - 1]; } LineSizes[idx] = i; } } row = 0; } else if (j == 0 && type == VALID) { return; } else { nextrow = Nextscreen + row * Columns; row = 0; for (;;) { LineSizes[idx] = LineSizes[j]; LinePointers[idx] = LinePointers[j]; if (type == VALID_TO_CURSCHAR) { if (LinePointers[idx]->next == Curschar->linep) { break; } } j++; if (j >= NumLineSizes) break; row += LineSizes[idx]; idx++; } start.linep = LinePointers[idx]; endscreen = nextrow + row * Columns; while (nextrow < endscreen) *screenp++ = *nextrow++; endscreen = Nextscreen + (Rows - 1) * Columns; } } srow = row; save = memp = start.linep; coff = P(P_NU) ? 8 : 0; if (P(P_NU)) lno = cntllines(Filemem, &start); done = didline = FALSE; col = 0; lines = 1; LinePointers[idx] = memp; p_extra = NULL; n_extra = 0; if (P(P_NU)) { strcpy(extra, mkline(lno++)); p_extra = extra; n_extra = 8; } ptr = memp->s; /* * We go one past the end of the screen so we can find out if the last * line fit on the screen or not. */ while (screenp <= endscreen) { /* Get the next character to put on the screen. */ /* * The 'extra' array contains the extra stuff that is inserted to * represent special characters (tabs, and other non-printable stuff. */ if (n_extra > 0) { c = *p_extra++; n_extra--; } else { c = *ptr++; if (c < 32 || c > 127) { if (c == NUL) { srow = ++row; /* * Save this position in case the next line won't fit on the * screen completely. */ save = memp; if (memp->next != Fileend->linep) { memp = memp->next; ptr = memp->s; } else { done = TRUE; } if (P(P_LS)) { *screenp++ = '$'; if (screenp > endscreen) break; col++; if (col >= Columns) { row++; lines++; } } LineSizes[idx++] = lines; lines = 1; LinePointers[idx] = memp; if (P(P_NU)) { strcpy(extra, mkline(lno++)); p_extra = extra; n_extra = 8; } /* blank out the rest of this row */ nextrow = Nextscreen + (row * Columns); while (screenp < nextrow) *screenp++ = ' '; if (done) break; if (screenp == endscreen) { didline = TRUE; break; } else if (screenp > endscreen) { idx--; break; } col = 0; continue; } else if (c == TAB) { if (!P(P_LS)) { strcpy(extra, " "); p_extra = extra; /* tab amount depends on current column */ n_extra = ((P(P_TS) - 1) - (col - coff) % P(P_TS)); c = ' '; } } else if ((n_extra = chars[c].ch_size - 1) > 0) { p_extra = chars[c].ch_str; c = *p_extra++; } } } if (col >= Columns) { lines++; row++; col = 0; } /* store the character in Nextscreen */ *screenp++ = c; col++; } /* Do we have to do off the top of the screen processing ? */ if (endscreen != (Nextscreen + (Rows - 1) * Columns)) { endscreen = Nextscreen + (Rows - 1) * Columns; row = 0; for(idx = 0; idx <= NumLineSizes && row < (Rows - 1); idx++) row += LineSizes[idx]; if (row < (Rows - 1)) { screenp = Nextscreen + (row * Columns); done = TRUE; } else if (row > (Rows - 1)) { /* Need to blank out the last line */ idx--; save = LinePointers[idx]; srow = row - LineSizes[idx]; didline = FALSE; } else { memp = LinePointers[idx]; screenp = Nextscreen + (row * Columns); didline = TRUE; } } /* * If we didn't hit the end of the file, and we didn't finish the last * line we were working on, then the line didn't fit. */ if (!done && !didline) { /* * Clear the rest of the screen and mark the unused lines. */ screenp = Nextscreen + (srow * Columns); while (screenp < endscreen) *screenp++ = ' '; for (; srow < (Rows - 1); srow++) Nextscreen[srow * Columns] = '@'; Botchar->linep = save; } else { /* make sure the rest of the screen is blank */ while (screenp < endscreen) *screenp++ = ' '; /* put '~'s on rows that aren't part of the file. */ if (col != 0) row++; while (row < Rows) { Nextscreen[row * Columns] = '~'; row++; } if (done) /* we hit the end of the file */ *Botchar = *Fileend; else Botchar->linep = memp; /* FIX - prev? */ } NumLineSizes = idx; }