diff options
-rw-r--r-- | src/nvim/os/rstream.c | 3 | ||||
-rw-r--r-- | src/nvim/tui/term_input.inl | 33 |
2 files changed, 24 insertions, 12 deletions
diff --git a/src/nvim/os/rstream.c b/src/nvim/os/rstream.c index a46e7d6f3c..29b8a5a9e1 100644 --- a/src/nvim/os/rstream.c +++ b/src/nvim/os/rstream.c @@ -243,8 +243,10 @@ void rstream_set_file(RStream *rstream, uv_file file) // previously allocated memory if (rstream->fread_idle != NULL) { uv_close((uv_handle_t *)rstream->fread_idle, close_cb); + rstream->fread_idle = NULL; } else { uv_close((uv_handle_t *)rstream->stream, close_cb); + rstream->stream = NULL; } } @@ -387,6 +389,7 @@ static void fread_idle_cb(uv_idle_t *handle) if (req.result <= 0) { uv_idle_stop(rstream->fread_idle); + rstream->cb(rstream, rstream->data, true); return; } diff --git a/src/nvim/tui/term_input.inl b/src/nvim/tui/term_input.inl index 9a40a64ed9..c1ccc863de 100644 --- a/src/nvim/tui/term_input.inl +++ b/src/nvim/tui/term_input.inl @@ -12,7 +12,6 @@ struct term_input { int in_fd; bool paste_enabled; TermKey *tk; - uv_pipe_t input_handle; uv_timer_t timer_handle; RBuffer *read_buffer; RStream *read_stream; @@ -210,13 +209,29 @@ static bool handle_forced_escape(TermInput *input) static void read_cb(RStream *rstream, void *rstream_data, bool eof) { + TermInput *input = rstream_data; + if (eof) { - input_done(); + if (input->in_fd == 0 && !os_isatty(0) && os_isatty(2)) { + // Started reading from stdin which is not a pty but failed. Switch to + // stderr since it is a pty. + // + // This is how we support commands like: + // + // echo q | nvim -es + // + // and + // + // ls *.md | xargs nvim + input->in_fd = 2; + rstream_set_file(input->read_stream, input->in_fd); + rstream_start(input->read_stream); + } else { + input_done(); + } return; } - TermInput *input = rstream_data; - do { if (handle_bracketed_paste(input) || handle_forced_escape(input)) { continue; @@ -240,8 +255,7 @@ static TermInput *term_input_new(void) { TermInput *rv = xmalloc(sizeof(TermInput)); rv->paste_enabled = false; - // read input from stderr if stdin is not a tty - rv->in_fd = os_isatty(0) ? 0 : (os_isatty(2) ? 2 : 0); + rv->in_fd = 0; // Set terminal encoding based on environment(taken from libtermkey source // code) @@ -259,12 +273,9 @@ static TermInput *term_input_new(void) int curflags = termkey_get_canonflags(rv->tk); termkey_set_canonflags(rv->tk, curflags | TERMKEY_CANON_DELBS); // setup input handle - uv_pipe_init(uv_default_loop(), &rv->input_handle, 0); - uv_pipe_open(&rv->input_handle, rv->in_fd); - rv->input_handle.data = NULL; rv->read_buffer = rbuffer_new(0xfff); rv->read_stream = rstream_new(read_cb, rv->read_buffer, rv); - rstream_set_stream(rv->read_stream, (uv_stream_t *)&rv->input_handle); + rstream_set_file(rv->read_stream, rv->in_fd); rstream_start(rv->read_stream); // initialize a timer handle for handling ESC with libtermkey uv_timer_init(uv_default_loop(), &rv->timer_handle); @@ -282,10 +293,8 @@ static void term_input_destroy(TermInput *input) uv_timer_stop(&input->timer_handle); rstream_stop(input->read_stream); rstream_free(input->read_stream); - uv_close((uv_handle_t *)&input->input_handle, NULL); uv_close((uv_handle_t *)&input->timer_handle, NULL); termkey_destroy(input->tk); event_poll(0); // Run once to remove references to input/timer handles - free(input->input_handle.data); free(input); } |