/* * Display matching character. Matching characters that are not in the * current window are displayed in the echo line. If in the current window, * move dot to the matching character, sit there a while, then move back. */ static void displaymatch(struct line *clp, int cbo) { struct line *tlp; int tbo; int cp; int bufo; int c; int inwindow; char buf[NLINE]; /* * Figure out if matching char is in current window by * searching from the top of the window to dot. */ inwindow = FALSE; for (tlp = curwp->w_linep; tlp != lforw(curwp->w_dotp); tlp = lforw(tlp)) if (tlp == clp) inwindow = TRUE; if (inwindow == TRUE) { tlp = curwp->w_dotp; /* save current position */ tbo = curwp->w_doto; curwp->w_dotp = clp; /* move to new position */ curwp->w_doto = cbo; curwp->w_rflag |= WFMOVE; update(); /* show match */ ttwait(1000); /* wait for key or 1 second */ curwp->w_dotp = tlp; /* return to old position */ curwp->w_doto = tbo; curwp->w_rflag |= WFMOVE; update(); } else { /* match is not in this window, so display line in echo area */ bufo = 0; for (cp = 0; cp < llength(clp); cp++) { c = lgetc(clp, cp); if (c != '\t' #ifdef NOTAB || (curbp->b_flag & BFNOTAB) #endif ) if (ISCTRL(c)) { buf[bufo++] = '^'; buf[bufo++] = CCHR(c); } else buf[bufo++] = c; else do { buf[bufo++] = ' '; } while (bufo & 7); } buf[bufo++] = '\0'; ewprintf("Matches %s", buf); } }
/* * Set the line number and switch to it. */ int setlineno(int n) { struct line *clp; if (n >= 0) { if (n == 0) n++; curwp->w_dotline = n; clp = lforw(curbp->b_headp); /* "clp" is first line */ while (--n > 0) { if (lforw(clp) == curbp->b_headp) { curwp->w_dotline = curwp->w_bufp->b_lines; break; } clp = lforw(clp); } } else { curwp->w_dotline = curwp->w_bufp->b_lines + n; clp = lback(curbp->b_headp); /* "clp" is last line */ while (n < 0) { if (lback(clp) == curbp->b_headp) { curwp->w_dotline = 1; break; } clp = lback(clp); n++; } } curwp->w_dotp = clp; curwp->w_doto = 0; curwp->w_rflag |= WFMOVE; return (TRUE); }
/* * Implements the vi "^F" command. * * Scroll forward by a specified number of lines, or by a full page if no * argument. */ int forwpage(int f, int n) { LINE *lp; int status; if ((n = full_pages(f, n)) < 0) return backpage(f, -n); if ((status = (lforw(DOT.l) != buf_head(curbp))) == TRUE) { lp = curwp->w_line.l; n -= line_height(curwp, lp); while (lp != buf_head(curbp)) { lp = lforw(lp); if ((n -= line_height(curwp, lp)) < 0) break; } if (n < 0) curwp->w_line.l = lp; DOT.l = lp; (void) firstnonwhite(FALSE, 1); curwp->w_flag |= WFHARD | WFMODE; } return status; }
/* * Write a buffer to the already opened file. bp points to the * buffer. Return the status. */ int ffputbuf(FILE *ffp, struct buffer *bp) { struct line *lp, *lpend; lpend = bp->b_headp; for (lp = lforw(lpend); lp != lpend; lp = lforw(lp)) { if (fwrite(ltext(lp), 1, llength(lp), ffp) != llength(lp)) { dobeep(); ewprintf("Write I/O error"); return (FIOERR); } if (lforw(lp) != lpend) /* no implied \n on last line */ putc('\n', ffp); } /* * XXX should be variable controlled (once we have variables) */ if (llength(lback(lpend)) != 0) { if (eyorn("No newline at end of file, add one") == TRUE) { lnewline_at(lback(lpend), llength(lback(lpend))); putc('\n', ffp); } } return (FIOSUC); }
/* * This function performs the details of file writing. Uses the file * management routines in the "fileio.c" package. The number of lines written * is displayed. Sadly, it looks inside a LINE; provide a macro for this. Most * of the grief is error checking of some sort. */ int writeout(char *fn) { LINE *lp; int nline, s; if ((s = ffwopen(fn)) != FIOSUC) /* Open writes message */ return (FALSE); mlwrite("[Writing]"); /* tell us were writing */ lp = lforw(curbp->b_linep); /* First line */ nline = 0; /* Number of lines */ while (lp != curbp->b_linep) { if ((s = ffputline(&lp->l_text[0], llength(lp))) != FIOSUC) break; ++nline; lp = lforw(lp); } if (s == FIOSUC) { /* No write error */ s = ffclose(); if (s == FIOSUC) { /* No close error */ if (nline != 1) mlwrite("[Wrote %d lines]", nline); else mlwrite("[Wrote 1 line]"); } } else /* ignore close error */ ffclose(); /* if a write error */ if (s != FIOSUC) /* some sort of error */ return (FALSE); return (TRUE); }
/* ARGSUSED */ int forwpage(int f, int n) { struct line *lp; if (!(f & FFARG)) { n = curwp->w_ntrows - 2; /* Default scroll. */ if (n <= 0) /* Forget the overlap */ n = 1; /* if tiny window. */ } else if (n < 0) return (backpage(f | FFRAND, -n)); lp = curwp->w_linep; while (n-- && lforw(lp) != curbp->b_headp) { lp = lforw(lp); } curwp->w_linep = lp; curwp->w_flag |= WFFULL; /* if in current window, don't move dot */ for (n = curwp->w_ntrows; n-- && lp != curbp->b_headp; lp = lforw(lp)) if (lp == curwp->w_dotp) return (TRUE); /* Advance the dot the slow way, for line nos */ while (curwp->w_dotp != curwp->w_linep) { curwp->w_dotp = lforw(curwp->w_dotp); curwp->w_dotline++; } curwp->w_doto = 0; return (TRUE); }
/* * Implements the vi "^D" command. * * Scroll forward by a half-page. If a repeat count is given, interpret that * as the number of half-pages to scroll. * * Unlike vi, the OPT_CVMVAS option causes the repeat-count to be interpreted as * half-page, rather than lines. */ int forwhpage(int f, int n) { LINE *llp, *dlp; int status; if ((n = half_pages(f, n)) < 0) return backhpage(f, -n); llp = curwp->w_line.l; dlp = DOT.l; if ((status = (lforw(dlp) != buf_head(curbp))) == TRUE) { n -= line_height(curwp, dlp); while (lforw(dlp) != buf_head(curbp)) { llp = lforw(llp); dlp = lforw(dlp); if ((n -= line_height(curwp, dlp)) < 0) break; } curwp->w_line.l = llp; DOT.l = dlp; curwp->w_flag |= WFHARD | WFKILLS; } (void) firstnonwhite(FALSE, 1); return status; }
/* * List all of the active buffers. First update the special * buffer that holds the list. Next make sure at least 1 * window is displaying the buffer list, splitting the screen * if this is what it takes. Lastly, repaint all of the * windows that are displaying the list. Bound to "C-X C-B". * * A numeric argument forces it to list invisible buffers as * well. */ int listbuffers(int f, int n) { struct window *wp; struct buffer *bp; int s; if ((s = makelist(f)) != TRUE) return s; if (blistp->b_nwnd == 0) { /* Not on screen yet. */ if ((wp = wpopup()) == NULL) return FALSE; bp = wp->w_bufp; if (--bp->b_nwnd == 0) { bp->b_dotp = wp->w_dotp; bp->b_doto = wp->w_doto; bp->b_markp = wp->w_markp; bp->b_marko = wp->w_marko; } wp->w_bufp = blistp; ++blistp->b_nwnd; } wp = wheadp; while (wp != NULL) { if (wp->w_bufp == blistp) { wp->w_linep = lforw(blistp->b_linep); wp->w_dotp = lforw(blistp->b_linep); wp->w_doto = 0; wp->w_markp = NULL; wp->w_marko = 0; wp->w_flag |= WFMODE | WFHARD; } wp = wp->w_wndp; } return TRUE; }
/* ARGSUSED */ int gotomos(int f GCC_UNUSED, int n) { LINE *last = DOT.l; LINE *lp, *head; int half = (curwp->w_ntrows + 1) / 2; head = buf_head(curbp); for (n = 0, lp = curwp->w_line.l; lp != head; lp = lforw(lp)) { if (n < half) DOT.l = lp; if ((n += line_height(curwp, lp)) >= curwp->w_ntrows) break; } if (n < curwp->w_ntrows) { /* then we hit eof before eos */ half = (n + 1) / 2; /* go back up */ for (n = 0, lp = curwp->w_line.l; lp != head; lp = lforw(lp)) { DOT.l = lp; if ((n += line_height(curwp, lp)) >= half) break; } } if (DOT.l != last) curwp->w_flag |= WFMOVE; return firstnonwhite(FALSE, 1); }
/* * This function does the work of counting matching lines. */ int countmatches(int cond) { int error; int count = 0; struct line *clp; clp = curwp->w_dotp; if (curwp->w_doto == llength(clp)) /* Consider dot on next line */ clp = lforw(clp); while (clp != (curbp->b_headp)) { /* see if line matches */ regex_match[0].rm_so = 0; regex_match[0].rm_eo = llength(clp); error = regexec_new(&re_buff, ltext(clp), RE_NMATCH, regex_match, REG_STARTEND); /* Count line when appropriate */ if ((cond == FALSE && error) || (cond == TRUE && !error)) count++; clp = lforw(clp); } if (cond) ewprintf("Number of lines matching: %d", count); else ewprintf("Number of lines not matching: %d", count); return (TRUE); }
/* * Go down the buffer until we find a line with non-space characters. */ int findpara(void) { int col, nospace = 0; /* we move forward to find a para to mark */ do { curwp->w_doto = 0; col = 0; /* check if we are on a blank line */ while (col < llength(curwp->w_dotp)) { if (!isspace(lgetc(curwp->w_dotp, col))) nospace = 1; col++; } if (nospace) break; if (lforw(curwp->w_dotp) == curbp->b_headp) return (FALSE); curwp->w_dotp = lforw(curwp->w_dotp); curwp->w_dotline++; } while (1); return (TRUE); }
/* ARGSUSED */ int killline(int f, int n) { struct line *nextp; RSIZE chunk; int i, c; /* clear kill buffer if last wasn't a kill */ if ((lastflag & CFKILL) == 0) kdelete(); thisflag |= CFKILL; if (!(f & FFARG)) { for (i = curwp->w_doto; i < llength(curwp->w_dotp); ++i) if ((c = lgetc(curwp->w_dotp, i)) != ' ' && c != '\t') break; if (i == llength(curwp->w_dotp)) chunk = llength(curwp->w_dotp) - curwp->w_doto + 1; else { chunk = llength(curwp->w_dotp) - curwp->w_doto; if (chunk == 0) chunk = 1; } } else if (n > 0) { chunk = llength(curwp->w_dotp) - curwp->w_doto; nextp = lforw(curwp->w_dotp); if (nextp != curbp->b_headp) chunk++; /* newline */ if (nextp == curbp->b_headp) goto done; /* EOL */ i = n; while (--i) { chunk += llength(nextp); nextp = lforw(nextp); if (nextp != curbp->b_headp) chunk++; /* newline */ if (nextp == curbp->b_headp) break; /* EOL */ } } else { /* n <= 0 */ chunk = curwp->w_doto; curwp->w_doto = 0; i = n; while (i++) { if (lforw(curwp->w_dotp)) chunk++; curwp->w_dotp = lback(curwp->w_dotp); curwp->w_rflag |= WFMOVE; chunk += llength(curwp->w_dotp); } } /* * KFORW here is a bug. Should be KBACK/KFORW, but we need to * rewrite the ldelete code (later)? */ done: if (chunk) return (ldelete(chunk, KFORW)); return (TRUE); }
/* Word wrap on n-spaces. Back-over whatever precedes the point on the current * line and stop on the first word-break or the beginning of the line. If we * reach the beginning of the line, jump back to the end of the word and start * a new line. Otherwise, break the line at the word-break, eat it, and jump * back to the end of the word. * Returns TRUE on success, FALSE on errors. */ wrapword() { register int cnt; /* size of word wrapped to next line */ register int bp; /* index to wrap on */ register int first = -1; register int i; if(curwp->w_doto <= 0) /* no line to wrap? */ return(FALSE); for(bp = cnt = i = 0; cnt < llength(curwp->w_dotp) && !bp; cnt++, i++){ if(isspace((unsigned char) lgetc(curwp->w_dotp, cnt).c)){ first = 0; if(lgetc(curwp->w_dotp, cnt).c == TAB) while(i+1 & 0x07) i++; } else if(!first) first = cnt; if(first > 0 && i >= fillcol) bp = first; } if(!bp) return(FALSE); /* bp now points to the first character of the next line */ cnt = curwp->w_doto - bp; curwp->w_doto = bp; if(!lnewline()) /* break the line */ return(FALSE); /* * if there's a line below, it doesn't start with whitespace * and there's room for this line... */ if(!(curbp->b_flag & BFWRAPOPEN) && lforw(curwp->w_dotp) != curbp->b_linep && llength(lforw(curwp->w_dotp)) && !isspace((unsigned char) lgetc(lforw(curwp->w_dotp), 0).c) && (llength(curwp->w_dotp) + llength(lforw(curwp->w_dotp)) < fillcol)){ gotoeol(0, 1); /* then pull text up from below */ if(lgetc(curwp->w_dotp, curwp->w_doto - 1).c != ' ') linsert(1, ' '); forwdel(0, 1); gotobol(0, 1); } curbp->b_flag &= ~BFWRAPOPEN; /* don't open new line next wrap */ /* restore dot (account for NL) */ if(cnt && !forwchar(0, cnt < 0 ? cnt-1 : cnt)) return(FALSE); return(TRUE); }
/* * This routine figures out the bound of the region in the current window, * and stores the results into the fields of the REGION structure. Dot and * mark are usually close together, but I don't know the order, so I scan * outward from dot, in both directions, looking for mark. The size is kept * in a long. At the end, after the size is figured out, it is assigned to * the size field of the region structure. If this assignment loses any bits, * then we print an error. This is "type independent" overflow checking. All * of the callers of this routine should be ready to get an ABORT status, * because I might add a "if regions is big, ask before clobbering" flag. */ static int getregion(struct region *rp) { struct line *flp, *blp; long fsize, bsize; if (curwp->w_markp == NULL) { dobeep(); ewprintf("No mark set in this window"); return (FALSE); } /* "r_size" always ok */ if (curwp->w_dotp == curwp->w_markp) { rp->r_linep = curwp->w_dotp; rp->r_lineno = curwp->w_dotline; if (curwp->w_doto < curwp->w_marko) { rp->r_offset = curwp->w_doto; rp->r_size = (RSIZE)(curwp->w_marko - curwp->w_doto); } else { rp->r_offset = curwp->w_marko; rp->r_size = (RSIZE)(curwp->w_doto - curwp->w_marko); } return (TRUE); } /* get region size */ flp = blp = curwp->w_dotp; bsize = curwp->w_doto; fsize = llength(flp) - curwp->w_doto + 1; while (lforw(flp) != curbp->b_headp || lback(blp) != curbp->b_headp) { if (lforw(flp) != curbp->b_headp) { flp = lforw(flp); if (flp == curwp->w_markp) { rp->r_linep = curwp->w_dotp; rp->r_offset = curwp->w_doto; rp->r_lineno = curwp->w_dotline; return (setsize(rp, (RSIZE)(fsize + curwp->w_marko))); } fsize += llength(flp) + 1; } if (lback(blp) != curbp->b_headp) { blp = lback(blp); bsize += llength(blp) + 1; if (blp == curwp->w_markp) { rp->r_linep = blp; rp->r_offset = curwp->w_marko; rp->r_lineno = curwp->w_markline; return (setsize(rp, (RSIZE)(bsize - curwp->w_marko))); } } } dobeep(); ewprintf("Bug: lost mark"); return (FALSE); }
/* * This routine does the real work of a forward search. The pattern is sitting * in the external variable "pat". If found, dot is updated, the window system * is notified of the change, and TRUE is returned. If the string isn't found, * FALSE is returned. */ int forwsrch(void) { struct line *clp, *tlp; int cbo, tbo, c, i, xcase = 0; char *pp; int nline; clp = curwp->w_dotp; cbo = curwp->w_doto; nline = curwp->w_dotline; for (i = 0; pat[i]; i++) if (ISUPPER(CHARMASK(pat[i]))) xcase = 1; for (;;) { if (cbo == llength(clp)) { if ((clp = lforw(clp)) == curbp->b_headp) break; nline++; cbo = 0; c = CCHR('J'); } else c = lgetc(clp, cbo++); if (eq(c, pat[0], xcase) != FALSE) { tlp = clp; tbo = cbo; pp = &pat[1]; while (*pp != 0) { if (tbo == llength(tlp)) { tlp = lforw(tlp); if (tlp == curbp->b_headp) goto fail; tbo = 0; c = CCHR('J'); if (eq(c, *pp++, xcase) == FALSE) goto fail; nline++; } else { c = lgetc(tlp, tbo++); if (eq(c, *pp++, xcase) == FALSE) goto fail; } } curwp->w_dotp = tlp; curwp->w_doto = tbo; curwp->w_dotline = nline; curwp->w_rflag |= WFMOVE; return (TRUE); } fail: ; } return (FALSE); }
/* * pico_give - free resources and give up picotext struct */ void pico_give(void *w) { register LINE *lp; register LINE *fp; fp = lforw(PT(w)->linep); while((lp = fp) != PT(w)->linep){ fp = lforw(lp); free(lp); } free(PT(w)->linep); free((PICOTEXT *)w); }
/* ARGSUSED */ int d_undel(int f, int n) { if (n < 0) return (d_undelbak(f, -n)); while (n--) { if (llength(curwp->w_dotp) > 0) lputc(curwp->w_dotp, 0, ' '); if (lforw(curwp->w_dotp) != curbp->b_headp) curwp->w_dotp = lforw(curwp->w_dotp); } curwp->w_flag |= WFEDIT | WFMOVE; curwp->w_doto = 0; return (TRUE); }
/* ARGSUSED */ int gotoline(int f, int n) { struct line *clp; char buf[32], *bufp; const char *err; if (!(f & FFARG)) { if ((bufp = eread("Goto line: ", buf, sizeof(buf), EFNUL | EFNEW | EFCR)) == NULL) return (ABORT); if (bufp[0] == '\0') return (ABORT); n = (int)strtonum(buf, INT_MIN, INT_MAX, &err); if (err) { ewprintf("Line number %s", err); return (FALSE); } } if (n >= 0) { if (n == 0) n++; curwp->w_dotline = n; clp = lforw(curbp->b_headp); /* "clp" is first line */ while (--n > 0) { if (lforw(clp) == curbp->b_headp) { curwp->w_dotline = curwp->w_bufp->b_lines; break; } clp = lforw(clp); } } else { curwp->w_dotline = curwp->w_bufp->b_lines + n; clp = lback(curbp->b_headp); /* "clp" is last line */ while (n < 0) { if (lback(clp) == curbp->b_headp) { curwp->w_dotline = 1; break; } clp = lback(clp); n++; } } curwp->w_dotp = clp; curwp->w_doto = 0; curwp->w_rflag |= WFMOVE; return (TRUE); }
/* * Implements the vi "L" command. * * Move to the last (or nth last) line in window */ int gotoeos(int f, int n) { LINE *last = DOT.l; int nn; n = need_at_least(f, n, 1); /* first get to the end */ DOT.l = curwp->w_line.l; nn = curwp->w_ntrows; while ((nn -= line_height(curwp, DOT.l)) > 0) { if (is_last_line(DOT, curbp)) break; DOT.l = lforw(DOT.l); } #ifdef WMDLINEWRAP /* adjust if we pointed to a line-fragment */ if (w_val(curwp, WMDLINEWRAP) && nn < 0 && DOT.l != curwp->w_line.l) DOT.l = lback(DOT.l); #endif /* and then go back up */ /* (we're either at eos or eof) */ while (--n != 0) { if (sameline(DOT, curwp->w_line)) break; DOT.l = lback(DOT.l); } if (DOT.l != last) curwp->w_flag |= WFMOVE; return firstnonwhite(FALSE, 1); }
/* ARGSUSED0 */ int gotobob (int f, int n) { curwp->w_dotp = lforw (curbp->b_linep); curwp->w_doto = 0; curwp->w_flag |= WFHARD; return (TRUE); }
/* * Move to a particular line (the argument). Count from bottom of file if * argument is negative. */ int vl_gotoline(int n) { int status = TRUE; /* status return */ MARK odot; if (n == 0) /* if a bogus argument...then leave */ return (FALSE); odot = DOT; DOT.o = w_left_margin(curwp); if (n < 0) { DOT.l = lback(buf_head(curbp)); status = backline(TRUE, -n - 1); } else { DOT.l = lforw(buf_head(curbp)); status = forwline(TRUE, n - 1); } if (status != TRUE) { DOT = odot; return status; } (void) firstnonwhite(FALSE, 1); curwp->w_flag |= WFMOVE; return TRUE; }
/* * Move the cursor forwards by "n" characters. If "n" is less than zero call * "backchar" to actually do the move. Otherwise compute the new cursor * location, and move ".". Error if you try and move off the end of the * buffer. Set the flag if the line pointer for dot changes. */ int forwchar(int f, int n) { int rc = TRUE; n = need_a_count(f, n, 1); if (n < 0) { rc = backchar(f, -n); } else { while (n--) { /* if an explicit arg was given, allow us to land on the newline, else skip it */ if (is_at_end_of_line(DOT) || (f == FALSE && !insertmode && llength(DOT.l) && DOT.o == llength(DOT.l) - 1)) { if (is_header_line(DOT, curbp) || is_last_line(DOT, curbp)) { rc = FALSE; break; } DOT.l = lforw(DOT.l); DOT.o = w_left_margin(curwp); curwp->w_flag |= WFMOVE; } else { DOT.o += BytesAt(DOT.l, DOT.o); } } } return (rc); }
/* * Upper case region. Zap all of the lower * case characters in the region to upper case. Use * the region code to set the limits. Scan the buffer, * doing the changes. Call "lchange" to ensure that * redisplay is done in all buffers. */ int upperregion (int f, int n, int k) { register LINE *linep; register int loffs; register int c; register int s; REGION region; if ((s = getregion (®ion)) != TRUE) return (s); if (checkreadonly () == FALSE) return FALSE; lchange (WFHARD); linep = region.r_pos.p; loffs = region.r_pos.o; while (region.r_size--) { if (loffs == llength (linep)) { linep = lforw (linep); loffs = 0; } else { c = lgetc (linep, loffs); if (ISLOWER (c) != FALSE) lputc (linep, loffs, TOUPPER (c)); ++loffs; } } return (TRUE); }
/* * This routine figures out the bound of the region * in the current window, and stores the results into the fields * of the REGION structure. Dot and mark are usually close together, * but I don't know the order, so I scan outward from dot, in both * directions, looking for mark. The size is kept in a long. At the * end, after the size is figured out, it is assigned to the size * field of the region structure. If this assignment loses any bits, * then we print an error. This is "type independent" overflow * checking. All of the callers of this routine should be ready to * get an ABORT status, because I might add a "if regions is big, * ask before clobberring" flag. */ static int getregion (REGION *rp) { register LINE *flp; register LINE *blp; register long fsize; /* Long now. */ register long bsize; if (curwp->w_mark.p == NULL) { eprintf ("No mark in this window"); return (FALSE); } if (curwp->w_dot.p == curwp->w_mark.p) { /* "r_size" always ok. */ rp->r_pos.p = curwp->w_dot.p; if (curwp->w_dot.o < curwp->w_mark.o) { rp->r_pos.o = curwp->w_dot.o; rp->r_size = curwp->w_mark.o - curwp->w_dot.o; } else { rp->r_pos.o = curwp->w_mark.o; rp->r_size = curwp->w_dot.o - curwp->w_mark.o; } return (TRUE); } blp = curwp->w_dot.p; /* Get region size. */ flp = curwp->w_dot.p; bsize = curwp->w_dot.o; fsize = llength (flp) - curwp->w_dot.o + 1; while (flp != curbp->b_linep || lback (blp) != curbp->b_linep) { if (flp != curbp->b_linep) { flp = lforw (flp); if (flp == curwp->w_mark.p) { rp->r_pos.p = curwp->w_dot.p; rp->r_pos.o = curwp->w_dot.o; return (setsize (rp, fsize + curwp->w_mark.o)); } fsize += llength (flp) + 1; } if (lback (blp) != curbp->b_linep) { blp = lback (blp); bsize += llength (blp) + 1; if (blp == curwp->w_mark.p) { rp->r_pos.p = blp; rp->r_pos.o = curwp->w_mark.o; return (setsize (rp, bsize - curwp->w_mark.o)); } } } eprintf ("Bug: lost mark"); /* Gak! */ return (FALSE); }
/* push an unreal line onto the undo stack * lp should be the new line, _after_ insertion, so * lforw() and lback() are right */ int tag_for_undo(LINE *lp) { int status = FALSE; LINE *nlp; TRACE2((T_CALLED "tag_for_undo(%p)\n", lp)); if (needundocleanup) preundocleanup(); if (liscopied(lp)) { status = TRUE; } else if ((nlp = lalloc(LINENOTREAL, curbp)) == 0) { TRACE(("tag_for_undo: no memory\n")); status = ABORT; } else { set_lforw(nlp, lforw(lp)); set_lback(nlp, lback(lp)); pushline(nlp, BACKSTK(curbp)); lsetcopied(lp); FORWDOT(curbp).l = lp; FORWDOT(curbp).o = DOT.o; status = TRUE; } return2Code(status); }
/* ARGSUSED */ int lowerregion(int f, int n) { struct line *linep; struct region region; int loffs, c, s; if ((s = checkdirty(curbp)) != TRUE) return (s); if (curbp->b_flag & BFREADONLY) { ewprintf("Buffer is read-only"); return (FALSE); } if ((s = getregion(®ion)) != TRUE) return (s); undo_add_change(region.r_linep, region.r_offset, region.r_size); lchange(WFFULL); linep = region.r_linep; loffs = region.r_offset; while (region.r_size--) { if (loffs == llength(linep)) { linep = lforw(linep); loffs = 0; } else { c = lgetc(linep, loffs); if (ISUPPER(c) != FALSE) lputc(linep, loffs, TOLOWER(c)); ++loffs; } } return (TRUE); }
/* ARGSUSED */ int forwline(int f, int n) { struct line *dlp; if (n < 0) return (backline(f | FFRAND, -n)); if ((dlp = curwp->w_dotp) == curbp->b_headp) return(TRUE); if ((lastflag & CFCPCN) == 0) /* Fix goal. */ setgoal(); thisflag |= CFCPCN; if (n == 0) return (TRUE); while (n--) { dlp = lforw(dlp); if (dlp == curbp->b_headp) { curwp->w_dotp = lback(dlp); curwp->w_doto = llength(curwp->w_dotp); curwp->w_rflag |= WFMOVE; return (TRUE); } curwp->w_dotline++; } curwp->w_rflag |= WFMOVE; curwp->w_dotp = dlp; curwp->w_doto = getgoal(dlp); return (TRUE); }
/*ARGSUSED*/ copyregion(f, n) { register LINE *linep; register int loffs; register int s; REGION region; VOID kdelete(); if ((s=getregion(®ion)) != TRUE) return s; if ((lastflag&CFKILL) == 0) /* Kill type command. */ kdelete(); thisflag |= CFKILL; linep = region.r_linep; /* Current line. */ loffs = region.r_offset; /* Current offset. */ while (region.r_size--) { if (loffs == llength(linep)) { /* End of line. */ if ((s=kinsert('\n', KFORW)) != TRUE) return (s); linep = lforw(linep); loffs = 0; } else { /* Middle of line. */ if ((s=kinsert(lgetc(linep, loffs), KFORW)) != TRUE) return s; ++loffs; } } #ifdef CLIPBOARD send_clipboard(); #endif /* CLIPBOARD */ return TRUE; }
/* * movenext -- move to next character in either direction, but * don't return it. will wrap, and doesn't set motion flags. */ static void movenext(MARK *pdot, int dir) { LINE *curline; int curoff; curline = pdot->l; curoff = pdot->o; if (dir == FORWARD) { if (curoff == llength(curline)) { curline = lforw(curline); /* skip to next line */ curoff = 0; } else { curoff += BytesAt(curline, curoff); } } else { if (curoff == 0) { curline = lback(curline); curoff = llength(curline); } else { curoff -= BytesBefore(curline, curoff); } } pdot->l = curline; pdot->o = curoff; }
/* ARGSUSED */ int clear_match_attrs(int f GCC_UNUSED, int n GCC_UNUSED) { int status; MARK origdot, origmark; if ((curbp->b_highlight & HILITE_ON) == 0) return TRUE; origdot = DOT; origmark = MK; DOT.l = lforw(buf_head(curbp)); DOT.o = 0; MK.l = lback(buf_head(curbp)); MK.o = llength(MK.l) - 1; videoattribute = VOWN_MATCHES; if ((status = attributeregion()) == TRUE) { DOT = origdot; MK = origmark; curbp->b_highlight = 0; #if OPT_HILITEMATCH hilite_suppressed = TRUE; #endif } return status; }