summaryrefslogtreecommitdiff
path: root/usr.bin/mg/line.c
diff options
context:
space:
mode:
authorKjell Wooding <kjell@cvs.openbsd.org>2006-12-24 01:20:54 +0000
committerKjell Wooding <kjell@cvs.openbsd.org>2006-12-24 01:20:54 +0000
commit4d5358fd7c257f9f2610a68567e988f001a69287 (patch)
tree2392c3e51afb0494630a3271595517f7ff06bea2 /usr.bin/mg/line.c
parentb18c2eb6dbffaecb00c0d437c38db98d75734a5a (diff)
Fix a bug where inserting a file resulted in an incorrect
line-number count for a buffer (M-X insert-file, M-> to reproduce). While here, fix a number of bugs with incorrect line numbers after swap point-and-mark Originally reported via debian's bug tracking system. Fix tested by Han Boetes and Deanna Phillips.
Diffstat (limited to 'usr.bin/mg/line.c')
-rw-r--r--usr.bin/mg/line.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/usr.bin/mg/line.c b/usr.bin/mg/line.c
index 47b341c0cc2..ac600887381 100644
--- a/usr.bin/mg/line.c
+++ b/usr.bin/mg/line.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: line.c,v 1.43 2006/11/17 08:45:31 kjell Exp $ */
+/* $OpenBSD: line.c,v 1.44 2006/12/24 01:20:53 kjell Exp $ */
/* This file is in the public domain. */
@@ -309,6 +309,13 @@ linsert(int n, int c)
return (TRUE);
}
+/*
+ * Do the work of inserting a newline at the given line/offset.
+ * If mark is on the current line, we may have to move the markline
+ * to keep line numbers in sync.
+ * lnewline_at assumes the current buffer is writable. Checking for
+ * this fact should be done by the caller.
+ */
int
lnewline_at(struct line *lp1, int doto)
{
@@ -318,6 +325,14 @@ lnewline_at(struct line *lp1, int doto)
lchange(WFFULL);
+ curwp->w_bufp->b_lines++;
+ /* Check if mark is past dot (even on current line) */
+ if (curwp->w_markline > curwp->w_dotline ||
+ (curwp->w_dotline == curwp->w_markline &&
+ curwp->w_marko >= doto))
+ curwp->w_markline++;
+ curwp->w_dotline++;
+
/* If start of line, allocate a new line instead of copying */
if (doto == 0) {
/* new first part */
@@ -377,8 +392,6 @@ lnewline(void)
ewprintf("Buffer is read only");
return (FALSE);
}
- curwp->w_bufp->b_lines++;
- curwp->w_dotline++;
return (lnewline_at(curwp->w_dotp, curwp->w_doto));
}
@@ -472,7 +485,9 @@ ldelete(RSIZE n, int kflag)
* line is the magic header line always return TRUE; merging the last line
* with the header line can be thought of as always being a successful
* operation. Even if nothing is done, this makes the kill buffer work
- * "right". Easy cases can be done by shuffling data around. Hard cases
+ * "right". If the mark is past the dot (actually, markline > dotline),
+ * decrease the markline accordingly to keep line numbers in sync.
+ * Easy cases can be done by shuffling data around. Hard cases
* require that lines be moved about in memory. Return FALSE on error and
* TRUE if all looks ok. We do not update w_dotline here, as deletes are done
* after moves.
@@ -493,7 +508,10 @@ ldelnewline(void)
/* at the end of the buffer */
if (lp2 == curbp->b_headp)
return (TRUE);
+ /* Keep line counts in sync */
curwp->w_bufp->b_lines--;
+ if (curwp->w_markline > curwp->w_dotline)
+ curwp->w_markline--;
if (lp2->l_used <= lp1->l_size - lp1->l_used) {
bcopy(&lp2->l_text[0], &lp1->l_text[lp1->l_used], lp2->l_used);
for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {