-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RDY] Refactor/enhance job api #2247
Conversation
bfb89a3
to
14b25a1
Compare
@tarruda any reason to use |
I don't remember if it was discussed before or not, but have you considered using/supporting the already existing
|
|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: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: with the any
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Is there a difference from the "user" option? Its already possible to do this: function s:Handler(id, data, user)
endfunction
call jobstart([..], {'on_stdout': 's:Handler', 'user': {}}) edit: Plus the "user" option allow passing strings, numbers or lists(Is it possible for |
Nothing except consistency with existing vimscript functionality. Not that
|
I could change the "user" option to "self" and pass it as a implicit self argument, but nothing would stop the user from doing this: function s:Handler(id, data)
self.id = 1 " self is available
endfunction
call jobstart([..], {'on_stdout': 's:Handler', 'self': {id: 0}}) Even though s:Handler is not a dictionary function. Also, I don't think there's a way avoid having to pass the "self" function despite using a dictionary function as callback: let dict = {id: 1}
function dict.handler(id, data)
echo self.id " self.id == 0
endfunction
call jobstart([..], {'on_stdout': dict.handler, 'self': {id: 0}}) That is, self will always be what is passed to |
Sorry if I'm misunderstanding something and this went completely over my head, but I understood @bfredl's suggestion as something like this: let dict = {'on_stdout': function("s:Handler"), 'id': 0}
function! s:Handler() dict
echo self.id
endfunction
call jobstart([..], dict) Where |
I use dictionary functions all the time in my plugins – they are one of the rare truly high level Vim script features, allowing OOP type encapsulation of behaviour.
It doesn't – the behaviour you describe is consistent with what |
@tarruda I didn't mean introduce yet another semantics for funcref passing, just supporting the existing semantics for calling a function inside a dict, i e if jobstart "was a vimscript function" the following would be expected to work
but as @pgdouyon pointed out, there would be a namespace conflict with the options here, so if this pattern was "actively" supported, there would probably be a separate "handlers" argument/option. |
14b25a1
to
f21f3c5
Compare
I've refactored to be more friendly with the dictionary pattern. Even with the possible namespace clashes, I think its simpler to reuse the job options object as "self", its not like the user will run out of keys 😄 |
78b219b
to
51fa871
Compare
\ 'on_exit': function('s:JobHandler') | ||
\ } | ||
let job1 = jobstart(['bash'], extend({'shell': 'shell 1'}, s:callbacks)) | ||
let job2 = jobstart(['bash', '-c', 'for ((i = 0; i < 10; i++)); do echo hello $i!; sleep 1; done'], extend({'shell': 'shell 2'}, s:callbacks)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{1..10}
could be used here too, I must have missed it the first time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
51fa871
to
85458b4
Compare
Implemented the Also modified |
0b9e8d0
to
c7226cc
Compare
@tarruda It does what's required, but enables to crash nvim:
Also, would it hurt to have separate |
d514cd8
to
4d85004
Compare
@bfredl Implemented your |
If you did not alter code that calls user functions then function NonDict()
echo l:
endfunction
function Dict() dict
echo l:
endfunction
call call('NonDict', [], {}) " echoes {}
call call('Dict', [], {}) " echoes {'self': {}} |
- Make it possible to call or unref ufunc_T pointers directly. - Keep refcount of named functions, and stop them from being deleted if the refcount is greater than 1.
- Remove JobActivity autocmd and v:job_data variable - Simplify `jobstart` to receive: - An argument vector - An optional dictionary which may contain any of the current `jobstart` options plus `on_stdout`, `on_stderr` and `on_exit` callbacks. - Refactor and add more job tests - Update documentation
Use the `is_user_job` to ensure that the job was started by `jobstart` or `termopen`.
With some spacing/indentation fixes. Helped by: @pyrohh, @kopischke
4d85004
to
b94f290
Compare
Just noted a small discrepancy between |
No reason, it's simply a consequence of how |
@rainerborene I owe you a retraction: I realize now you were talking about the vimscript |
👍 |
This is the refactor I mentioned in #2076. It aims to simplify and optimize the job API, removing the
JobActivity
/v:job_data
and calling functions instead of autocmds.It is also necessary to avoid deferred events and needless preprocessing of job data when a terminal is spawned(Currently every chunk of data received from the job is split into a list of lines with NULs replaced by linefeeds, even if no job handlers are registered)
Close #1838