diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2011-07-15 16:50:53 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2011-07-15 16:50:53 +0000 |
commit | 9797dfd1b54f9e508d1ebe1bb3c1b002005156ee (patch) | |
tree | 970bb6db7bf4812de8617a0861d003c325d6844c /usr.bin/mg/yank.c | |
parent | 3e0b329055e784dc541846127ef8b58e5cda7b91 (diff) |
When killing lines using ^U <n> ^K, count the characters exactly (for
both forwards and backwards cases, though the forward case is better
tested. This is required because the actual character deleter
function (ldelete) requires an exact count. If it runs short, it will
not put the deletion into the kill buffer. This is complicated by how
mg internals consider newline's as counted characters even though they
do not occur in the buffers... and then there is the no newline at EOF
fiasco....
Diffstat (limited to 'usr.bin/mg/yank.c')
-rw-r--r-- | usr.bin/mg/yank.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/usr.bin/mg/yank.c b/usr.bin/mg/yank.c index fa1cb3cb078..d408286ecc7 100644 --- a/usr.bin/mg/yank.c +++ b/usr.bin/mg/yank.c @@ -1,4 +1,4 @@ -/* $OpenBSD: yank.c,v 1.9 2009/06/05 18:02:06 kjell Exp $ */ +/* $OpenBSD: yank.c,v 1.10 2011/07/15 16:50:52 deraadt Exp $ */ /* This file is in the public domain. */ @@ -169,14 +169,20 @@ killline(int f, int n) chunk = 1; } } else if (n > 0) { - chunk = llength(curwp->w_dotp) - curwp->w_doto + 1; + 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) { - if (nextp == curbp->b_headp) - break; - chunk += llength(nextp) + 1; + chunk += llength(nextp); nextp = lforw(nextp); + if (nextp != curbp->b_headp) + chunk++; /* newline */ + if (nextp == curbp->b_headp) + break; /* EOL */ } } else { /* n <= 0 */ @@ -184,18 +190,21 @@ killline(int f, int n) curwp->w_doto = 0; i = n; while (i++) { - if (lback(curwp->w_dotp) == curbp->b_headp) - break; + if (lforw(curwp->w_dotp)) + chunk++; curwp->w_dotp = lback(curwp->w_dotp); curwp->w_rflag |= WFMOVE; - chunk += llength(curwp->w_dotp) + 1; + chunk += llength(curwp->w_dotp); } } /* * KFORW here is a bug. Should be KBACK/KFORW, but we need to * rewrite the ldelete code (later)? */ - return (ldelete(chunk, KFORW)); +done: + if (chunk) + return (ldelete(chunk, KFORW)); + return (TRUE); } /* |