aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/autoload/provider.vim5
-rw-r--r--runtime/autoload/provider/pythonx.vim2
-rw-r--r--runtime/doc/eval.txt5
-rw-r--r--src/nvim/channel.c4
-rw-r--r--src/nvim/eval/funcs.c20
-rw-r--r--src/nvim/event/libuv_process.c7
-rw-r--r--src/nvim/event/process.h2
7 files changed, 34 insertions, 11 deletions
diff --git a/runtime/autoload/provider.vim b/runtime/autoload/provider.vim
index dc24e801d0..803c1a0b1c 100644
--- a/runtime/autoload/provider.vim
+++ b/runtime/autoload/provider.vim
@@ -3,8 +3,11 @@
" Start the provider and perform a 'poll' request
"
" Returns a valid channel on success
-function! provider#Poll(argv, orig_name, log_env) abort
+function! provider#Poll(argv, orig_name, log_env, ...) abort
let job = {'rpc': v:true, 'stderr_buffered': v:true}
+ if a:0
+ let job = extend(job, a:1)
+ endif
try
let channel_id = jobstart(a:argv, job)
if channel_id > 0 && rpcrequest(channel_id, 'poll') ==# 'ok'
diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim
index ffb9bf3021..e89d519790 100644
--- a/runtime/autoload/provider/pythonx.vim
+++ b/runtime/autoload/provider/pythonx.vim
@@ -19,7 +19,7 @@ function! provider#pythonx#Require(host) abort
call add(args, plugin.path)
endfor
- return provider#Poll(args, a:host.orig_name, '$NVIM_PYTHON_LOG_FILE')
+ return provider#Poll(args, a:host.orig_name, '$NVIM_PYTHON_LOG_FILE', {'overlapped': v:true})
endfunction
function! s:get_python_executable_from_host_var(major_version) abort
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 99bc526659..92f703a8a3 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -5506,6 +5506,11 @@ jobstart({cmd}[, {opts}]) *jobstart()*
stdout data.
|on_stderr|: (function) Callback invoked when the job emits
stderr data.
+ overlapped: (boolean) Set FILE_FLAG_OVERLAPPED for the
+ standard input/output passed to the child process.
+ Normally you do not need to set this.
+ (Only available on MS-Windows, On other
+ platforms, this option is silently ignored.)
pty: (boolean) Connect the job to a new pseudo
terminal, and its streams to the master file
descriptor. Then `on_stderr` is ignored,
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 5eb29a7290..37cbfb968b 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -301,7 +301,8 @@ static void close_cb(Stream *stream, void *data)
/// @returns [allocated] channel
Channel *channel_job_start(char **argv, CallbackReader on_stdout,
CallbackReader on_stderr, Callback on_exit,
- bool pty, bool rpc, bool detach, const char *cwd,
+ bool pty, bool rpc, bool overlapped, bool detach,
+ const char *cwd,
uint16_t pty_width, uint16_t pty_height,
char *term_name, char **env, varnumber_T *status_out)
{
@@ -342,6 +343,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
proc->detach = detach;
proc->cwd = cwd;
proc->env = env;
+ proc->overlapped = overlapped;
char *cmd = xstrdup(proc->argv[0]);
bool has_out, has_err;
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 4526eecaba..1071e75c06 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -4862,6 +4862,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool rpc = false;
bool pty = false;
bool clear_env = false;
+ bool overlapped = false;
CallbackReader on_stdout = CALLBACK_READER_INIT,
on_stderr = CALLBACK_READER_INIT;
Callback on_exit = CALLBACK_NONE;
@@ -4873,12 +4874,23 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rpc = tv_dict_get_number(job_opts, "rpc") != 0;
pty = tv_dict_get_number(job_opts, "pty") != 0;
clear_env = tv_dict_get_number(job_opts, "clear_env") != 0;
+ overlapped = tv_dict_get_number(job_opts, "overlapped") != 0;
+
if (pty && rpc) {
EMSG2(_(e_invarg2), "job cannot have both 'pty' and 'rpc' options set");
shell_free_argv(argv);
return;
}
+#ifdef WIN32
+ if (pty && overlapped) {
+ EMSG2(_(e_invarg2),
+ "job cannot have both 'pty' and 'overlapped' options set");
+ shell_free_argv(argv);
+ return;
+ }
+#endif
+
char *new_cwd = tv_dict_get_string(job_opts, "cwd", false);
if (new_cwd && strlen(new_cwd) > 0) {
cwd = new_cwd;
@@ -4945,7 +4957,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, pty,
- rpc, detach, cwd, width, height,
+ rpc, overlapped, detach, cwd, width, height,
term_name, env, &rettv->vval.v_number);
if (chan) {
channel_create_event(chan, NULL);
@@ -7372,8 +7384,8 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
Channel *chan = channel_job_start(argv, CALLBACK_READER_INIT,
CALLBACK_READER_INIT, CALLBACK_NONE,
- false, true, false, NULL, 0, 0, NULL, NULL,
- &rettv->vval.v_number);
+ false, true, false, false, NULL, 0, 0,
+ NULL, NULL, &rettv->vval.v_number);
if (chan) {
channel_create_event(chan, NULL);
}
@@ -10461,7 +10473,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
uint16_t term_width = MAX(0, curwin->w_width_inner - win_col_off(curwin));
Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit,
- true, false, false, cwd,
+ true, false, false, false, cwd,
term_width, curwin->w_height_inner,
xstrdup("xterm-256color"), NULL,
&rettv->vval.v_number);
diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c
index 37b9f73ba4..13517d3df1 100644
--- a/src/nvim/event/libuv_process.c
+++ b/src/nvim/event/libuv_process.c
@@ -52,7 +52,7 @@ int libuv_process_spawn(LibuvProcess *uvproc)
if (!proc->in.closed) {
uvproc->uvstdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
#ifdef WIN32
- uvproc->uvstdio[0].flags |= UV_OVERLAPPED_PIPE;
+ uvproc->uvstdio[0].flags |= proc->overlapped ? UV_OVERLAPPED_PIPE : 0;
#endif
uvproc->uvstdio[0].data.stream = STRUCT_CAST(uv_stream_t,
&proc->in.uv.pipe);
@@ -61,8 +61,9 @@ int libuv_process_spawn(LibuvProcess *uvproc)
if (!proc->out.closed) {
uvproc->uvstdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
#ifdef WIN32
- // pipe must be readable for IOCP to work.
- uvproc->uvstdio[1].flags |= UV_READABLE_PIPE | UV_OVERLAPPED_PIPE;
+ // pipe must be readable for IOCP to work on Windows.
+ uvproc->uvstdio[1].flags |= proc->overlapped ?
+ (UV_READABLE_PIPE | UV_OVERLAPPED_PIPE) : 0;
#endif
uvproc->uvstdio[1].data.stream = STRUCT_CAST(uv_stream_t,
&proc->out.uv.pipe);
diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
index b677b80bfe..84e81238e9 100644
--- a/src/nvim/event/process.h
+++ b/src/nvim/event/process.h
@@ -27,7 +27,7 @@ struct process {
Stream in, out, err;
process_exit_cb cb;
internal_process_cb internal_exit_cb, internal_close_cb;
- bool closed, detach;
+ bool closed, detach, overlapped;
MultiQueue *events;
};