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
|
||||
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()*
|
||||
Resize {job}'s pseudo terminal window to {width} and {height}.
|
||||
This function will fail if used on jobs started without the
|
||||
|
@ -445,6 +445,7 @@ typedef struct {
|
||||
Job *job;
|
||||
Terminal *term;
|
||||
bool exited;
|
||||
bool stdin_closed;
|
||||
int refcount;
|
||||
ufunc_T *on_stdout, *on_stderr, *on_exit;
|
||||
dict_T *self;
|
||||
@ -6535,6 +6536,7 @@ static struct fst {
|
||||
{"isdirectory", 1, 1, f_isdirectory},
|
||||
{"islocked", 1, 1, f_islocked},
|
||||
{"items", 1, 1, f_items},
|
||||
{"jobclose", 1, 2, f_jobclose},
|
||||
{"jobresize", 3, 3, f_jobresize},
|
||||
{"jobsend", 2, 2, f_jobsend},
|
||||
{"jobstart", 1, 2, f_jobstart},
|
||||
@ -10658,6 +10660,48 @@ static void f_items(typval_T *argvars, typval_T *rettv)
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
if (((TerminalJobData *)job_data(job))->stdin_closed) {
|
||||
EMSG(_("Can't send data to the job: stdin is closed"));
|
||||
return;
|
||||
}
|
||||
|
||||
ssize_t input_len;
|
||||
char *input = (char *) save_tv_as_string(&argvars[1], &input_len, false);
|
||||
if (!input) {
|
||||
|
@ -290,6 +290,18 @@ void job_close_in(Job *job) FUNC_ATTR_NONNULL_ALL
|
||||
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
|
||||
/// to `cb`.
|
||||
///
|
||||
|
@ -107,6 +107,20 @@ describe('jobs', function()
|
||||
eq({'notification', 'exit', {0, 0}}, next_msg())
|
||||
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()
|
||||
eq(false, pcall(eval, "jobsend(-1, 'lol')"))
|
||||
eq(false, pcall(eval, "jobstop(-1)"))
|
||||
|
Loading…
Reference in New Issue
Block a user