/* region.c -- implements region.h */ #include "region.h" /* 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" #include "line.h" #include "main.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) { int s; struct 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) { struct line *linep; int loffs; int s; struct 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) { struct line *linep; int loffs; int c; int s; struct 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) { struct line *linep; int loffs; int c; int s; struct 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 "struct 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(struct region *rp) { struct line *flp; struct 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; }