mirror of
https://github.com/openbsd/src.git
synced 2026-04-29 00:27:11 +00:00
vi: fix 'p' command with a count
This moves the count support from v_put() to put(). Previously, v_put() would call put() "count" times. Because put() also updates the cursor position, this resulted in the text being pasted in the wrong place after the first call to put(). Moving the "count" loop into put() itself means the cursor position is only updated once. From Walter Alejandro Iglesias
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: put.c,v 1.16 2016/05/27 09:18:11 martijn Exp $ */
|
||||
/* $OpenBSD: put.c,v 1.17 2025/08/23 21:02:10 millert Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
@@ -27,16 +27,16 @@
|
||||
* put --
|
||||
* Put text buffer contents into the file.
|
||||
*
|
||||
* PUBLIC: int put(SCR *, CB *, CHAR_T *, MARK *, MARK *, int);
|
||||
* PUBLIC: int put(SCR *, CB *, CHAR_T *, MARK *, MARK *, int, int);
|
||||
*/
|
||||
int
|
||||
put(SCR *sp, CB *cbp, CHAR_T *namep, MARK *cp, MARK *rp, int append)
|
||||
put(SCR *sp, CB *cbp, CHAR_T *namep, MARK *cp, MARK *rp, int append, int cnt)
|
||||
{
|
||||
CHAR_T name;
|
||||
TEXT *ltp, *tp;
|
||||
recno_t lno;
|
||||
size_t blen, clen, len;
|
||||
int rval;
|
||||
int rval, i, isempty;
|
||||
char *bp, *p, *t;
|
||||
|
||||
if (cbp == NULL) {
|
||||
@@ -77,11 +77,15 @@ put(SCR *sp, CB *cbp, CHAR_T *namep, MARK *cp, MARK *rp, int append)
|
||||
if (cp->lno == 1) {
|
||||
if (db_last(sp, &lno))
|
||||
return (1);
|
||||
if (lno == 0) {
|
||||
for (; tp; ++lno, ++sp->rptlines[L_ADDED],
|
||||
tp = TAILQ_NEXT(tp, q))
|
||||
if (db_append(sp, 1, lno, tp->lb, tp->len))
|
||||
return (1);
|
||||
if (lno == 0 && F_ISSET(cbp, CB_LMODE)) {
|
||||
for (i = cnt; i > 0; i--) {
|
||||
for (; tp; ++lno, ++sp->rptlines[L_ADDED],
|
||||
tp = TAILQ_NEXT(tp, q))
|
||||
if (db_append(sp, 1, lno, tp->lb,
|
||||
tp->len))
|
||||
return (1);
|
||||
tp = TAILQ_FIRST(&cbp->textq);
|
||||
}
|
||||
rp->lno = 1;
|
||||
rp->cno = 0;
|
||||
return (0);
|
||||
@@ -92,10 +96,14 @@ put(SCR *sp, CB *cbp, CHAR_T *namep, MARK *cp, MARK *rp, int append)
|
||||
if (F_ISSET(cbp, CB_LMODE)) {
|
||||
lno = append ? cp->lno : cp->lno - 1;
|
||||
rp->lno = lno + 1;
|
||||
for (; tp;
|
||||
++lno, ++sp->rptlines[L_ADDED], tp = TAILQ_NEXT(tp, q))
|
||||
if (db_append(sp, 1, lno, tp->lb, tp->len))
|
||||
return (1);
|
||||
for (i = cnt; i > 0; i--) {
|
||||
for (; tp;
|
||||
++lno, ++sp->rptlines[L_ADDED],
|
||||
tp = TAILQ_NEXT(tp, q))
|
||||
if (db_append(sp, 1, lno, tp->lb, tp->len))
|
||||
return (1);
|
||||
tp = TAILQ_FIRST(&cbp->textq);
|
||||
}
|
||||
rp->cno = 0;
|
||||
(void)nonblank(sp, rp->lno, &rp->cno);
|
||||
return (0);
|
||||
@@ -111,8 +119,11 @@ put(SCR *sp, CB *cbp, CHAR_T *namep, MARK *cp, MARK *rp, int append)
|
||||
* Get the first line.
|
||||
*/
|
||||
lno = cp->lno;
|
||||
if (db_get(sp, lno, DBG_FATAL, &p, &len))
|
||||
return (1);
|
||||
if (db_eget(sp, lno, &p, &len, &isempty)) {
|
||||
if (!isempty)
|
||||
return (1);
|
||||
len = 0;
|
||||
}
|
||||
|
||||
GET_SPACE_RET(sp, bp, blen, tp->len + len + 1);
|
||||
t = bp;
|
||||
@@ -126,8 +137,10 @@ put(SCR *sp, CB *cbp, CHAR_T *namep, MARK *cp, MARK *rp, int append)
|
||||
|
||||
/* First line from the CB. */
|
||||
if (tp->len != 0) {
|
||||
memcpy(t, tp->lb, tp->len);
|
||||
t += tp->len;
|
||||
for (i = cnt; i > 0; i--) {
|
||||
memcpy(t, tp->lb, tp->len);
|
||||
t += tp->len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate length left in the original line. */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ex_move.c,v 1.11 2016/01/06 22:28:52 millert Exp $ */
|
||||
/* $OpenBSD: ex_move.c,v 1.12 2025/08/23 21:02:10 millert Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
@@ -59,7 +59,7 @@ ex_copy(SCR *sp, EXCMD *cmdp)
|
||||
/* Put the text into place. */
|
||||
tm.lno = cmdp->lineno;
|
||||
tm.cno = 0;
|
||||
if (put(sp, &cb, NULL, &tm, &m, 1))
|
||||
if (put(sp, &cb, NULL, &tm, &m, 1, 1))
|
||||
rval = 1;
|
||||
else {
|
||||
/*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ex_put.c,v 1.6 2014/11/12 04:28:41 bentley Exp $ */
|
||||
/* $OpenBSD: ex_put.c,v 1.7 2025/08/23 21:02:10 millert Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
@@ -39,7 +39,7 @@ ex_put(SCR *sp, EXCMD *cmdp)
|
||||
m.cno = sp->cno;
|
||||
if (put(sp, NULL,
|
||||
FL_ISSET(cmdp->iflags, E_C_BUFFER) ? &cmdp->buffer : NULL,
|
||||
&cmdp->addr1, &m, 1))
|
||||
&cmdp->addr1, &m, 1, 1))
|
||||
return (1);
|
||||
sp->lno = m.lno;
|
||||
sp->cno = m.cno;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: com_extern.h,v 1.16 2019/05/21 09:24:58 martijn Exp $ */
|
||||
/* $OpenBSD: com_extern.h,v 1.17 2025/08/23 21:02:10 millert Exp $ */
|
||||
|
||||
int cut(SCR *, CHAR_T *, MARK *, MARK *, int);
|
||||
int cut_line(SCR *, recno_t, size_t, size_t, CB *);
|
||||
@@ -81,7 +81,7 @@ int f_w300(SCR *, OPTION *, char *, u_long *);
|
||||
int f_w1200(SCR *, OPTION *, char *, u_long *);
|
||||
int f_w9600(SCR *, OPTION *, char *, u_long *);
|
||||
int f_window(SCR *, OPTION *, char *, u_long *);
|
||||
int put(SCR *, CB *, CHAR_T *, MARK *, MARK *, int);
|
||||
int put(SCR *, CB *, CHAR_T *, MARK *, MARK *, int, int);
|
||||
int rcv_tmp(SCR *, EXF *, char *);
|
||||
int rcv_init(SCR *);
|
||||
int rcv_sync(SCR *, u_int);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: v_put.c,v 1.8 2016/05/27 09:18:12 martijn Exp $ */
|
||||
/* $OpenBSD: v_put.c,v 1.9 2025/08/23 21:02:10 millert Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
@@ -43,15 +43,11 @@ v_Put(SCR *sp, VICMD *vp)
|
||||
* Historic vi did not support a count with the 'p' and 'P'
|
||||
* commands. It's useful, so we do.
|
||||
*/
|
||||
for (cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
|
||||
if (put(sp, NULL,
|
||||
F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
|
||||
&vp->m_start, &vp->m_final, 0))
|
||||
return (1);
|
||||
vp->m_start = vp->m_final;
|
||||
if (INTERRUPTED(sp))
|
||||
return (1);
|
||||
}
|
||||
cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
|
||||
if (put(sp, NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
|
||||
&vp->m_start, &vp->m_final, 0, cnt))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -74,15 +70,11 @@ v_put(SCR *sp, VICMD *vp)
|
||||
* Historic vi did not support a count with the 'p' and 'P'
|
||||
* commands. It's useful, so we do.
|
||||
*/
|
||||
for (cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
|
||||
if (put(sp, NULL,
|
||||
F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
|
||||
&vp->m_start, &vp->m_final, 1))
|
||||
return (1);
|
||||
vp->m_start = vp->m_final;
|
||||
if (INTERRUPTED(sp))
|
||||
return (1);
|
||||
}
|
||||
cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
|
||||
if (put(sp, NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
|
||||
&vp->m_start, &vp->m_final, 1, cnt))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user