mirror of
https://github.com/neovim/neovim.git
synced 2025-09-21 18:58:18 +00:00
Merge PR #3210 'Bugfixes'
Helped-by: oni-link <knil.ino@gmail.com> Reviewed-by: oni-link <knil.ino@gmail.com>
This commit is contained in:
@@ -18987,7 +18987,7 @@ void ex_function(exarg_T *eap)
|
|||||||
emsg_funcname(e_funcexts, name);
|
emsg_funcname(e_funcexts, name);
|
||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
if (fp->uf_calls > 0) {
|
if (fp->uf_refcount > 1 || fp->uf_calls > 0) {
|
||||||
emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"),
|
emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"),
|
||||||
name);
|
name);
|
||||||
goto erret;
|
goto erret;
|
||||||
@@ -21136,14 +21136,18 @@ static inline bool common_job_start(TerminalJobData *data, typval_T *rettv)
|
|||||||
{
|
{
|
||||||
data->refcount++;
|
data->refcount++;
|
||||||
Process *proc = (Process *)&data->proc;
|
Process *proc = (Process *)&data->proc;
|
||||||
|
char *cmd = xstrdup(proc->argv[0]);
|
||||||
if (!process_spawn(proc)) {
|
if (!process_spawn(proc)) {
|
||||||
EMSG(_(e_jobexe));
|
EMSG2(_(e_jobspawn), cmd);
|
||||||
|
xfree(cmd);
|
||||||
if (proc->type == kProcessTypePty) {
|
if (proc->type == kProcessTypePty) {
|
||||||
xfree(data->proc.pty.term_name);
|
xfree(data->proc.pty.term_name);
|
||||||
free_term_job_data(data);
|
|
||||||
}
|
}
|
||||||
|
rettv->vval.v_number = proc->status;
|
||||||
|
term_job_data_decref(data);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
xfree(cmd);
|
||||||
|
|
||||||
data->id = current_job_id++;
|
data->id = current_job_id++;
|
||||||
wstream_init(proc->in, 0);
|
wstream_init(proc->in, 0);
|
||||||
|
@@ -66,7 +66,12 @@ bool process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
|
|||||||
if (proc->err) {
|
if (proc->err) {
|
||||||
uv_close((uv_handle_t *)&proc->err->uv.pipe, NULL);
|
uv_close((uv_handle_t *)&proc->err->uv.pipe, NULL);
|
||||||
}
|
}
|
||||||
process_close(proc);
|
|
||||||
|
if (proc->type == kProcessTypeUv) {
|
||||||
|
uv_close((uv_handle_t *)&(((UvProcess *)proc)->uv), NULL);
|
||||||
|
} else {
|
||||||
|
process_close(proc);
|
||||||
|
}
|
||||||
shell_free_argv(proc->argv);
|
shell_free_argv(proc->argv);
|
||||||
proc->status = -1;
|
proc->status = -1;
|
||||||
return false;
|
return false;
|
||||||
|
@@ -1107,6 +1107,8 @@ EXTERN char_u e_isadir2[] INIT(= N_("E17: \"%s\" is a directory"));
|
|||||||
EXTERN char_u e_invjob[] INIT(= N_("E900: Invalid job id"));
|
EXTERN char_u e_invjob[] INIT(= N_("E900: Invalid job id"));
|
||||||
EXTERN char_u e_jobtblfull[] INIT(= N_("E901: Job table is full"));
|
EXTERN char_u e_jobtblfull[] INIT(= N_("E901: Job table is full"));
|
||||||
EXTERN char_u e_jobexe[] INIT(= N_("E902: \"%s\" is not an executable"));
|
EXTERN char_u e_jobexe[] INIT(= N_("E902: \"%s\" is not an executable"));
|
||||||
|
EXTERN char_u e_jobspawn[] INIT(= N_(
|
||||||
|
"E903: Process for command \"%s\" could not be spawned"));
|
||||||
EXTERN char_u e_jobnotpty[] INIT(= N_("E904: Job is not connected to a pty"));
|
EXTERN char_u e_jobnotpty[] INIT(= N_("E904: Job is not connected to a pty"));
|
||||||
EXTERN char_u e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\""));
|
EXTERN char_u e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\""));
|
||||||
EXTERN char_u e_mkdir[] INIT(= N_("E739: Cannot create directory %s: %s"));
|
EXTERN char_u e_mkdir[] INIT(= N_("E739: Cannot create directory %s: %s"));
|
||||||
|
@@ -245,6 +245,7 @@ int main(int argc, char **argv)
|
|||||||
set_vim_var_string(VV_PROGPATH, (char_u *)argv[0], -1);
|
set_vim_var_string(VV_PROGPATH, (char_u *)argv[0], -1);
|
||||||
set_vim_var_string(VV_PROGNAME, path_tail((char_u *)argv[0]), -1);
|
set_vim_var_string(VV_PROGNAME, path_tail((char_u *)argv[0]), -1);
|
||||||
|
|
||||||
|
event_init();
|
||||||
/*
|
/*
|
||||||
* Process the command line arguments. File names are put in the global
|
* Process the command line arguments. File names are put in the global
|
||||||
* argument list "global_alist".
|
* argument list "global_alist".
|
||||||
@@ -275,7 +276,6 @@ int main(int argc, char **argv)
|
|||||||
if (GARGCOUNT > 1 && !silent_mode)
|
if (GARGCOUNT > 1 && !silent_mode)
|
||||||
printf(_("%d files to edit\n"), GARGCOUNT);
|
printf(_("%d files to edit\n"), GARGCOUNT);
|
||||||
|
|
||||||
event_init();
|
|
||||||
full_screen = true;
|
full_screen = true;
|
||||||
t_colors = 256;
|
t_colors = 256;
|
||||||
check_tty(¶ms);
|
check_tty(¶ms);
|
||||||
@@ -963,6 +963,7 @@ static void command_line_scan(mparm_T *parmp)
|
|||||||
} else if (STRICMP(argv[0] + argv_idx, "embed") == 0) {
|
} else if (STRICMP(argv[0] + argv_idx, "embed") == 0) {
|
||||||
embedded_mode = true;
|
embedded_mode = true;
|
||||||
parmp->headless = true;
|
parmp->headless = true;
|
||||||
|
channel_from_stdio();
|
||||||
} else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
|
} else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
|
||||||
#if !defined(UNIX)
|
#if !defined(UNIX)
|
||||||
parmp->literal = TRUE;
|
parmp->literal = TRUE;
|
||||||
|
@@ -93,11 +93,6 @@ void channel_init(void)
|
|||||||
channels = pmap_new(uint64_t)();
|
channels = pmap_new(uint64_t)();
|
||||||
event_strings = pmap_new(cstr_t)();
|
event_strings = pmap_new(cstr_t)();
|
||||||
msgpack_sbuffer_init(&out_buffer);
|
msgpack_sbuffer_init(&out_buffer);
|
||||||
|
|
||||||
if (embedded_mode) {
|
|
||||||
channel_from_stdio();
|
|
||||||
}
|
|
||||||
|
|
||||||
remote_ui_init();
|
remote_ui_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +311,7 @@ bool channel_close(uint64_t id)
|
|||||||
|
|
||||||
/// Creates an API channel from stdin/stdout. This is used when embedding
|
/// Creates an API channel from stdin/stdout. This is used when embedding
|
||||||
/// Neovim
|
/// Neovim
|
||||||
static void channel_from_stdio(void)
|
void channel_from_stdio(void)
|
||||||
{
|
{
|
||||||
Channel *channel = register_channel(kChannelTypeStdio);
|
Channel *channel = register_channel(kChannelTypeStdio);
|
||||||
incref(channel); // stdio channels are only closed on exit
|
incref(channel); // stdio channels are only closed on exit
|
||||||
|
@@ -28,7 +28,7 @@ void remote_ui_init(void)
|
|||||||
connected_uis = pmap_new(uint64_t)();
|
connected_uis = pmap_new(uint64_t)();
|
||||||
// Add handler for "attach_ui"
|
// Add handler for "attach_ui"
|
||||||
String method = cstr_as_string("ui_attach");
|
String method = cstr_as_string("ui_attach");
|
||||||
MsgpackRpcRequestHandler handler = {.fn = remote_ui_attach, .async = true};
|
MsgpackRpcRequestHandler handler = {.fn = remote_ui_attach, .async = false};
|
||||||
msgpack_rpc_add_method_handler(method, handler);
|
msgpack_rpc_add_method_handler(method, handler);
|
||||||
method = cstr_as_string("ui_detach");
|
method = cstr_as_string("ui_detach");
|
||||||
handler.fn = remote_ui_detach;
|
handler.fn = remote_ui_detach;
|
||||||
|
@@ -423,7 +423,9 @@ end:
|
|||||||
ui_busy_stop();
|
ui_busy_stop();
|
||||||
if (close) {
|
if (close) {
|
||||||
term->opts.close_cb(term->opts.data);
|
term->opts.close_cb(term->opts.data);
|
||||||
do_cmdline_cmd("bwipeout!");
|
if (term->buf) {
|
||||||
|
do_cmdline_cmd("bwipeout!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -140,6 +140,7 @@ UI *tui_start(void)
|
|||||||
|
|
||||||
// listen for SIGWINCH
|
// listen for SIGWINCH
|
||||||
signal_watcher_init(&loop, &data->winch_handle, ui);
|
signal_watcher_init(&loop, &data->winch_handle, ui);
|
||||||
|
data->winch_handle.events = queue_new_child(loop.events);
|
||||||
signal_watcher_start(&data->winch_handle, sigwinch_cb, SIGWINCH);
|
signal_watcher_start(&data->winch_handle, sigwinch_cb, SIGWINCH);
|
||||||
|
|
||||||
ui->stop = tui_stop;
|
ui->stop = tui_stop;
|
||||||
@@ -179,6 +180,7 @@ static void tui_stop(UI *ui)
|
|||||||
// Destroy common stuff
|
// Destroy common stuff
|
||||||
kv_destroy(data->invalid_regions);
|
kv_destroy(data->invalid_regions);
|
||||||
signal_watcher_stop(&data->winch_handle);
|
signal_watcher_stop(&data->winch_handle);
|
||||||
|
queue_free(data->winch_handle.events);
|
||||||
signal_watcher_close(&data->winch_handle, NULL);
|
signal_watcher_close(&data->winch_handle, NULL);
|
||||||
// Destroy input stuff
|
// Destroy input stuff
|
||||||
term_input_destroy(data->input);
|
term_input_destroy(data->input);
|
||||||
|
@@ -6,6 +6,7 @@ local clear, eq, eval, execute, expect, feed, insert, neq, next_msg, nvim,
|
|||||||
helpers.insert, helpers.neq, helpers.next_message, helpers.nvim,
|
helpers.insert, helpers.neq, helpers.next_message, helpers.nvim,
|
||||||
helpers.nvim_dir, helpers.ok, helpers.run, helpers.session, helpers.source,
|
helpers.nvim_dir, helpers.ok, helpers.run, helpers.session, helpers.source,
|
||||||
helpers.stop, helpers.wait, helpers.write_file
|
helpers.stop, helpers.wait, helpers.write_file
|
||||||
|
local Screen = require('test.functional.ui.screen')
|
||||||
|
|
||||||
|
|
||||||
describe('jobs', function()
|
describe('jobs', function()
|
||||||
@@ -188,6 +189,41 @@ describe('jobs', function()
|
|||||||
eq({'notification', 'exit', {45, 10}}, next_msg())
|
eq({'notification', 'exit', {45, 10}}, next_msg())
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('cant redefine callbacks being used by a job', function()
|
||||||
|
local screen = Screen.new()
|
||||||
|
screen:attach()
|
||||||
|
local script = [[
|
||||||
|
function! g:JobHandler(job_id, data, event)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let g:callbacks = {
|
||||||
|
\ 'on_stdout': function('g:JobHandler'),
|
||||||
|
\ 'on_stderr': function('g:JobHandler'),
|
||||||
|
\ 'on_exit': function('g:JobHandler')
|
||||||
|
\ }
|
||||||
|
let job = jobstart('cat -', g:callbacks)
|
||||||
|
]]
|
||||||
|
source(script)
|
||||||
|
feed(':function! g:JobHandler(job_id, data, event)<cr>')
|
||||||
|
feed(':endfunction<cr>')
|
||||||
|
screen:expect([[
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
:function! g:JobHandler(job_id, data, event) |
|
||||||
|
: :endfunction |
|
||||||
|
E127: Cannot redefine function JobHandler: It is in u|
|
||||||
|
se |
|
||||||
|
Press ENTER or type command to continue^ |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
describe('jobwait', function()
|
describe('jobwait', function()
|
||||||
it('returns a list of status codes', function()
|
it('returns a list of status codes', function()
|
||||||
source([[
|
source([[
|
||||||
|
Reference in New Issue
Block a user