mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
eval: Implement jobclose()
vimscript function
This commit is contained in:
parent
028f6d7d3f
commit
b8b9e5ebad
@ -4012,6 +4012,10 @@ items({dict}) *items()*
|
|||||||
entry and the value of this entry. The |List| is in arbitrary
|
entry and the value of this entry. The |List| is in arbitrary
|
||||||
order.
|
order.
|
||||||
|
|
||||||
|
jobclose({job}[, {stream}]) {Nvim} *jobclose()*
|
||||||
|
Close {job}'s {stream}, which can be one "stdin", "stdout" or
|
||||||
|
"stderr". If {stream} is omitted, all streams are closed.
|
||||||
|
|
||||||
jobresize({job}, {width}, {height}) {Nvim} *jobresize()*
|
jobresize({job}, {width}, {height}) {Nvim} *jobresize()*
|
||||||
Resize {job}'s pseudo terminal window to {width} and {height}.
|
Resize {job}'s pseudo terminal window to {width} and {height}.
|
||||||
This function will fail if used on jobs started without the
|
This function will fail if used on jobs started without the
|
||||||
|
@ -445,6 +445,7 @@ typedef struct {
|
|||||||
Job *job;
|
Job *job;
|
||||||
Terminal *term;
|
Terminal *term;
|
||||||
bool exited;
|
bool exited;
|
||||||
|
bool stdin_closed;
|
||||||
int refcount;
|
int refcount;
|
||||||
ufunc_T *on_stdout, *on_stderr, *on_exit;
|
ufunc_T *on_stdout, *on_stderr, *on_exit;
|
||||||
dict_T *self;
|
dict_T *self;
|
||||||
@ -6535,6 +6536,7 @@ static struct fst {
|
|||||||
{"isdirectory", 1, 1, f_isdirectory},
|
{"isdirectory", 1, 1, f_isdirectory},
|
||||||
{"islocked", 1, 1, f_islocked},
|
{"islocked", 1, 1, f_islocked},
|
||||||
{"items", 1, 1, f_items},
|
{"items", 1, 1, f_items},
|
||||||
|
{"jobclose", 1, 2, f_jobclose},
|
||||||
{"jobresize", 3, 3, f_jobresize},
|
{"jobresize", 3, 3, f_jobresize},
|
||||||
{"jobsend", 2, 2, f_jobsend},
|
{"jobsend", 2, 2, f_jobsend},
|
||||||
{"jobstart", 1, 2, f_jobstart},
|
{"jobstart", 1, 2, f_jobstart},
|
||||||
@ -10658,6 +10660,48 @@ static void f_items(typval_T *argvars, typval_T *rettv)
|
|||||||
dict_list(argvars, rettv, 2);
|
dict_list(argvars, rettv, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "jobclose(id[, stream])" function
|
||||||
|
static void f_jobclose(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->v_type = VAR_NUMBER;
|
||||||
|
rettv->vval.v_number = 0;
|
||||||
|
|
||||||
|
if (check_restricted() || check_secure()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argvars[0].v_type != VAR_NUMBER || (argvars[1].v_type != VAR_STRING
|
||||||
|
&& argvars[1].v_type != VAR_UNKNOWN)) {
|
||||||
|
EMSG(_(e_invarg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Job *job = job_find(argvars[0].vval.v_number);
|
||||||
|
|
||||||
|
if (!is_user_job(job)) {
|
||||||
|
// Invalid job id
|
||||||
|
EMSG(_(e_invjob));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argvars[1].v_type == VAR_STRING) {
|
||||||
|
char *stream = (char *)argvars[1].vval.v_string;
|
||||||
|
if (!strcmp(stream, "stdin")) {
|
||||||
|
job_close_in(job);
|
||||||
|
((TerminalJobData *)job_data(job))->stdin_closed = true;
|
||||||
|
} else if (!strcmp(stream, "stdout")) {
|
||||||
|
job_close_out(job);
|
||||||
|
} else if (!strcmp(stream, "stderr")) {
|
||||||
|
job_close_err(job);
|
||||||
|
} else {
|
||||||
|
EMSG2(_("Invalid job stream \"%s\""), stream);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
((TerminalJobData *)job_data(job))->stdin_closed = true;
|
||||||
|
job_close_streams(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// "jobsend()" function
|
// "jobsend()" function
|
||||||
static void f_jobsend(typval_T *argvars, typval_T *rettv)
|
static void f_jobsend(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
@ -10683,6 +10727,11 @@ static void f_jobsend(typval_T *argvars, typval_T *rettv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (((TerminalJobData *)job_data(job))->stdin_closed) {
|
||||||
|
EMSG(_("Can't send data to the job: stdin is closed"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t input_len;
|
ssize_t input_len;
|
||||||
char *input = (char *) save_tv_as_string(&argvars[1], &input_len, false);
|
char *input = (char *) save_tv_as_string(&argvars[1], &input_len, false);
|
||||||
if (!input) {
|
if (!input) {
|
||||||
|
@ -290,6 +290,18 @@ void job_close_in(Job *job) FUNC_ATTR_NONNULL_ALL
|
|||||||
close_job_in(job);
|
close_job_in(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close the job stdout stream.
|
||||||
|
void job_close_out(Job *job) FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
close_job_out(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the job stderr stream.
|
||||||
|
void job_close_err(Job *job) FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
close_job_out(job);
|
||||||
|
}
|
||||||
|
|
||||||
/// All writes that complete after calling this function will be reported
|
/// All writes that complete after calling this function will be reported
|
||||||
/// to `cb`.
|
/// to `cb`.
|
||||||
///
|
///
|
||||||
|
@ -107,6 +107,20 @@ describe('jobs', function()
|
|||||||
eq({'notification', 'exit', {0, 0}}, next_msg())
|
eq({'notification', 'exit', {0, 0}}, next_msg())
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('can close the job streams with jobclose', function()
|
||||||
|
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
|
||||||
|
nvim('command', 'call jobclose(j, "stdin")')
|
||||||
|
eq({'notification', 'exit', {0, 0}}, next_msg())
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('wont allow jobsend with a job that closed stdin', function()
|
||||||
|
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
|
||||||
|
nvim('command', 'call jobclose(j, "stdin")')
|
||||||
|
eq(false, pcall(function()
|
||||||
|
nvim('command', 'call jobsend(j, ["some data"])')
|
||||||
|
end))
|
||||||
|
end)
|
||||||
|
|
||||||
it('will not allow jobsend/stop on a non-existent job', function()
|
it('will not allow jobsend/stop on a non-existent job', function()
|
||||||
eq(false, pcall(eval, "jobsend(-1, 'lol')"))
|
eq(false, pcall(eval, "jobsend(-1, 'lol')"))
|
||||||
eq(false, pcall(eval, "jobstop(-1)"))
|
eq(false, pcall(eval, "jobstop(-1)"))
|
||||||
|
Loading…
Reference in New Issue
Block a user