aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/os/rstream.c3
-rw-r--r--src/nvim/tui/term_input.inl33
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);
}