Index | Thread | Search

From:
Walter Alejandro Iglesias <wai@roquesor.com>
Subject:
vi(1) issue with '!)fmt' at the EOF
To:
tech@openbsd.org
Date:
Thu, 23 Apr 2026 15:20:57 +0200

Download raw body.

Thread
In a sentence of more than one line, ')fmt' won't format the last line
of the file, *depending on which column you have the cursor*.

Index: vi/v_sentence.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/vi/v_sentence.c,v
diff -u -p -u -p -r1.8 v_sentence.c
--- vi/v_sentence.c	26 Dec 2022 19:16:04 -0000	1.8
+++ vi/v_sentence.c	23 Apr 2026 13:03:03 -0000
@@ -165,20 +165,36 @@ okret:	vp->m_stop.lno = cs.cs_lno;
 	 * range for motion commands.
 	 */
 	if (ISMOTION(vp)) {
-		if (vp->m_start.cno == 0 &&
+		/*
+		 * If the motion ended at EOF, we must ensure the stop
+		 * position is valid.  If we are filtering (!), and we
+		 * hit the end of the file, we want to include the whole
+		 * line even if we didn't start at column 0.
+		 */
+		if (cs.cs_flags == CS_EOF) {
+			/*
+			 * Keep the stop at the very end of the file.
+			 * Do NOT decrement m_stop.cno here.
+			 */
+			vp->m_stop.lno = cs.cs_lno;
+			vp->m_stop.cno = cs.cs_len > 0 ? cs.cs_len - 1 : 0;
+		} else if (vp->m_start.cno == 0 &&
 		    (cs.cs_flags != 0 || vp->m_stop.cno == 0)) {
 			if (vp->m_start.lno < vp->m_stop.lno) {
-				if (db_get(sp,
-				    --vp->m_stop.lno, DBG_FATAL, NULL, &len))
+				if (db_get(sp, --vp->m_stop.lno,
+				    DBG_FATAL, NULL, &len))
 					return (1);
 				vp->m_stop.cno = len ? len - 1 : 0;
 			}
 			F_SET(vp, VM_LMODE);
-		} else
-			--vp->m_stop.cno;
+		} else {
+			if (vp->m_stop.cno > 0)
+				--vp->m_stop.cno;
+		}
 		vp->m_final = vp->m_start;
 	} else
 		vp->m_final = vp->m_stop;
+
 	return (0);
 }
 

-- 
Walter