int redrawhelp() { int nextc; int col; fseek(helpfd, helpfilepos, 0); col = Columns - 52; if (col < 0) col = 0; outstr(T_ED); while ((nextc = getc(helpfd)) != -1 && nextc != '\f') { if (nextc == Ctrl('B')) /* begin of invert */ outstr(T_TI); else if (nextc == Ctrl('E')) /* end of invert */ outstr(T_TP); else outchar((char)nextc); } windgoto(0, (int)(Columns - strlen(Version) - 1)); outstrn(Version); windgoto((int)Rows - 1, col); outstrn("<space = next; return = quit; a = index; b = back>"); return (nextc == -1); }
static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf) { // TODO(tarruda): avoid using a growable array for this, refactor the // algorithm to call `ml_append` directly(skip unecessary copies/resizes) int i; ProcessData *pdata = (ProcessData *)stream->data; if (cnt <= 0) { if (cnt != UV_ENOBUFS) { uv_read_stop(stream); uv_close((uv_handle_t *)stream, NULL); pdata->exited++; } return; } for (i = 0; i < cnt; ++i) { if (pdata->rbuffer[i] == NL) { // Insert the line append_ga_line(&pdata->ga); } else if (pdata->rbuffer[i] == NUL) { // Translate NUL to NL ga_append(&pdata->ga, NL); } else { // buffer data into the grow array ga_append(&pdata->ga, pdata->rbuffer[i]); } } windgoto(msg_row, msg_col); cursor_on(); out_flush(); pdata->reading = false; }
/* * updateline() - like s_refresh() but only for cursor line * * This determines whether or not we need to call s_refresh() to examine * the entire screen for changes. This occurs if the size of the cursor line * (in rows) has changed. */ static void updateline(void) { char *ptr; int col; int size; int j; if (RedrawingDisabled) /* Is this the correct action ? */ return; ptr = format_line(Curschar->linep->s, &col); size = 1 + ((col - 1) / Columns); if (Cline_size == size) { s_cursor_off(); windgoto(Cline_row, 0); if (P(P_NU)) { /* * This should be done more efficiently. */ outstr(mkline(cntllines(Filemem, Curschar))); } outstr(ptr); j = col; col %= Columns; if ((col != 0) || (j == 0)) { #ifdef T_END_L windgoto(Cline_row + size - 1, col); toutstr(T_END_L); #else for (; col < Columns; col++) outchar(' '); #endif } s_cursor_on(); } else { s_refresh(VALID_TO_CURSCHAR); } }
void inschar(char c) { register char *p; register char *pend; if (last_command == 'R' && (gchar(Curschar) != NUL)) { pchar(Curschar, c); } else { /* make room for the new char. */ if (!canincrease(1)) return; p = &Curschar->linep->s[strlen(Curschar->linep->s) + 1]; pend = &Curschar->linep->s[Curschar->index]; for (; p > pend; p--) *p = *(p - 1); *p = c; } if (RedrawingDisabled) { Curschar->index++; return; } /* * If we're in insert mode and showmatch mode is set, then check for * right parens and braces. If there isn't a match, then beep. If there * is a match AND it's on the screen, then flash to it briefly. If it * isn't on the screen, don't do anything. */ if (P(P_SM) && State == INSERT && (c == ')' || c == '}' || c == ']')) { LPtr *lpos, csave; if ((lpos = showmatch()) == NULL) /* no match, so beep */ beep(); else if (LINEOF(lpos) >= LINEOF(Topchar)) { /* show the new char first */ s_refresh(VALID_TO_CURSCHAR); csave = *Curschar; *Curschar = *lpos; /* move to matching char */ cursupdate(UPDATE_CURSOR); windgoto(Cursrow, Curscol); delay(); /* brief pause */ *Curschar = csave; /* restore cursor position */ cursupdate(UPDATE_ALL); } } inc(Curschar); CHANGED; }
/* * lnexttoscreen * * Like nexttoscreen() but only for the cursor line. */ static void lnexttoscreen() { register char *np = Nextscreen + (Cline_row * Columns); register char *rp = Realscreen + (Cline_row * Columns); register char *endline; register int row, col; int gorow = -1, gocol = -1; endline = np + (Cline_size * Columns); row = Cline_row; col = 0; outstr(T_CI); /* disable cursor */ for ( ; np < endline ; np++,rp++ ) { /* If desired screen (contents of Nextscreen) does not */ /* match what's really there, put it there. */ if ( *np != *rp ) { /* if we are positioned at the right place, */ /* we don't have to use windgoto(). */ if (gocol != col || gorow != row) { /* * If we're just off by one, don't send * an entire esc. seq. (this happens a lot!) */ if (gorow == row && gocol+1 == col) { outchar(*(np-1)); gocol++; } else windgoto(gorow=row,gocol=col); } outchar(*rp = *np); gocol++; } if ( ++col >= Columns ) { col = 0; row++; } } outstr(T_CV); /* enable cursor again */ }
void edit() { extern bool_t need_redraw; int c; register char *p, *q; Prenum = 0; /* position the display and the cursor at the top of the file. */ *Topchar = *Filemem; *Curschar = *Filemem; Cursrow = Curscol = 0; do_mlines(); /* check for mode lines before starting */ updatescreen(); for ( ;; ) { /* Figure out where the cursor is based on Curschar. */ cursupdate(); if (need_redraw && !anyinput()) { updatescreen(); need_redraw = FALSE; } if (!anyinput()) windgoto(Cursrow,Curscol); c = vgetc(); if (State == NORMAL) { /* We're in the normal (non-insert) mode. */ /* Pick up any leading digits and compute 'Prenum' */ if ( (Prenum>0 && isdigit(c)) || (isdigit(c) && c!='0') ){ Prenum = Prenum*10 + (c-'0'); continue; } /* execute the command */ normal(c); Prenum = 0; } else { /* * Insert or Replace mode. */ switch (c) { case ESC: /* an escape ends input mode */ /* * If we just did an auto-indent, truncate the * line, and put the cursor back. */ if (did_ai) { Curschar->linep->s[0] = NUL; Curschar->index = 0; did_ai = FALSE; } set_want_col = TRUE; /* Don't end up on a '\n' if you can help it. */ if (gchar(Curschar) == NUL && Curschar->index != 0) dec(Curschar); /* * The cursor should end up on the last inserted * character. This is an attempt to match the real * 'vi', but it may not be quite right yet. */ if (Curschar->index != 0 && !endofline(Curschar)) dec(Curschar); State = NORMAL; msg(""); /* construct the Redo buffer */ p=Redobuff; q=Insbuff; while ( q < Insptr ) *p++ = *q++; *p++ = ESC; *p = NUL; updatescreen(); break; case CTRL('D'): /* * Control-D is treated as a backspace in insert * mode to make auto-indent easier. This isn't * completely compatible with vi, but it's a lot * easier than doing it exactly right, and the * difference isn't very noticeable. */ case BS: /* can't backup past starting point */ if (Curschar->linep == Insstart->linep && Curschar->index <= Insstart->index) { beep(); break; } /* can't backup to a previous line */ if (Curschar->linep != Insstart->linep && Curschar->index <= 0) { beep(); break; } did_ai = FALSE; dec(Curschar); if (State == INSERT) delchar(TRUE); /* * It's a little strange to put backspaces into * the redo buffer, but it makes auto-indent a * lot easier to deal with. */ *Insptr++ = BS; Ninsert++; cursupdate(); updateline(); break; case CR: case NL: if (State == REPLACE) /* DMT added, 12/89 */ delchar(FALSE); *Insptr++ = NL; Ninsert++; opencmd(FORWARD, TRUE); /* open a new line */ break; default: did_ai = FALSE; insertchar(c); break; } } } }
void edit() { int c; char *p, *q; Prenum = 0; /* position the display and the cursor at the top of the file. */ *Topchar = *Filemem; *Curschar = *Filemem; Cursrow = Curscol = 0; for ( ;; ) { /* Figure out where the cursor is based on Curschar. */ cursupdate(); windgoto(Cursrow,Curscol); c = vgetc(); if (State == NORMAL) { /* We're in the normal (non-insert) mode. */ /* Pick up any leading digits and compute 'Prenum' */ if ( (Prenum>0 && isdigit(c)) || (isdigit(c) && c!='0') ){ Prenum = Prenum*10 + (c-'0'); continue; } /* execute the command */ normal(c); Prenum = 0; } else { switch (c) { /* We're in insert mode */ case ESC: /* an escape ends input mode */ set_want_col = TRUE; /* Don't end up on a '\n' if you can help it. */ if (gchar(Curschar) == NUL && Curschar->index != 0) dec(Curschar); /* * The cursor should end up on the last inserted * character. This is an attempt to match the real * 'vi', but it may not be quite right yet. */ if (Curschar->index != 0 && !endofline(Curschar)) dec(Curschar); State = NORMAL; msg(""); *Uncurschar = *Insstart; Undelchars = Ninsert; /* Undobuff[0] = '\0'; */ /* construct the Redo buffer */ p=Redobuff; q=Insbuff; while ( q < Insptr ) *p++ = *q++; *p++ = ESC; *p = NUL; updatescreen(); break; case CTRL('D'): /* * Control-D is treated as a backspace in insert * mode to make auto-indent easier. This isn't * completely compatible with vi, but it's a lot * easier than doing it exactly right, and the * difference isn't very noticeable. */ case BS: /* can't backup past starting point */ if (Curschar->linep == Insstart->linep && Curschar->index <= Insstart->index) { beep(); break; } /* can't backup to a previous line */ if (Curschar->linep != Insstart->linep && Curschar->index <= 0) { beep(); break; } did_ai = FALSE; dec(Curschar); delchar(TRUE); Insptr--; Ninsert--; cursupdate(); updateline(); break; case CR: case NL: *Insptr++ = NL; Ninsert++; opencmd(FORWARD, TRUE); /* open a new line */ cursupdate(); updatescreen(); break; default: did_ai = FALSE; insertchar(c); break; } } } }