diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 0eff0ae69f..9d018012f0 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -779,7 +779,7 @@ FileChangedShell When Vim notices that the modification time of change or when the size of the file changes. |timestamp| Triggered for each changed file, after: - - executing a shell command + - executing a shell command or |:terminal| job - |:checktime| - |FocusGained| @@ -1169,8 +1169,9 @@ SessionWritePost After writing a session file by calling ShellCmdPost After executing a shell command with |:!cmd|, |:make| and |:grep|. Can be used to check for any changed files. + For non-blocking shell commands, see - |job-control|. + |TermClose| |job-control|. *ShellFilterPost* ShellFilterPost After executing a shell command with diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index 128913a7f0..23202e63d8 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1543,11 +1543,10 @@ Vim remembers the modification timestamp, mode and size of a file when you begin editing it. This is used to avoid that you have two different versions of the same file (without you knowing this). -After a shell command is run (|:!cmd| |suspend| |:read!| |K|) timestamps, -file modes and file sizes are compared for all buffers in a window. Vim will -run any associated |FileChangedShell| autocommands or display a warning for -any files that have changed. In the GUI this happens when Vim regains input -focus. +After a shell command (|:!cmd| |suspend| |:read!| |K|) or |:terminal| job +exits: timestamps, file modes and file sizes are compared for all buffers +in a window. Nvim will run |FileChangedShell| autocommands or display +a warning for any files that changed. *E321* *E462* If you want to automatically reload a file when it has been changed outside of diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index fee844a545..3724bde076 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -729,6 +729,11 @@ void terminal_close(Terminal **termpp, int status) return; } + if (status >= 0) { // The job may have changed files on disk, like `do_shell` (":!cmd"). + did_check_timestamps = false; + need_check_timestamps = true; + } + if (buf && !is_autocmd_blocked()) { save_v_event_T save_v_event; dict_T *dict = get_v_event(&save_v_event); diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index 65011e0acb..a27ac8cff4 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -639,6 +639,23 @@ end) describe(':terminal buffer', function() before_each(clear) + it('exit emits FileChangedShell #41759', function() + local path = t.tmpname() + write_file(path, 'foo\n') + command('edit ' .. path) + command('set noautoread') -- Disable 'autoread' to exercise :checktime specifically. + api.nvim_buf_set_lines(0, 0, -1, true, { 'local change' }) + n.exec('let g:fcs = 0 | autocmd FileChangedShell * let g:fcs = 1') + write_file(path, 'external change\n') + + -- Terminal in another tab, so returning to the buffer is not what triggers the check. + command('tabnew') + fn.jobstart({ testprg('shell-test'), 'EXIT', '0' }, { term = true }) + retry(nil, 10000, function() + eq(1, api.nvim_get_var('fcs')) + end) + end) + it('can resume suspended PTY process running in fish', function() skip(is_os('win'), 'N/A for Windows') skip(fn.executable('fish') == 0, 'missing "fish" command')