changeset 30843:82e62fd4eae9 v9.0.0756

patch 9.0.0756: no autocmd event for changing text in a terminal window Commit: https://github.com/vim/vim/commit/4ccaedfcd7526983f4b6b3b06b0bfb54f333f1f3 Author: Shougo Matsushita <Shougo.Matsu@gmail.com> Date: Sat Oct 15 11:48:00 2022 +0100 patch 9.0.0756: no autocmd event for changing text in a terminal window Problem: No autocmd event for changing text in a terminal window. Solution: Add TextChangedT. (Shougo Matsushita, closes https://github.com/vim/vim/issues/11366)
author Bram Moolenaar <Bram@vim.org>
date Sat, 15 Oct 2022 13:00:02 +0200
parents dbe6a8d245ed
children 163b57477057
files runtime/doc/autocmd.txt src/autocmd.c src/terminal.c src/testdir/test_terminal.vim src/version.c src/vim.h
diffstat 6 files changed, 70 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -409,6 +409,7 @@ Name			triggered by ~
 			when popup menu is not visible
 |TextChangedP|		after a change was made to the text in Insert mode
 			when popup menu visible
+|TextChangedT|		after a change was made to the text in Terminal mode
 |TextYankPost|		after text has been yanked or deleted
 
 |SafeState|		nothing pending, going to wait for the user to type a
@@ -1237,6 +1238,10 @@ TextChangedP			After a change was made t
 				current buffer in Insert mode, only when the
 				popup menu is visible.  Otherwise the same as
 				TextChanged.
+							*TextChangedT*
+TextChangedT			After a change was made to the text in the
+				current buffer in Terminal mode.
+				Otherwise the same as TextChanged.
 							*TextYankPost*
 TextYankPost			After text has been yanked or deleted in the
 				current buffer.  The following values of
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -182,6 +182,7 @@ static struct event_name
     {"TextChanged",	EVENT_TEXTCHANGED},
     {"TextChangedI",	EVENT_TEXTCHANGEDI},
     {"TextChangedP",	EVENT_TEXTCHANGEDP},
+    {"TextChangedT",	EVENT_TEXTCHANGEDT},
     {"User",		EVENT_USER},
     {"VimEnter",	EVENT_VIMENTER},
     {"VimLeave",	EVENT_VIMLEAVE},
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -1222,6 +1222,8 @@ update_cursor(term_T *term, int redraw)
 	setcursor();
     if (redraw)
     {
+	aco_save_T	aco;
+
 	if (term->tl_buffer == curbuf && term->tl_cursor_visible)
 	    cursor_on();
 	out_flush();
@@ -1232,6 +1234,16 @@ update_cursor(term_T *term, int redraw)
 	    gui_mch_flush();
 	}
 #endif
+        // Make sure an invoked autocmd doesn't delete the buffer (and the
+        // terminal) under our fingers.
+	++term->tl_buffer->b_locked;
+
+	// save and restore curwin and curbuf, in case the autocmd changes them
+	aucmd_prepbuf(&aco, curbuf);
+	apply_autocmds(EVENT_TEXTCHANGEDT, NULL, NULL, FALSE, term->tl_buffer);
+	aucmd_restbuf(&aco);
+
+	--term->tl_buffer->b_locked;
     }
 }
 
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -2321,5 +2321,54 @@ func Test_term_wait_in_close_cb()
   bwipe!
 endfunc
 
+func Test_term_TextChangedT()
+  augroup TermTest
+    autocmd TextChangedT * ++once
+          \ execute expand('<abuf>') . 'buffer' |
+          \ let b:called = 1 |
+          \ split |
+          \ enew
+  augroup END
+
+  terminal
+
+  let term_buf = bufnr()
+
+  let b:called = 0
+
+  call term_sendkeys(term_buf, "aaabbc\r")
+  call TermWait(term_buf)
+
+  call assert_equal(1, getbufvar(term_buf, 'called'))
+
+  " Current buffer will be restored
+  call assert_equal(bufnr(), term_buf)
+
+  bwipe!
+  augroup TermTest
+    au!
+  augroup END
+endfunc
+
+func Test_term_TextChangedT_close()
+  augroup TermTest
+    autocmd TextChangedT * ++once split | enew | 1close!
+  augroup END
+
+  terminal
+
+  let term_buf = bufnr()
+
+  call term_sendkeys(term_buf, "aaabbc\r")
+  call TermWait(term_buf)
+
+  " Current buffer will be restored
+  call assert_equal(bufnr(), term_buf)
+
+  bwipe!
+  augroup TermTest
+    au!
+  augroup END
+endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    756,
+/**/
     755,
 /**/
     754,
--- a/src/vim.h
+++ b/src/vim.h
@@ -1394,6 +1394,7 @@ enum auto_event
     EVENT_TEXTCHANGED,		// text was modified not in Insert mode
     EVENT_TEXTCHANGEDI,		// text was modified in Insert mode
     EVENT_TEXTCHANGEDP,		// TextChangedI with popup menu visible
+    EVENT_TEXTCHANGEDT,		// text was modified in Terminal mode
     EVENT_TEXTYANKPOST,		// after some text was yanked
     EVENT_USER,			// user defined autocommand
     EVENT_VIMENTER,		// after starting Vim