/* REGION.C * * The routines in this file * deal with the region, that magic space * between "." and mark. Some functions are * commands. Some functions are just for * internal use. * * modified by Petri Kutvonen */ #include #include "estruct.h" #include "edef.h" #include "efunc.h" /* * Kill the region. Ask "getregion" * to figure out the bounds of the region. * Move "." to the start, and kill the characters. * Bound to "C-W". */ int killregion(int f, int n) { register int s; REGION region; if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return (rdonly()); /* we are in read only mode */ if ((s = getregion(®ion)) != TRUE) return (s); if ((lastflag & CFKILL) == 0) /* This is a kill type */ kdelete(); /* command, so do magic */ thisflag |= CFKILL; /* kill buffer stuff. */ curwp->w_dotp = region.r_linep; curwp->w_doto = region.r_offset; return (ldelete(region.r_size, TRUE)); } /* * Copy all of the characters in the * region to the kill buffer. Don't move dot * at all. This is a bit like a kill region followed * by a yank. Bound to "M-W". */ int copyregion(int f, int n) { register LINE *linep; register int loffs; register int s; REGION region; 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')) != TRUE) return (s); linep = lforw(linep); loffs = 0; } else { /* Middle of line. */ if ((s = kinsert(lgetc(linep, loffs))) != TRUE) return (s); ++loffs; } } mlwrite("(region copied)"); return (TRUE); } /* * Lower case region. Zap all of the upper * case characters in the region to lower 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. Bound to * "C-X C-L". */ int lowerregion(int f, int n) { register LINE *linep; register int loffs; register int c; register int s; REGION region; if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return (rdonly()); /* we are in read only mode */ if ((s = getregion(®ion)) != TRUE) return (s); lchange(WFHARD); 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 (c >= 'A' && c <= 'Z') lputc(linep, loffs, c + 'a' - 'A'); ++loffs; } } return (TRUE); } /* * 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. Bound to * "C-X C-L". */ int upperregion(int f, int n) { register LINE *linep; register int loffs; register int c; register int s; REGION region; if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return (rdonly()); /* we are in read only mode */ if ((s = getregion(®ion)) != TRUE) return (s); lchange(WFHARD); 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 (c >= 'a' && c <= 'z') lputc(linep, loffs, c - 'a' + 'A'); ++loffs; } } return (TRUE); } /* * This routine figures out the * bounds of the region in the current window, and * fills in the fields of the "REGION" structure pointed * to by "rp". Because the dot and mark are usually very * close together, we scan outward from dot looking for * mark. This should save time. Return a standard code. * Callers of this routine should be prepared to get * an "ABORT" status; we might make this have the * conform thing later. */ int getregion(REGION *rp) { register LINE *flp; register LINE *blp; long fsize; long bsize; if (curwp->w_markp == NULL) { mlwrite("No mark set in this window"); return (FALSE); } if (curwp->w_dotp == curwp->w_markp) { rp->r_linep = curwp->w_dotp; if (curwp->w_doto < curwp->w_marko) { rp->r_offset = curwp->w_doto; rp->r_size = (long) (curwp->w_marko - curwp->w_doto); } else { rp->r_offset = curwp->w_marko; rp->r_size = (long) (curwp->w_doto - curwp->w_marko); } return (TRUE); } blp = curwp->w_dotp; bsize = (long) curwp->w_doto; flp = curwp->w_dotp; fsize = (long) (llength(flp) - curwp->w_doto + 1); while (flp != curbp->b_linep || lback(blp) != curbp->b_linep) { if (flp != curbp->b_linep) { flp = lforw(flp); if (flp == curwp->w_markp) { rp->r_linep = curwp->w_dotp; rp->r_offset = curwp->w_doto; rp->r_size = fsize + curwp->w_marko; return (TRUE); } fsize += llength(flp) + 1; } if (lback(blp) != curbp->b_linep) { blp = lback(blp); bsize += llength(blp) + 1; if (blp == curwp->w_markp) { rp->r_linep = blp; rp->r_offset = curwp->w_marko; rp->r_size = bsize - curwp->w_marko; return (TRUE); } } } mlwrite("Bug: lost mark"); return (FALSE); }