# HG changeset patch # User Bram Moolenaar # Date 1665831602 -7200 # Node ID 82e62fd4eae96355c6b9f428afd5d803e7cc4ff1 # Parent dbe6a8d245ed82b46f1c6a24743d8308a20bc9ee 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 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) diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt --- 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 diff --git a/src/autocmd.c b/src/autocmd.c --- 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}, diff --git a/src/terminal.c b/src/terminal.c --- 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; } } diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim --- 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('') . '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 diff --git a/src/version.c b/src/version.c --- 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, diff --git a/src/vim.h b/src/vim.h --- 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