diff options
Diffstat (limited to 'src/nvim/os')
-rw-r--r-- | src/nvim/os/shell.c | 52 | ||||
-rw-r--r-- | src/nvim/os/shell.h | 15 | ||||
-rw-r--r-- | src/nvim/os/time.c | 37 |
3 files changed, 61 insertions, 43 deletions
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index cdd85e4e96..88b7f5c73d 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -141,7 +141,7 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_arg) } if (output) { - write_output(output, nread); + (void)write_output(output, nread, true, true); free(output); } @@ -197,6 +197,9 @@ static int shell(const char *cmd, // the output buffer DynamicBuffer buf = DYNAMIC_BUFFER_INIT; rstream_cb data_cb = system_data_cb; + if (nread) { + *nread = 0; + } if (forward_output) { data_cb = out_data_cb; @@ -296,9 +299,9 @@ static void system_data_cb(RStream *rstream, void *data, bool eof) static void out_data_cb(RStream *rstream, void *data, bool eof) { RBuffer *rbuffer = rstream_buffer(rstream); - size_t len = rbuffer_pending(rbuffer); - ui_write((char_u *)rbuffer_read_ptr(rbuffer), (int)len); - rbuffer_consumed(rbuffer, len); + size_t written = write_output(rbuffer_read_ptr(rbuffer), + rbuffer_pending(rbuffer), false, eof); + rbuffer_consumed(rbuffer, written); } /// Parses a command string into a sequence of words, taking quotes into @@ -407,18 +410,27 @@ static void read_input(DynamicBuffer *buf) } } -static void write_output(char *output, size_t remaining) +static size_t write_output(char *output, size_t remaining, bool to_buffer, + bool eof) { if (!output) { - return; + return 0; } + char *start = output; size_t off = 0; while (off < remaining) { if (output[off] == NL) { // Insert the line output[off] = NUL; - ml_append(curwin->w_cursor.lnum++, (char_u *)output, 0, false); + if (to_buffer) { + ml_append(curwin->w_cursor.lnum++, (char_u *)output, 0, false); + } else { + // pending data from the output buffer has been flushed to the screen, + // safe to call ui_write directly + ui_write((char_u *)output, (int)off); + ui_write((char_u *)"\r\n", 2); + } size_t skip = off + 1; output += skip; remaining -= skip; @@ -433,14 +445,26 @@ static void write_output(char *output, size_t remaining) off++; } - if (remaining) { - // append unfinished line - ml_append(curwin->w_cursor.lnum++, (char_u *)output, 0, false); - // remember that the NL was missing - curbuf->b_no_eol_lnum = curwin->w_cursor.lnum; - } else { - curbuf->b_no_eol_lnum = 0; + if (eof) { + if (remaining) { + if (to_buffer) { + // append unfinished line + ml_append(curwin->w_cursor.lnum++, (char_u *)output, 0, false); + // remember that the NL was missing + curbuf->b_no_eol_lnum = curwin->w_cursor.lnum; + } else { + ui_write((char_u *)output, (int)remaining); + ui_write((char_u *)"\r\n", 2); + } + output += remaining; + } else if (to_buffer) { + curbuf->b_no_eol_lnum = 0; + } } + + out_flush(); + + return (size_t)(output - start); } static void shell_write_cb(WStream *wstream, void *data, int status) diff --git a/src/nvim/os/shell.h b/src/nvim/os/shell.h index a4c588d7a3..64e7c79ba7 100644 --- a/src/nvim/os/shell.h +++ b/src/nvim/os/shell.h @@ -5,14 +5,13 @@ // Flags for mch_call_shell() second argument typedef enum { - kShellOptFilter = 1, ///< filtering text - kShellOptExpand = 2, ///< expanding wildcards - kShellOptCooked = 4, ///< set term to cooked mode - kShellOptDoOut = 8, ///< redirecting output - kShellOptSilent = 16, ///< don't print error returned by command - kShellOptRead = 32, ///< read lines and insert into buffer - kShellOptWrite = 64, ///< write lines from buffer - kShellOptHideMess = 128, ///< previously a global variable from os_unix.c + kShellOptFilter = 1, ///< filtering text + kShellOptExpand = 2, ///< expanding wildcards + kShellOptDoOut = 4, ///< redirecting output + kShellOptSilent = 8, ///< don't print error returned by command + kShellOptRead = 16, ///< read lines and insert into buffer + kShellOptWrite = 32, ///< write lines from buffer + kShellOptHideMess = 64, ///< previously a global variable from os_unix.c } ShellOpts; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 3794e813d2..810ddea82b 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -54,7 +54,22 @@ void os_delay(uint64_t milliseconds, bool ignoreinput) /// @param microseconds Number of microseconds to sleep void os_microdelay(uint64_t microseconds) { - microdelay(microseconds); + uint64_t elapsed = 0; + uint64_t ns = microseconds * 1000; // convert to nanoseconds + uint64_t base = uv_hrtime(); + + uv_mutex_lock(&delay_mutex); + + while (elapsed < ns) { + if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns - elapsed) + == UV_ETIMEDOUT) + break; + uint64_t now = uv_hrtime(); + elapsed += now - base; + base = now; + } + + uv_mutex_unlock(&delay_mutex); } /// Portable version of POSIX localtime_r() @@ -88,23 +103,3 @@ struct tm *os_get_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL time_t rawtime = time(NULL); return os_localtime_r(&rawtime, result); } - -static void microdelay(uint64_t microseconds) -{ - uint64_t elapsed = 0; - uint64_t ns = microseconds * 1000; // convert to nanoseconds - uint64_t base = uv_hrtime(); - - uv_mutex_lock(&delay_mutex); - - while (elapsed < ns) { - if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns - elapsed) - == UV_ETIMEDOUT) - break; - uint64_t now = uv_hrtime(); - elapsed += now - base; - base = now; - } - - uv_mutex_unlock(&delay_mutex); -} |