mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(terminal): assign channel to terminal earlier (#25771)
This commit is contained in:
parent
1094d0c0db
commit
684e93054b
@ -1034,9 +1034,12 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err)
|
|||||||
topts.write_cb = term_write;
|
topts.write_cb = term_write;
|
||||||
topts.resize_cb = term_resize;
|
topts.resize_cb = term_resize;
|
||||||
topts.close_cb = term_close;
|
topts.close_cb = term_close;
|
||||||
Terminal *term = terminal_open(buf, topts);
|
channel_incref(chan);
|
||||||
terminal_check_size(term);
|
terminal_open(&chan->term, buf, topts);
|
||||||
chan->term = term;
|
if (chan->term != NULL) {
|
||||||
|
terminal_check_size(chan->term);
|
||||||
|
}
|
||||||
|
channel_decref(chan);
|
||||||
return (Integer)chan->id;
|
return (Integer)chan->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,9 +786,8 @@ void channel_terminal_open(buf_T *buf, Channel *chan)
|
|||||||
topts.resize_cb = term_resize;
|
topts.resize_cb = term_resize;
|
||||||
topts.close_cb = term_close;
|
topts.close_cb = term_close;
|
||||||
buf->b_p_channel = (OptInt)chan->id; // 'channel' option
|
buf->b_p_channel = (OptInt)chan->id; // 'channel' option
|
||||||
Terminal *term = terminal_open(buf, topts);
|
|
||||||
chan->term = term;
|
|
||||||
channel_incref(chan);
|
channel_incref(chan);
|
||||||
|
terminal_open(&chan->term, buf, topts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void term_write(char *buf, size_t size, void *data)
|
static void term_write(char *buf, size_t size, void *data)
|
||||||
|
@ -8637,8 +8637,10 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
INTEGER_OBJ(pid), false, false, &err);
|
INTEGER_OBJ(pid), false, false, &err);
|
||||||
api_clear_error(&err);
|
api_clear_error(&err);
|
||||||
|
|
||||||
|
channel_incref(chan);
|
||||||
channel_terminal_open(curbuf, chan);
|
channel_terminal_open(curbuf, chan);
|
||||||
channel_create_event(chan, NULL);
|
channel_create_event(chan, NULL);
|
||||||
|
channel_decref(chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "timer_info([timer])" function
|
/// "timer_info([timer])" function
|
||||||
|
@ -203,10 +203,11 @@ static void term_output_callback(const char *s, size_t len, void *user_data)
|
|||||||
///
|
///
|
||||||
/// @param buf Buffer used for presentation of the terminal.
|
/// @param buf Buffer used for presentation of the terminal.
|
||||||
/// @param opts PTY process channel, various terminal properties and callbacks.
|
/// @param opts PTY process channel, various terminal properties and callbacks.
|
||||||
Terminal *terminal_open(buf_T *buf, TerminalOptions opts)
|
void terminal_open(Terminal **termpp, buf_T *buf, TerminalOptions opts)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
// Create a new terminal instance and configure it
|
// Create a new terminal instance and configure it
|
||||||
Terminal *rv = xcalloc(1, sizeof(Terminal));
|
Terminal *rv = *termpp = xcalloc(1, sizeof(Terminal));
|
||||||
rv->opts = opts;
|
rv->opts = opts;
|
||||||
rv->cursor.visible = true;
|
rv->cursor.visible = true;
|
||||||
// Associate the terminal instance with the new buffer
|
// Associate the terminal instance with the new buffer
|
||||||
@ -251,18 +252,26 @@ Terminal *terminal_open(buf_T *buf, TerminalOptions opts)
|
|||||||
RESET_BINDING(curwin);
|
RESET_BINDING(curwin);
|
||||||
// Reset cursor in current window.
|
// Reset cursor in current window.
|
||||||
curwin->w_cursor = (pos_T){ .lnum = 1, .col = 0, .coladd = 0 };
|
curwin->w_cursor = (pos_T){ .lnum = 1, .col = 0, .coladd = 0 };
|
||||||
// Initialize to check if the scrollback buffer has been allocated inside a TermOpen autocmd
|
// Initialize to check if the scrollback buffer has been allocated in a TermOpen autocmd.
|
||||||
rv->sb_buffer = NULL;
|
rv->sb_buffer = NULL;
|
||||||
// Apply TermOpen autocmds _before_ configuring the scrollback buffer.
|
// Apply TermOpen autocmds _before_ configuring the scrollback buffer.
|
||||||
apply_autocmds(EVENT_TERMOPEN, NULL, NULL, false, buf);
|
apply_autocmds(EVENT_TERMOPEN, NULL, NULL, false, buf);
|
||||||
// Local 'scrollback' _after_ autocmds.
|
|
||||||
buf->b_p_scbk = (buf->b_p_scbk < 1) ? SB_MAX : buf->b_p_scbk;
|
|
||||||
|
|
||||||
aucmd_restbuf(&aco);
|
aucmd_restbuf(&aco);
|
||||||
|
|
||||||
// Configure the scrollback buffer.
|
if (*termpp == NULL) {
|
||||||
rv->sb_size = (size_t)buf->b_p_scbk;
|
return; // Terminal has already been destroyed.
|
||||||
rv->sb_buffer = xmalloc(sizeof(ScrollbackLine *) * rv->sb_size);
|
}
|
||||||
|
|
||||||
|
if (rv->sb_buffer == NULL) {
|
||||||
|
// Local 'scrollback' _after_ autocmds.
|
||||||
|
if (buf->b_p_scbk < 1) {
|
||||||
|
buf->b_p_scbk = SB_MAX;
|
||||||
|
}
|
||||||
|
// Configure the scrollback buffer.
|
||||||
|
rv->sb_size = (size_t)buf->b_p_scbk;
|
||||||
|
rv->sb_buffer = xmalloc(sizeof(ScrollbackLine *) * rv->sb_size);
|
||||||
|
}
|
||||||
|
|
||||||
// Configure the color palette. Try to get the color from:
|
// Configure the color palette. Try to get the color from:
|
||||||
//
|
//
|
||||||
@ -290,14 +299,13 @@ Terminal *terminal_open(buf_T *buf, TerminalOptions opts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Closes the Terminal buffer.
|
/// Closes the Terminal buffer.
|
||||||
///
|
///
|
||||||
/// May call terminal_destroy, which sets caller storage to NULL.
|
/// May call terminal_destroy, which sets caller storage to NULL.
|
||||||
void terminal_close(Terminal **termpp, int status)
|
void terminal_close(Terminal **termpp, int status)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
Terminal *term = *termpp;
|
Terminal *term = *termpp;
|
||||||
if (term->destroy) {
|
if (term->destroy) {
|
||||||
@ -647,6 +655,7 @@ static int terminal_execute(VimState *state, int key)
|
|||||||
/// Frees the given Terminal structure and sets the caller storage to NULL (in the spirit of
|
/// Frees the given Terminal structure and sets the caller storage to NULL (in the spirit of
|
||||||
/// XFREE_CLEAR).
|
/// XFREE_CLEAR).
|
||||||
void terminal_destroy(Terminal **termpp)
|
void terminal_destroy(Terminal **termpp)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
Terminal *term = *termpp;
|
Terminal *term = *termpp;
|
||||||
buf_T *buf = handle_get_buffer(term->buf_handle);
|
buf_T *buf = handle_get_buffer(term->buf_handle);
|
||||||
|
@ -22,7 +22,6 @@ describe('autocmd TermClose', function()
|
|||||||
command('set shellcmdflag=EXE shellredir= shellpipe= shellquote= shellxquote=')
|
command('set shellcmdflag=EXE shellredir= shellpipe= shellquote= shellxquote=')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
local function test_termclose_delete_own_buf()
|
local function test_termclose_delete_own_buf()
|
||||||
-- The terminal process needs to keep running so that TermClose isn't triggered immediately.
|
-- The terminal process needs to keep running so that TermClose isn't triggered immediately.
|
||||||
nvim('set_option_value', 'shell', string.format('"%s" INTERACT', testprg('shell-test')), {})
|
nvim('set_option_value', 'shell', string.format('"%s" INTERACT', testprg('shell-test')), {})
|
||||||
|
@ -8,6 +8,10 @@ local pcall_err = helpers.pcall_err
|
|||||||
local feed = helpers.feed
|
local feed = helpers.feed
|
||||||
local poke_eventloop = helpers.poke_eventloop
|
local poke_eventloop = helpers.poke_eventloop
|
||||||
local is_os = helpers.is_os
|
local is_os = helpers.is_os
|
||||||
|
local meths = helpers.meths
|
||||||
|
local async_meths = helpers.async_meths
|
||||||
|
local testprg = helpers.testprg
|
||||||
|
local assert_alive = helpers.assert_alive
|
||||||
|
|
||||||
describe('terminal channel is closed and later released if', function()
|
describe('terminal channel is closed and later released if', function()
|
||||||
local screen
|
local screen
|
||||||
@ -116,3 +120,82 @@ it('chansend sends lines to terminal channel in proper order', function()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe('no crash when TermOpen autocommand', function()
|
||||||
|
local screen
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
clear()
|
||||||
|
meths.set_option_value('shell', testprg('shell-test'), {})
|
||||||
|
command('set shellcmdflag=EXE shellredir= shellpipe= shellquote= shellxquote=')
|
||||||
|
screen = Screen.new(60, 4)
|
||||||
|
screen:set_default_attr_ids({
|
||||||
|
[0] = {bold = true, foreground = Screen.colors.Blue};
|
||||||
|
})
|
||||||
|
screen:attach()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('processes job exit event when using termopen()', function()
|
||||||
|
command([[autocmd TermOpen * call input('')]])
|
||||||
|
async_meths.command('terminal foobar')
|
||||||
|
screen:expect{grid=[[
|
||||||
|
|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
^ |
|
||||||
|
]]}
|
||||||
|
feed('<CR>')
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^ready $ foobar |
|
||||||
|
|
|
||||||
|
[Process exited 0] |
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
feed('i<CR>')
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^ |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
assert_alive()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('wipes buffer and processes events when using termopen()', function()
|
||||||
|
command([[autocmd TermOpen * bwipe! | call input('')]])
|
||||||
|
async_meths.command('terminal foobar')
|
||||||
|
screen:expect{grid=[[
|
||||||
|
|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
^ |
|
||||||
|
]]}
|
||||||
|
feed('<CR>')
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^ |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
assert_alive()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('wipes buffer and processes events when using nvim_open_term()', function()
|
||||||
|
command([[autocmd TermOpen * bwipe! | call input('')]])
|
||||||
|
async_meths.open_term(0, {})
|
||||||
|
screen:expect{grid=[[
|
||||||
|
|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
^ |
|
||||||
|
]]}
|
||||||
|
feed('<CR>')
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^ |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
assert_alive()
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user