/* * A special insert used as the undo of delete char (C-d or DEL) * this is where the char is inserted at the point and the cursor * is NOT moved on 1 char. This MUST be a seperate function so that * INSERT + BACKSPACE are matching undo pairs * INSERT_AT + DELETE are matching undo pairs * Note: This function is only ever called by execute_undo to undo a DEL. */ void insert_at() { char_t the_char[2]; /* the inserted char plus a null */ assert(curbp->b_gap <= curbp->b_egap); if (curbp->b_gap == curbp->b_egap && !growgap(curbp, CHUNK)) return; curbp->b_point = movegap(curbp, curbp->b_point); /* overwrite if mid line, not EOL or EOF, CR will insert as normal */ if ((curbp->b_flags & B_OVERWRITE) && *input != '\r' && *(ptr(curbp, curbp->b_point)) != '\n' && curbp->b_point < pos(curbp,curbp->b_ebuf) ) { *(ptr(curbp, curbp->b_point)) = *input; if (curbp->b_point < pos(curbp, curbp->b_ebuf)) ++curbp->b_point; /* FIXME - overwite mode not handled properly for undo yet */ } else { the_char[0] = *input == '\r' ? '\n' : *input; the_char[1] = '\0'; /* null terminate */ *curbp->b_gap++ = the_char[0]; curbp->b_point = pos(curbp, curbp->b_egap); curbp->b_point--; /* move point back to where it was before, should always be safe */ /* the point is set so that and undo will DELETE the char */ add_undo(curbp, UNDO_T_INSAT, curbp->b_point, the_char, NULL); } add_mode(curbp, B_MODIFIED); }
void backsp() { curbp->b_point = movegap(curbp, curbp->b_point); undoset(); if (curbp->b_buf < curbp->b_gap) { --curbp->b_gap; curbp->b_flags |= B_MODIFIED; } curbp->b_point = pos(curbp, curbp->b_egap); }
int main(int argc, char **argv) { int i; if (argc < 2) { dprintf(2,"usage: edit file\n"); exit(-1); } initscr(); keypad(1); ebuf = egap = BUF; if ((i = open(filename = argv[1], O_RDONLY)) >= 0) { if ((gap = read(i, buf, BUF)) < 0) gap = 0; close(i); } // for (gap = 0; (n = read(i, buf + gap, BUF - gap)) > 0; gap += n) ; // for (p = buf; p < buf + gap && (p = memchr(p, '\n', gap - p)); lines++, p++) ; for (;;) { display(); switch (i = getch()) { case KEY_UP: x = prev(prev(x) - 1); adjust(); break; case KEY_DOWN: next(); adjust(); break; case KEY_LEFT: if (x > 0) x--; break; case KEY_RIGHT: if (x < ebuf + gap - egap) x++; break; case KEY_PPAGE: x = prev(x); for (i=0; i<LINES-2; i++) { up(); x = prev(x - 1); } adjust(); break; case KEY_NPAGE: for (i=0; i<LINES-2; i++) { down(); next(); } page = prev(page); adjust(); break; case KEY_HOME: x = page = 0; line = 1; break; case KEY_END: x = ebuf + gap - egap; break; case KEY_DC: if (x == ebuf + gap - egap) break; if (x != gap) movegap(); if (buf[egap] == '\n') lines--; egap++; pagex = -1; break; // XXX del \r\n case KEY_F1: save(); break; case '\e': goto done; case '\b': if (x == 0) break; if (x != gap) movegap(); gap--; x = gap; if (buf[gap] == '\n') lines--; pagex = -1; break; case '\r': if (gap == egap) break; if (x != gap) movegap(); buf[gap++] = '\n'; lines++; x = gap; pagex = -1; break; default: if (gap == egap) break; if (x != gap) movegap(); buf[gap++] = i; x = gap; pagex = -1; break; } } done: endwin(); return 0; }
void insert() { assert(curbp->b_gap <= curbp->b_egap); if (curbp->b_gap == curbp->b_egap && !growgap(curbp, CHUNK)) return; curbp->b_point = movegap(curbp, curbp->b_point); /* overwrite if mid line, not EOL or EOF, CR will insert as normal */ if ((curbp->b_flags & B_OVERWRITE) && input != '\r' && *(ptr(curbp, curbp->b_point)) != '\n' && curbp->b_point < pos(curbp,curbp->b_ebuf) ) { *(ptr(curbp, curbp->b_point)) = input; if (curbp->b_point < pos(curbp, curbp->b_ebuf)) ++curbp->b_point; } else { *curbp->b_gap++ = input == '\r' ? '\n' : input; curbp->b_point = pos(curbp, curbp->b_egap); } curbp->b_flags |= B_MODIFIED; }
void backspace() { char_t the_char[7]; /* the deleted char, allow 6 unsigned chars plus a null */ int n = prev_utf8_char_size(); curbp->b_point = movegap(curbp, curbp->b_point); if (curbp->b_buf < (curbp->b_gap - (n - 1)) ) { curbp->b_gap -= n; /* increase start of gap by size of char */ add_mode(curbp, B_MODIFIED); /* record the backspaced chars in the undo structure */ memcpy(the_char, curbp->b_gap, n); the_char[n] = '\0'; /* null terminate, the backspaced char(s) */ curbp->b_point = pos(curbp, curbp->b_egap); //debug("point after bs = %ld\n", curbp->b_point); add_undo(curbp, UNDO_T_BACKSPACE, curbp->b_point, the_char, NULL); } curbp->b_point = pos(curbp, curbp->b_egap); }
/*search for a string and replace it with another string */ void query_replace(void) { point_t o_point = curbp->b_point; point_t l_point = -1; point_t found; char question[STRBUF_L]; int slen, rlen; /* length of search and replace strings */ int numsub = 0; /* number of substitutions */ int ask = TRUE; int c; searchtext[0] = '\0'; replace[0] = '\0'; if (!getinput("Query replace: ", (char*)searchtext, STRBUF_M)) return; if (!getinput("With: ", (char*)replace, STRBUF_M)) return; slen = strlen(searchtext); rlen = strlen(replace); /* build query replace question string */ sprintf(question, "Replace '%s' with '%s' ? ", searchtext, replace); /* scan through the file, from point */ numsub = 0; while(TRUE) { found = search_forward(searchtext); /* if not found set the point to the last point of replacement, or where we started */ if (found == -1) { curbp->b_point = (l_point == -1 ? o_point : l_point); break; } curbp->b_point = found; /* search_forward places point at end of search, move to start of search */ curbp->b_point -= slen; if (ask == TRUE) { msg(question); clrtoeol(); qprompt: display(curwp, TRUE); c = getch(); switch (c) { case 'y': /* yes, substitute */ break; case 'n': /* no, find next */ curbp->b_point = found; /* set to end of search string */ continue; case '!': /* yes/stop asking, do the lot */ ask = FALSE; break; case 0x1B: /* esc */ flushinp(); /* discard any escape sequence without writing in buffer */ case 'q': /* controlled exit */ return; default: /* help me */ msg("(y)es, (n)o, (!)do the rest, (q)uit"); goto qprompt; } } if (rlen > slen) { movegap(curbp, found); /*check enough space in gap left */ if (rlen - slen < curbp->b_egap - curbp->b_gap) growgap(curbp, rlen - slen); /* shrink gap right by r - s */ curbp->b_gap = curbp->b_gap + (rlen - slen); } else if (slen > rlen) { movegap(curbp, found); /* stretch gap left by s - r, no need to worry about space */ curbp->b_gap = curbp->b_gap - (slen - rlen); } else { /* if rlen = slen, we just overwrite the chars, no need to move gap */ } /* now just overwrite the chars at point in the buffer */ l_point = curbp->b_point; memcpy(ptr(curbp, curbp->b_point), replace, rlen * sizeof (char_t)); curbp->b_flags |= B_MODIFIED; curbp->b_point = found - (slen - rlen); /* end of replcement */ numsub++; } msg("%d substitutions", numsub); }
} void backsp() { curbp->b_point = movegap(curbp, curbp->b_point); undoset(); if (curbp->b_buf < curbp->b_gap) { --curbp->b_gap; curbp->b_flags |= B_MODIFIED; } curbp->b_point = pos(curbp, curbp->b_egap); } void delete() { curbp->b_point = movegap(curbp, curbp->b_point); undoset(); if (curbp->b_egap < curbp->b_ebuf) { curbp->b_point = pos(curbp, ++curbp->b_egap); curbp->b_flags |= B_MODIFIED; } } void gotoline() { temp[0] = '\0'; int line; point_t p; result = getinput(m_goto, (char*)temp, STRBUF_S); if (temp[0] != '\0' && result) {