Skip to content

Commit

Permalink
Refactor job API
Browse files Browse the repository at this point in the history
  • Loading branch information
tarruda committed Mar 20, 2015
1 parent 3e9220b commit 45c3b43
Show file tree
Hide file tree
Showing 11 changed files with 384 additions and 217 deletions.
20 changes: 16 additions & 4 deletions runtime/doc/eval.txt
Expand Up @@ -4024,10 +4024,22 @@ jobsend({job}, {data}) {Nvim} *jobsend()*
:call jobsend(j, ["abc", "123\n456", ""])
< will send "abc<NL>123<NUL>456<NL>".

jobstart({name}, {prog}[, {argv}]) {Nvim} *jobstart()*
Spawns {prog} as a job and associate it with the {name} string,
which will be used to match the "filename pattern" in
|JobActivity| events. It returns:
jobstart({argv}[, {opts}]) {Nvim} *jobstart()*
Spawns {argv}(list) as a job. If passed, {opts} must be a
dictionary with the any of the following keys:
- on_stdout: stdout event handler
- on_stderr: stderr event handler
- on_exit: exit event handler
- user: user data passed to all callbacks
- pty: If set, the job will be connected to a new pseudo
terminal, and the job streams are connected to the master
file descriptor.
- width: Width of the terminal screen(only if pty is set)
- height: Height of the terminal screen(only if pty is set)
- TERM: $TERM environment variable(only if pty is set)
Either funcrefs or function names can be passed as event
handlers.
Returns:
- The job id on success, which is used by |jobsend()| and
|jobstop()|
- 0 when the job table is full or on invalid arguments
Expand Down
46 changes: 26 additions & 20 deletions runtime/doc/job_control.txt
Expand Up @@ -38,26 +38,28 @@ for details
2. Usage *job-control-usage*

Job control is achieved by calling a combination of the |jobstart()|,
|jobsend()| and |jobstop()| functions, and by listening to the |JobActivity|
event. The best way to understand is with a complete example:
|jobsend()| and |jobstop()| functions. The best way to understand is with a
complete example:
>
set nocp
let job1 = jobstart('shell1', 'bash')
let job2 = jobstart('shell2', 'bash', ['-c', 'for ((i = 0; i < 10; i++)); do echo hello $i!; sleep 1; done'])
function JobHandler()
if v:job_data[1] == 'stdout'
let str = 'shell '. v:job_data[0].' stdout: '.join(v:job_data[2])
elseif v:job_data[1] == 'stderr'
let str = 'shell '.v:job_data[0].' stderr: '.join(v:job_data[2])
function s:JobHandler(job_id, data, user, event)
if a:event == 'stdout'
let str = a:user.' stdout: '.join(a:data)
elseif a:event == 'stderr'
let str = a:user.' stderr: '.join(a:data)
else
let str = 'shell '.v:job_data[0].' exited'
let str = a:user.' exited'
endif
call append(line('$'), str)
endfunction
let s:callbacks = {
\ 'on_stdout': function('s:JobHandler'),
\ 'on_stderr': function('s:JobHandler'),
\ 'on_exit': function('s:JobHandler')
\ }
let job1 = jobstart(['bash'], extend({'user': 'shell 1'}, s:callbacks))
let job2 = jobstart(['bash', '-c', 'for ((i = 0; i < 10; i++)); do echo hello $i!; sleep 1; done'], extend({'user': 'shell 2'}, s:callbacks))
au JobActivity shell* call JobHandler()
<
To test the above, copy it to the file ~/jobcontrol.vim and start with a clean
nvim instance:
Expand All @@ -72,15 +74,19 @@ Here's what is happening:
- The second shell is started with the -c argument, causing it to execute a
command then exit. In this case, the command is a for loop that will print 0
through 9 then exit.
- The |JobHandler()| function is called by the `JobActivity` autocommand (notice
how the shell* pattern matches the names `shell1` and `shell2` passed to
|jobstart()|), and it takes care of displaying stdout/stderr received from
- The `JobHandler()` function is a callback passed to |jobstart()| to handle
various job events. It takes care of displaying stdout/stderr received from
the shells.
- The v:job_data is an array set by the JobActivity event. It has the
following elements:
- The arguments passed to `JobHandler()` are:

0: The job id
1: The kind of activity: one of "stdout", "stderr" or "exit"
2: When "activity" is "stdout" or "stderr", this will contain a list of
1: If the event is 'stdout' or 'stderr', a list with lines read from the
corresponding stream. For 'exit', it is the status returned by the
program.
2: User data set in the "user" option passed to |jobstart()|. Can be any
vimscript object and is used to identify the context when multiple
|jobstart()| calls share a single set of callbacks.
3: is "stdout" or "stderr", this will contain a list of
lines read from stdout or stderr

To send data to the job's stdin, one can use the |jobsend()| function, like
Expand Down

0 comments on commit 45c3b43

Please sign in to comment.