diff options
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/src/eval.c b/src/eval.c index 18d7597a24..8cd9f30f0a 100644 --- a/src/eval.c +++ b/src/eval.c @@ -405,10 +405,11 @@ static struct vimvar { static dictitem_T vimvars_var; /* variable used for v: */ #define vimvarht vimvardict.dv_hashtab -static void apply_job_autocmds(int id, - void *data, - RStream *target, - bool from_stdout); +static void on_job_stdout(RStream *rstream, void *data, bool eof); +static void on_job_stderr(RStream *rstream, void *data, bool eof); +static void on_job_exit(Job *job, void *data); +static void on_job_data(RStream *rstream, void *data, bool eof, char *type); +static void apply_job_autocmds(Job *job, char *name, char *type, char *str); static void prepare_vimvar(int idx, typval_T *save_tv); static void restore_vimvar(int idx, typval_T *save_tv); static int ex_let_vars(char_u *arg, typval_T *tv, int copy, @@ -11073,7 +11074,9 @@ static void f_job_start(typval_T *argvars, typval_T *rettv) rettv->vval.v_number = job_start(argv, xstrdup((char *)argvars[0].vval.v_string), - apply_job_autocmds); + on_job_stdout, + on_job_stderr, + on_job_exit); if (rettv->vval.v_number <= 0) { if (rettv->vval.v_number == 0) { @@ -19796,31 +19799,56 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags) return ret; } -static void apply_job_autocmds(int id, - void *data, - RStream *target, - bool from_stdout) +static void on_job_stdout(RStream *rstream, void *data, bool eof) { - list_T *list; - char *str; - listitem_T *str_slot = listitem_alloc(); - uint32_t read_count = rstream_available(target); + if (!eof) { + on_job_data(rstream, data, eof, "stdout"); + } +} + +static void on_job_stderr(RStream *rstream, void *data, bool eof) +{ + if (!eof) { + on_job_data(rstream, data, eof, "stderr"); + } +} + +static void on_job_exit(Job *job, void *data) +{ + apply_job_autocmds(job, data, "exit", NULL); +} - // Prepare the list item containing the data read - str = xmalloc(read_count + 1); - rstream_read(target, str, read_count); +static void on_job_data(RStream *rstream, void *data, bool eof, char *type) +{ + Job *job = data; + uint32_t read_count = rstream_available(rstream); + char *str = xmalloc(read_count + 1); + + rstream_read(rstream, str, read_count); str[read_count] = NUL; - str_slot->li_tv.v_type = VAR_STRING; - str_slot->li_tv.v_lock = 0; - str_slot->li_tv.vval.v_string = (char_u *)str; + apply_job_autocmds(job, job_data(job), type, str); +} + +static void apply_job_autocmds(Job *job, char *name, char *type, char *str) +{ + list_T *list; + // Create the list which will be set to v:job_data list = list_alloc(); - list_append_number(list, id); - list_append(list, str_slot); - list_append_string(list, (char_u *)(from_stdout ? "out" : "err"), 3); + list_append_number(list, job_id(job)); + list_append_string(list, (uint8_t *)type, -1); + + if (str) { + listitem_T *str_slot = listitem_alloc(); + str_slot->li_tv.v_type = VAR_STRING; + str_slot->li_tv.v_lock = 0; + str_slot->li_tv.vval.v_string = (uint8_t *)str; + list_append(list, str_slot); + } + // Update v:job_data for the autocommands set_vim_var_list(VV_JOB_DATA, list); // Call JobActivity autocommands - apply_autocmds(EVENT_JOBACTIVITY, (char_u *)data, NULL, TRUE, NULL); + apply_autocmds(EVENT_JOBACTIVITY, (uint8_t *)name, NULL, TRUE, NULL); } |