Index | Thread | Search

From:
jerry <mail@jerryfletcher.org>
Subject:
vi(1) notimeout strange behaviour
To:
tech@openbsd.org
Date:
Thu, 18 Sep 2025 17:29:29 +0200

Download raw body.

Thread
  • jerry:

    vi(1) notimeout strange behaviour

Hello,

I noticed that setting escapetime to 0, either by setting it directly or
with notimeout, let vi(1) (and also nvi(1) from ports) behave
strangely.  I have proposed a possible solution below.

An example of a strange behaviour is going into a non empty line, doing
A then <esc>.  The normal behaviour should be a visible movement of the
cursor back to the last character of the line, so back by one.  With
escapetime set to 0, the cursor stays visually at the newline character
without moving back, but if other actions follow, it is as if the cursor
was in the correct position.

An other example is doing O<esc>O, after the second O the cursor is
stack on the old line, then after a character is typed, it will do the O
action, creating the line above and putting the character typed.

I found out that the bug happens when setting the timeout variable in
common/key.c to 0 (see the patch below).  A possible solution is setting
the variable to 1 instead of 0 when escapetime is 0.  Note that the
value of the variable is in 1/1000 of second, so it would be as if
setting escapetime (that is in 1/10 of second) to 0.01.  Right now
testing with this patch everything seems to be working correctly, it is
kind of an hack thought.

Bye,
jerry

diff --git common/key.c common/key.c
index 8b14269c598..dbc5b713eca 100644
--- common/key.c
+++ common/key.c
@@ -619,11 +619,12 @@ newmap:	evp = &gp->i_event[gp->i_next];
 	 */
 	if (ispartial) {
 		if (O_ISSET(sp, O_TIMEOUT))
-			timeout = (evp->e_value == K_ESCAPE ?
-			    O_VAL(sp, O_ESCAPETIME) :
-			    O_VAL(sp, O_KEYTIME)) * 100;
+			timeout = evp->e_value == K_ESCAPE ?
+			    (O_VAL(sp, O_ESCAPETIME) == 0 ?
+				1 : (O_VAL(sp, O_ESCAPETIME) * 100)) :
+			    (O_VAL(sp, O_KEYTIME) * 100);
 		else
-			timeout = 0;
+			timeout = evp->e_value == K_ESCAPE ? 1 : 0;
 		goto loop;
 	}