diff --git a/.github/scripts/install_deps.sh b/.github/scripts/install_deps.sh index dea9ec11da..ea2ceff277 100755 --- a/.github/scripts/install_deps.sh +++ b/.github/scripts/install_deps.sh @@ -31,7 +31,7 @@ if [[ $OS == Linux ]]; then fi if [[ -n $TEST ]]; then - sudo apt-get install -y locales-all cpanminus attr libattr1-dev gdb inotify-tools xdg-utils + sudo apt-get install -y locales-all cpanminus attr libattr1-dev fish gdb inotify-tools xdg-utils # Use default CC to avoid compilation problems when installing Python modules CC=cc python3 -m pip -q install --user --upgrade --break-system-packages pynvim @@ -47,7 +47,7 @@ elif [[ $OS == Darwin ]]; then brew update --quiet brew install ninja if [[ -n $TEST ]]; then - brew install cpanminus fswatch + brew install cpanminus fish fswatch npm install -g neovim npm link neovim diff --git a/src/nvim/os/pty_proc_unix.c b/src/nvim/os/pty_proc_unix.c index ad91c133bd..cc5cd899fb 100644 --- a/src/nvim/os/pty_proc_unix.c +++ b/src/nvim/os/pty_proc_unix.c @@ -241,7 +241,9 @@ void pty_proc_resize(PtyProc *ptyproc, uint16_t width, uint16_t height) void pty_proc_resume(PtyProc *ptyproc) { - kill(((Proc *)ptyproc)->pid, SIGCONT); + // Send SIGCONT to the entire process group, as some shells (e.g. fish) don't + // propagate SIGCONT to suspended child processes. + killpg(((Proc *)ptyproc)->pid, SIGCONT); } void pty_proc_close(PtyProc *ptyproc) diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index 56cdaca768..9717d782cc 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -612,6 +612,46 @@ end) describe(':terminal buffer', function() before_each(clear) + 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') + + local screen = Screen.new(50, 7) + screen:add_extra_attr_ids({ + [100] = { + foreground = Screen.colors.NvimDarkGrey2, + background = Screen.colors.NvimLightGrey2, + }, + [101] = { + foreground = Screen.colors.NvimLightGrey4, + background = Screen.colors.NvimLightGrey2, + }, + [102] = { + foreground = Screen.colors.NvimDarkGrey2, + background = Screen.colors.NvimLightGrey4, + }, + }) + command('set shell=fish termguicolors') + command(('terminal %s -u NONE -i NONE'):format(fn.shellescape(nvim_prog))) + command('startinsert') + local s0 = [[ + {100:^ }| + {101:~ }|*3 + {102:[No Name] 0,0-1 All}| + {100: }| + {5:-- TERMINAL --} | + ]] + screen:expect(s0) + feed('') + screen:expect([[ + |*5 + ^[Process suspended] | + {5:-- TERMINAL --} | + ]]) + feed('') + screen:expect(s0) + end) + it('term_close() use-after-free #4393', function() command('terminal yes') feed('') -- Add input to separate two RPC requests diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index 49cb5cfee5..29f17fee19 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -24,6 +24,7 @@ local eval = n.eval local command = n.command local write_file = t.write_file local api = n.api +local fn = n.fn local sleep = vim.uv.sleep local assert_alive = n.assert_alive local poke_eventloop = n.poke_eventloop @@ -88,10 +89,8 @@ describe('backtick expansion', function() end) it('with shell=fish', function() - if eval("executable('fish')") == 0 then - pending('missing "fish" command') - return - end + t.skip(fn.executable('fish') == 0, 'missing "fish" command') + command('set shell=fish') command(':silent args `echo ***2`') eq({ 'file2' }, eval('argv()'))