changeset 11601:0a5d405e2520 v8.0.0683

patch 8.0.0683: visual bell flashes too quickly commit https://github.com/vim/vim/commit/2e147caa14f622dfd1c1def8e07c113b9b85d4b2 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jun 27 17:09:37 2017 +0200 patch 8.0.0683: visual bell flashes too quickly Problem: When using a visual bell there is no delay, causing the flash to be very short, possibly unnoticeable. Also, the flash and the beep can lockup the UI when repeated often. Solution: Do the delay in Vim or flush the output before the delay. Limit the bell to once per half a second. (Ozaki Kiichi, closes #1789)
author Christian Brabandt <cb@256bit.org>
date Tue, 27 Jun 2017 17:15:03 +0200
parents 8ea05b723b25
children f36644d90543
files src/misc1.c src/proto/term.pro src/term.c src/version.c
diffstat 4 files changed, 95 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -3685,16 +3685,30 @@ vim_beep(
     {
 	if (!((bo_flags & val) || (bo_flags & BO_ALL)))
 	{
-	    if (p_vb
+#ifdef ELAPSED_FUNC
+	    static int		did_init = FALSE;
+	    static ELAPSED_TYPE	start_tv;
+
+	    /* Only beep once per half a second, otherwise a sequence of beeps
+	     * would freeze Vim. */
+	    if (!did_init || ELAPSED_FUNC(start_tv) > 500)
+	    {
+		did_init = TRUE;
+		ELAPSED_INIT(start_tv);
+#endif
+		if (p_vb
 #ifdef FEAT_GUI
-		    /* While the GUI is starting up the termcap is set for the
-		     * GUI but the output still goes to a terminal. */
-		    && !(gui.in_use && gui.starting)
-#endif
-		    )
-		out_str(T_VB);
-	    else
-		out_char(BELL);
+			/* While the GUI is starting up the termcap is set for
+			 * the GUI but the output still goes to a terminal. */
+			&& !(gui.in_use && gui.starting)
+#endif
+			)
+		    out_str_cf(T_VB);
+		else
+		    out_char(BELL);
+#ifdef ELAPSED_FUNC
+	    }
+#endif
 	}
 
 	/* When 'verbose' is set and we are sourcing a script or executing a
--- a/src/proto/term.pro
+++ b/src/proto/term.pro
@@ -16,6 +16,7 @@ void out_flush_check(void);
 void out_trash(void);
 void out_char(unsigned c);
 void out_str_nf(char_u *s);
+void out_str_cf(char_u *s);
 void out_str(char_u *s);
 void term_windgoto(int row, int col);
 void term_cursor_right(int i);
--- a/src/term.c
+++ b/src/term.c
@@ -2514,6 +2514,75 @@ out_str_nf(char_u *s)
 #endif
 
 /*
+ * A conditional-flushing out_str, mainly for visualbell.
+ * Handles a delay internally, because termlib may not respect the delay or do
+ * it at the wrong time.
+ * Note: Only for terminal strings.
+ */
+    void
+out_str_cf(char_u *s)
+{
+    if (s != NULL && *s)
+    {
+	char_u *p;
+
+#ifdef FEAT_GUI
+	/* Don't use tputs() when GUI is used, ncurses crashes. */
+	if (gui.in_use)
+	{
+	    out_str_nf(s);
+	    return;
+	}
+#endif
+	if (out_pos > OUT_SIZE - 20)
+	    out_flush();
+#ifdef HAVE_TGETENT
+	for (p = s; *s; ++s)
+	{
+	    /* flush just before delay command */
+	    if (*s == '$' && *(s + 1) == '<')
+	    {
+		char_u save_c = *s;
+		int duration = atoi((char *)s + 2);
+
+		*s = NUL;
+		tputs((char *)p, 1, TPUTSFUNCAST out_char_nf);
+		*s = save_c;
+		out_flush();
+#ifdef ELAPSED_FUNC
+		/* Only sleep here if we can limit this happening in
+		 * vim_beep(). */
+		p = vim_strchr(s, '>');
+		if (p == NULL || duration <= 0)
+		{
+		    /* can't parse the time, don't sleep here */
+		    p = s;
+		}
+		else
+		{
+		    ++p;
+		    do_sleep(duration);
+		}
+#else
+		/* Rely on the terminal library to sleep. */
+		p = s;
+#endif
+		break;
+	    }
+	}
+	tputs((char *)p, 1, TPUTSFUNCAST out_char_nf);
+#else
+	while (*s)
+	    out_char_nf(*s++);
+#endif
+
+	/* For testing we write one string at a time. */
+	if (p_wd)
+	    out_flush();
+    }
+}
+
+/*
  * out_str(s): Put a character string a byte at a time into the output buffer.
  * If HAVE_TGETENT is defined use the termcap parser. (jw)
  * This should only be used for writing terminal codes, not for outputting
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    683,
+/**/
     682,
 /**/
     681,