aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/os')
-rw-r--r--src/nvim/os/shell.c52
-rw-r--r--src/nvim/os/shell.h15
-rw-r--r--src/nvim/os/time.c37
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);
-}