X-Git-Url: https://pd.if.org/git/?p=pd_readline;a=blobdiff_plain;f=mg%2Fyank.c;fp=mg%2Fyank.c;h=0000000000000000000000000000000000000000;hp=d408286ecc7b6a1e96107fb97443b3c22475ed93;hb=4bb27266f935c9aafad6870ffc8847fc65c8120f;hpb=3f771e17236364ded86e96ee64f99344337991f8 diff --git a/mg/yank.c b/mg/yank.c deleted file mode 100644 index d408286..0000000 --- a/mg/yank.c +++ /dev/null @@ -1,264 +0,0 @@ -/* $OpenBSD: yank.c,v 1.10 2011/07/15 16:50:52 deraadt Exp $ */ - -/* This file is in the public domain. */ - -/* - * kill ring functions - */ - -#include "def.h" - -#include - -#ifndef KBLOCK -#define KBLOCK 256 /* Kill buffer block size. */ -#endif - -static char *kbufp = NULL; /* Kill buffer data. */ -static RSIZE kused = 0; /* # of bytes used in KB. */ -static RSIZE ksize = 0; /* # of bytes allocated in KB. */ -static RSIZE kstart = 0; /* # of first used byte in KB. */ - -static int kgrow(int); - -/* - * Delete all of the text saved in the kill buffer. Called by commands when - * a new kill context is created. The kill buffer array is released, just in - * case the buffer has grown to an immense size. No errors. - */ -void -kdelete(void) -{ - if (kbufp != NULL) { - free(kbufp); - kbufp = NULL; - kstart = kused = ksize = 0; - } -} - -/* - * Insert a character to the kill buffer, enlarging the buffer if there - * isn't any room. Always grow the buffer in chunks, on the assumption - * that if you put something in the kill buffer you are going to put more - * stuff there too later. Return TRUE if all is well, and FALSE on errors. - * Print a message on errors. Dir says whether to put it at back or front. - * This call is ignored if KNONE is set. - */ -int -kinsert(int c, int dir) -{ - if (dir == KNONE) - return (TRUE); - if (kused == ksize && dir == KFORW && kgrow(dir) == FALSE) - return (FALSE); - if (kstart == 0 && dir == KBACK && kgrow(dir) == FALSE) - return (FALSE); - if (dir == KFORW) - kbufp[kused++] = c; - else if (dir == KBACK) - kbufp[--kstart] = c; - else - panic("broken kinsert call"); /* Oh shit! */ - return (TRUE); -} - -/* - * kgrow - just get more kill buffer for the callee. If dir = KBACK - * we are trying to get space at the beginning of the kill buffer. - */ -static int -kgrow(int dir) -{ - int nstart; - char *nbufp; - - if ((unsigned)(ksize + KBLOCK) <= (unsigned)ksize) { - /* probably 16 bit unsigned */ - ewprintf("Kill buffer size at maximum"); - return (FALSE); - } - if ((nbufp = malloc((unsigned)(ksize + KBLOCK))) == NULL) { - ewprintf("Can't get %ld bytes", (long)(ksize + KBLOCK)); - return (FALSE); - } - nstart = (dir == KBACK) ? (kstart + KBLOCK) : (KBLOCK / 4); - bcopy(&(kbufp[kstart]), &(nbufp[nstart]), (int)(kused - kstart)); - if (kbufp != NULL) - free(kbufp); - kbufp = nbufp; - ksize += KBLOCK; - kused = kused - kstart + nstart; - kstart = nstart; - return (TRUE); -} - -/* - * This function gets characters from the kill buffer. If the character - * index "n" is off the end, it returns "-1". This lets the caller just - * scan along until it gets a "-1" back. - */ -int -kremove(int n) -{ - if (n < 0 || n + kstart >= kused) - return (-1); - return (CHARMASK(kbufp[n + kstart])); -} - -/* - * Copy a string into the kill buffer. kflag gives direction. - * if KNONE, do nothing. - */ -int -kchunk(char *cp1, RSIZE chunk, int kflag) -{ - /* - * HACK - doesn't matter, and fixes back-over-nl bug for empty - * kill buffers. - */ - if (kused == kstart) - kflag = KFORW; - - if (kflag & KFORW) { - while (ksize - kused < chunk) - if (kgrow(kflag) == FALSE) - return (FALSE); - bcopy(cp1, &(kbufp[kused]), (int)chunk); - kused += chunk; - } else if (kflag & KBACK) { - while (kstart < chunk) - if (kgrow(kflag) == FALSE) - return (FALSE); - bcopy(cp1, &(kbufp[kstart - chunk]), (int)chunk); - kstart -= chunk; - } - - return (TRUE); -} - -/* - * Kill line. If called without an argument, it kills from dot to the end - * of the line, unless it is at the end of the line, when it kills the - * newline. If called with an argument of 0, it kills from the start of the - * line to dot. If called with a positive argument, it kills from dot - * forward over that number of newlines. If called with a negative argument - * it kills any text before dot on the current line, then it kills back - * abs(arg) lines. - */ -/* 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); -} - -/* - * Yank text back from the kill buffer. This is really easy. All of the work - * is done by the standard insert routines. All you do is run the loop, and - * check for errors. The blank lines are inserted with a call to "newline" - * instead of a call to "lnewline" so that the magic stuff that happens when - * you type a carriage return also happens when a carriage return is yanked - * back from the kill buffer. An attempt has been made to fix the cosmetic - * bug associated with a yank when dot is on the top line of the window - * (nothing moves, because all of the new text landed off screen). - */ -/* ARGSUSED */ -int -yank(int f, int n) -{ - struct line *lp; - int c, i, nline; - - if (n < 0) - return (FALSE); - - /* newline counting */ - nline = 0; - - undo_boundary_enable(FFRAND, 0); - while (n--) { - /* mark around last yank */ - isetmark(); - i = 0; - while ((c = kremove(i)) >= 0) { - if (c == '\n') { - if (newline(FFRAND, 1) == FALSE) - return (FALSE); - ++nline; - } else { - if (linsert(1, c) == FALSE) - return (FALSE); - } - ++i; - } - } - /* cosmetic adjustment */ - lp = curwp->w_linep; - - /* if offscreen insert */ - if (curwp->w_dotp == lp) { - while (nline-- && lback(lp) != curbp->b_headp) - lp = lback(lp); - /* adjust framing */ - curwp->w_linep = lp; - curwp->w_rflag |= WFFULL; - } - undo_boundary_enable(FFRAND, 1); - return (TRUE); -} -