Merge #15440 close 'shell' :terminal automatically

This commit is contained in:
Justin M. Keyes 2023-08-13 05:23:15 -07:00 committed by GitHub
commit 0fe921663f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 55 additions and 22 deletions

View File

@ -190,6 +190,10 @@ The following changes to existing APIs or features add new behavior.
supports it, unless |'keywordprg'| was customized before calling supports it, unless |'keywordprg'| was customized before calling
|vim.lsp.start()|. |vim.lsp.start()|.
• Terminal buffers started with no arguments (and use 'shell') close
automatically if the job exited without error, eliminating the (often
unwanted) "[Process exited 0]" message.
============================================================================== ==============================================================================
REMOVED FEATURES *news-removed* REMOVED FEATURES *news-removed*

View File

@ -249,6 +249,10 @@ gx Opens the current filepath or URL (decided by
Fails if changes have been made to the current buffer, Fails if changes have been made to the current buffer,
unless 'hidden' is set. unless 'hidden' is set.
If {cmd} is omitted, and the 'shell' job exits with no
error, the buffer is closed automatically
|default-autocmds|.
To enter |Terminal-mode| automatically: > To enter |Terminal-mode| automatically: >
autocmd TermOpen * startinsert autocmd TermOpen * startinsert
< <

View File

@ -133,6 +133,8 @@ remove them and ":autocmd {group}" to see how they're defined.
nvim_terminal: nvim_terminal:
- BufReadCmd: Treats "term://" buffers as |terminal| buffers. |terminal-start| - BufReadCmd: Treats "term://" buffers as |terminal| buffers. |terminal-start|
- TermClose: A |terminal| buffer started with no arguments (which thus uses
'shell') and which exits with no error is closed automatically.
nvim_cmdwin: nvim_cmdwin:
- CmdwinEnter: Limits syntax sync to maxlines=1 in the |cmdwin|. - CmdwinEnter: Limits syntax sync to maxlines=1 in the |cmdwin|.

View File

@ -1107,13 +1107,26 @@ end
function vim._init_default_autocmds() function vim._init_default_autocmds()
local nvim_terminal_augroup = vim.api.nvim_create_augroup('nvim_terminal', {}) local nvim_terminal_augroup = vim.api.nvim_create_augroup('nvim_terminal', {})
vim.api.nvim_create_autocmd({ 'bufreadcmd' }, { vim.api.nvim_create_autocmd({ 'BufReadCmd' }, {
pattern = 'term://*', pattern = 'term://*',
group = nvim_terminal_augroup, group = nvim_terminal_augroup,
nested = true, nested = true,
command = "if !exists('b:term_title')|call termopen(matchstr(expand(\"<amatch>\"), '\\c\\mterm://\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), {'cwd': expand(get(matchlist(expand(\"<amatch>\"), '\\c\\mterm://\\(.\\{-}\\)//'), 1, ''))})", command = "if !exists('b:term_title')|call termopen(matchstr(expand(\"<amatch>\"), '\\c\\mterm://\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), {'cwd': expand(get(matchlist(expand(\"<amatch>\"), '\\c\\mterm://\\(.\\{-}\\)//'), 1, ''))})",
}) })
vim.api.nvim_create_autocmd({ 'cmdwinenter' }, { vim.api.nvim_create_autocmd({ 'TermClose' }, {
group = nvim_terminal_augroup,
desc = 'Automatically close terminal buffers when started with no arguments and exiting without an error',
callback = function(args)
if vim.v.event.status == 0 then
local info = vim.api.nvim_get_chan_info(vim.bo[args.buf].channel)
local argv = info.argv or {}
if #argv == 1 and argv[1] == vim.o.shell then
vim.cmd({ cmd = 'bdelete', args = { args.buf }, bang = true })
end
end
end,
})
vim.api.nvim_create_autocmd({ 'CmdwinEnter' }, {
pattern = '[:>]', pattern = '[:>]',
group = vim.api.nvim_create_augroup('nvim_cmdwin', {}), group = vim.api.nvim_create_augroup('nvim_cmdwin', {}),
command = 'syntax sync minlines=1 maxlines=1', command = 'syntax sync minlines=1 maxlines=1',

View File

@ -103,12 +103,13 @@ describe('autocmd TermClose', function()
it('reports the correct <abuf>', function() it('reports the correct <abuf>', function()
command('set hidden') command('set hidden')
command('set shellcmdflag=EXE')
command('autocmd TermClose * let g:abuf = expand("<abuf>")') command('autocmd TermClose * let g:abuf = expand("<abuf>")')
command('edit foo') command('edit foo')
command('edit bar') command('edit bar')
eq(2, eval('bufnr("%")')) eq(2, eval('bufnr("%")'))
command('terminal') command('terminal ls')
retry(nil, nil, function() eq(3, eval('bufnr("%")')) end) retry(nil, nil, function() eq(3, eval('bufnr("%")')) end)
command('buffer 1') command('buffer 1')

View File

@ -137,23 +137,29 @@ describe(':terminal (with fake shell)', function()
-- shell-test.c is a fake shell that prints its arguments and exits. -- shell-test.c is a fake shell that prints its arguments and exits.
nvim('set_option_value', 'shell', testprg('shell-test'), {}) nvim('set_option_value', 'shell', testprg('shell-test'), {})
nvim('set_option_value', 'shellcmdflag', 'EXE', {}) nvim('set_option_value', 'shellcmdflag', 'EXE', {})
nvim('set_option_value', 'shellxquote', '', {})
end) end)
-- Invokes `:terminal {cmd}` using a fake shell (shell-test.c) which prints -- Invokes `:terminal {cmd}` using a fake shell (shell-test.c) which prints
-- the {cmd} and exits immediately . -- the {cmd} and exits immediately.
-- When no argument is given and the exit code is zero, the terminal buffer
-- closes automatically.
local function terminal_with_fake_shell(cmd) local function terminal_with_fake_shell(cmd)
feed_command("terminal "..(cmd and cmd or "")) feed_command("terminal "..(cmd and cmd or ""))
end end
it('with no argument, acts like termopen()', function() it('with no argument, acts like termopen()', function()
skip(is_os('win')) skip(is_os('win'))
terminal_with_fake_shell() -- Use the EXIT subcommand to end the process with a non-zero exit code to
-- prevent the buffer from closing automatically
nvim('set_option_value', 'shellcmdflag', 'EXIT', {})
terminal_with_fake_shell(1)
retry(nil, 4 * screen.timeout, function() retry(nil, 4 * screen.timeout, function()
screen:expect([[ screen:expect([[
^ready $ | ^ |
[Process exited 0] | [Process exited 1] |
| |
:terminal | :terminal 1 |
]]) ]])
end) end)
end) end)
@ -245,12 +251,13 @@ describe(':terminal (with fake shell)', function()
it('works with :find', function() it('works with :find', function()
skip(is_os('win')) skip(is_os('win'))
terminal_with_fake_shell() nvim('set_option_value', 'shellcmdflag', 'EXIT', {})
terminal_with_fake_shell(1)
screen:expect([[ screen:expect([[
^ready $ | ^ |
[Process exited 0] | [Process exited 1] |
| |
:terminal | :terminal 1 |
]]) ]])
eq('term://', string.match(eval('bufname("%")'), "^term://")) eq('term://', string.match(eval('bufname("%")'), "^term://"))
feed([[<C-\><C-N>]]) feed([[<C-\><C-N>]])

View File

@ -514,7 +514,9 @@ describe("'scrollback' option", function()
-- _Global_ scrollback=-1 defaults :terminal to 10_000. -- _Global_ scrollback=-1 defaults :terminal to 10_000.
command('setglobal scrollback=-1') command('setglobal scrollback=-1')
command('terminal') -- Pass a command to prevent the terminal buffer from automatically
-- closing. The ':' command is just a no-op.
command('terminal :')
eq(10000, meths.get_option_value('scrollback', {})) eq(10000, meths.get_option_value('scrollback', {}))
-- _Local_ scrollback=-1 in :terminal forces the _maximum_. -- _Local_ scrollback=-1 in :terminal forces the _maximum_.

View File

@ -2075,26 +2075,26 @@ describe('TUI FocusGained/FocusLost', function()
end) end)
it('in terminal-mode', function() it('in terminal-mode', function()
feed_data(':set shell='..testprg('shell-test')..'\n') feed_data(':set shell='..testprg('shell-test')..' shellcmdflag=EXE\n')
feed_data(':set noshowmode laststatus=0\n') feed_data(':set noshowmode laststatus=0\n')
feed_data(':terminal\n') feed_data(':terminal zia\n')
-- Wait for terminal to be ready. -- Wait for terminal to be ready.
screen:expect{grid=[[ screen:expect{grid=[[
{1:r}eady $ | {1:r}eady $ zia |
|
[Process exited 0] | [Process exited 0] |
| |
| |
| :terminal zia |
:terminal |
{3:-- TERMINAL --} | {3:-- TERMINAL --} |
]]} ]]}
feed_data('\027[I') feed_data('\027[I')
screen:expect{grid=[[ screen:expect{grid=[[
{1:r}eady $ | {1:r}eady $ zia |
[Process exited 0] |
| |
[Process exited 0] |
| |
| |
gained | gained |
@ -2103,9 +2103,9 @@ describe('TUI FocusGained/FocusLost', function()
feed_data('\027[O') feed_data('\027[O')
screen:expect([[ screen:expect([[
{1:r}eady $ | {1:r}eady $ zia |
[Process exited 0] |
| |
[Process exited 0] |
| |
| |
lost | lost |