Index | Thread | Search

From:
Walter Alejandro Iglesias <wai@roquesor.com>
Subject:
vi(1) issue with paragraph movement
To:
tech@openbsd.org
Date:
Thu, 23 Apr 2026 15:12:12 +0200

Download raw body.

Thread
When you put the cursor in the last character of the last line (EOF) and
try to run a external command entering '!', vi does nothing.  You have
to move the cursor back, at least to the penultimate character, then it
reacts.

I find this annoying: while editing text I usually format the paragraph
with !}fmt (I use a map in ~/.nexrc).  It's normal the case you're at
the end of what you're editing, right?  In this case you have to move
one character back to be able to run this command.

Another example is, when the cursor is in the last character, you can't
delete it with 'd}'.

I took the idea from the way EOF check is handled in v_sentence()
(vi/v_sentence.c.146) which seems a more consistent check:

        /* EOF is a movement sink, but it's an error not to have moved. */
	if (vp->m_start.lno == cs.cs_lno && vp->m_start.cno == cs.cs_cno) {
		v_eof(sp, NULL);
		return (1);
	}

(There is another bug, with '!)fmt' in v_sentencef() that I'll talk in
another message.)


Index: vi/v_paragraph.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/vi/v_paragraph.c,v
diff -u -p -u -p -r1.10 v_paragraph.c
--- vi/v_paragraph.c	7 Sep 2023 11:17:32 -0000	1.10
+++ vi/v_paragraph.c	23 Apr 2026 10:03:51 -0000
@@ -175,7 +175,8 @@ eof:	if (vp->m_start.lno == lno || vp->m
 			vp->m_start.cno = 0;
 			return (0);
 		}
-		if (vp->m_start.cno == (len ? len - 1 : 0)) {
+		if (vp->m_start.lno == vp->m_stop.lno &&
+		    vp->m_start.cno == vp->m_stop.cno) {
 			v_eof(sp, NULL);
 			return (1);
 		}


-- 
Walter