# HG changeset patch # User Christian Brabandt # Date 1457793004 -3600 # Node ID ee5cb2e9ed5a473bc60c7337d3fbb3812bc16469 # Parent e6534d33f5ea4e344057144aa1493d53932b5572 commit https://github.com/vim/vim/commit/8950a563b306ce76f259573d91c2ddccdf52e32e Author: Bram Moolenaar Date: Sat Mar 12 15:22:55 2016 +0100 patch 7.4.1541 Problem: Missing job_info(). Solution: Implement it. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -4527,6 +4527,8 @@ job_status({job}) *job_status()* *E9 If an exit callback was set with the "exit-cb" option and the job is now detected to be "dead" the callback will be invoked. + For more information see |job_info()|. + {only available when compiled with the |+job| feature} job_stop({job} [, {how}]) *job_stop()* diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -3725,6 +3725,40 @@ job_status(job_T *job) return result; } +/* + * Implementation of job_info(). + */ + void +job_info(job_T *job, dict_T *dict) +{ + dictitem_T *item; + varnumber_T nr; + + dict_add_nr_str(dict, "status", 0L, (char_u *)job_status(job)); + + item = dictitem_alloc((char_u *)"channel"); + if (item == NULL) + return; + item->di_tv.v_lock = 0; + item->di_tv.v_type = VAR_CHANNEL; + item->di_tv.vval.v_channel = job->jv_channel; + if (job->jv_channel != NULL) + ++job->jv_channel->ch_refcount; + if (dict_add(dict, item) == FAIL) + dictitem_free(item); + +#ifdef UNIX + nr = job->jv_pid; +#else + nr = job->jv_proc_info.dwProcessId; +#endif + dict_add_nr_str(dict, "process", nr, NULL); + + dict_add_nr_str(dict, "exitval", job->jv_exitval, NULL); + dict_add_nr_str(dict, "exit-cb", 0L, job->jv_exit_cb); + dict_add_nr_str(dict, "stoponexit", 0L, job->jv_stoponexit); +} + int job_stop(job_T *job, typval_T *argvars) { diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -632,6 +632,7 @@ static void f_isnan(typval_T *argvars, t static void f_items(typval_T *argvars, typval_T *rettv); #ifdef FEAT_JOB_CHANNEL static void f_job_getchannel(typval_T *argvars, typval_T *rettv); +static void f_job_info(typval_T *argvars, typval_T *rettv); static void f_job_setoptions(typval_T *argvars, typval_T *rettv); static void f_job_start(typval_T *argvars, typval_T *rettv); static void f_job_stop(typval_T *argvars, typval_T *rettv); @@ -8208,6 +8209,7 @@ static struct fst {"items", 1, 1, f_items}, #ifdef FEAT_JOB_CHANNEL {"job_getchannel", 1, 1, f_job_getchannel}, + {"job_info", 1, 1, f_job_info}, {"job_setoptions", 2, 2, f_job_setoptions}, {"job_start", 1, 2, f_job_start}, {"job_status", 1, 1, f_job_status}, @@ -14342,6 +14344,18 @@ f_job_getchannel(typval_T *argvars, typv } /* + * "job_info()" function + */ + static void +f_job_info(typval_T *argvars, typval_T *rettv) +{ + job_T *job = get_job_arg(&argvars[0]); + + if (job != NULL && rettv_dict_alloc(rettv) != FAIL) + job_info(job, rettv->vval.v_dict); +} + +/* * "job_setoptions()" function */ static void @@ -14375,13 +14389,11 @@ f_job_start(typval_T *argvars, typval_T f_job_status(typval_T *argvars, typval_T *rettv) { job_T *job = get_job_arg(&argvars[0]); - char *result; if (job != NULL) { - result = job_status(job); rettv->v_type = VAR_STRING; - rettv->vval.v_string = vim_strsave((char_u *)result); + rettv->vval.v_string = vim_strsave((char_u *)job_status(job)); } } diff --git a/src/proto/channel.pro b/src/proto/channel.pro --- a/src/proto/channel.pro +++ b/src/proto/channel.pro @@ -54,5 +54,6 @@ void job_stop_on_exit(void); void job_check_ended(void); job_T *job_start(typval_T *argvars); char *job_status(job_T *job); +void job_info(job_T *job, dict_T *dict); int job_stop(job_T *job, typval_T *argvars); /* vim: set ft=c : */ diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -479,6 +479,12 @@ func Test_raw_pipe() finally call job_stop(job) endtry + + let s:job = job + call s:waitFor('"dead" == job_status(s:job)') + let info = job_info(job) + call assert_equal("dead", info.status) + call assert_equal("term", info.stoponexit) endfunc func Test_nl_pipe() @@ -1051,6 +1057,7 @@ endfunc function s:test_exit_callback(port) call job_setoptions(s:job, {'exit-cb': 'MyExitCb'}) let s:exit_job = s:job + call assert_equal('MyExitCb', job_info(s:job)['exit-cb']) endfunc func Test_exit_callback() @@ -1069,6 +1076,7 @@ func Test_exit_callback() endfor call assert_equal('done', s:job_exit_ret) + call assert_equal('dead', job_info(s:exit_job).status) unlet s:exit_job endif endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -744,6 +744,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1541, +/**/ 1540, /**/ 1539,