diff options
| -rw-r--r-- | .ci/gcc.sh | 12 | ||||
| -rw-r--r-- | src/nvim/api/vim.c | 14 | ||||
| -rw-r--r-- | src/nvim/os/input.c | 29 | ||||
| -rw-r--r-- | src/nvim/os/job.c | 7 | 
4 files changed, 44 insertions, 18 deletions
| diff --git a/.ci/gcc.sh b/.ci/gcc.sh index 57ff52ee49..90063e48f3 100644 --- a/.ci/gcc.sh +++ b/.ci/gcc.sh @@ -11,8 +11,16 @@ export VALGRIND_LOG="$tmpdir/valgrind-%p.log"  CMAKE_EXTRA_FLAGS="-DTRAVIS_CI_BUILD=ON -DUSE_GCOV=ON"  $MAKE_CMD CMAKE_EXTRA_FLAGS="${CMAKE_EXTRA_FLAGS}" unittest -$MAKE_CMD test +if ! $MAKE_CMD test; then +	valgrind_check "$tmpdir" +	exit 1 +fi +valgrind_check "$tmpdir" + +if ! $MAKE_CMD oldtest; then +	valgrind_check "$tmpdir" +	exit 1 +fi  valgrind_check "$tmpdir" -$MAKE_CMD oldtest  coveralls --encoding iso-8859-1 || echo 'coveralls upload failed.' diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 9afefd6fa3..b6bac1588a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -24,6 +24,7 @@  #include "nvim/misc2.h"  #include "nvim/term.h"  #include "nvim/getchar.h" +#include "nvim/os/input.h"  #define LINE_BUFFER_SIZE 4096 @@ -51,6 +52,7 @@ void vim_command(String str, Error *err)  /// @param mode specifies the mapping options  /// @see feedkeys()  void vim_feedkeys(String keys, String mode) +  FUNC_ATTR_DEFERRED  {    bool remap = true;    bool typed = false; @@ -78,6 +80,18 @@ void vim_feedkeys(String keys, String mode)      typebuf_was_filled = true;  } +/// Pass input keys to Neovim. Unlike `vim_feedkeys`, this will use a +/// lower-level input buffer and the call is not deferred. +/// This is the most reliable way to emulate real user input. +/// +/// @param keys to be typed +/// @return The number bytes actually written, which can be lower than +///         requested if the buffer becomes full. +Integer vim_input(String keys) +{ +  return (Integer)input_enqueue(keys); +} +  /// Replace any terminal codes with the internal representation  ///  /// @see replace_termcodes diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index e4501aeb82..d948a48b64 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -20,8 +20,8 @@  #include "nvim/getchar.h"  #include "nvim/term.h" -#define READ_BUFFER_SIZE 0xffff -#define INPUT_BUFFER_SIZE 4096 +#define READ_BUFFER_SIZE 0xfff +#define INPUT_BUFFER_SIZE (READ_BUFFER_SIZE * 4)  typedef enum {    kInputNone, @@ -116,7 +116,6 @@ int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)      return 0;    } -  convert_input();    // Safe to convert rbuffer_read to int, it will never overflow since    // we use relatively small buffers.    return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen); @@ -132,8 +131,8 @@ bool os_char_avail(void)  // In cooked mode we should get SIGINT, no need to check.  void os_breakcheck(void)  { -  if (curr_tmode == TMODE_RAW && input_poll(0)) -    convert_input(); +  if (curr_tmode == TMODE_RAW) +    input_poll(0);  }  /// Test whether a file descriptor refers to a terminal. @@ -166,6 +165,13 @@ void input_buffer_restore(String str)    free(str.data);  } +size_t input_enqueue(String keys) +{ +  size_t rv = rbuffer_write(input_buffer, keys.data, keys.size); +  process_interrupts(); +  return rv; +} +  static bool input_poll(int ms)  {    event_poll_until(ms, input_ready()); @@ -220,6 +226,8 @@ static void read_cb(RStream *rstream, void *data, bool at_eof)      }    } +  convert_input(); +  process_interrupts();    started_reading = true;  } @@ -260,7 +268,10 @@ static void convert_input(void)      // data points to memory allocated by `string_convert_ext`, free it.      free(data);    } +} +static void process_interrupts(void) +{    if (!ctrl_c_interrupts) {      return;    } @@ -299,10 +310,10 @@ static int push_event_key(uint8_t *buf, int maxlen)  // Check if there's pending input  static bool input_ready(void)  { -  return typebuf_was_filled ||                   // API call filled typeahead -         event_has_deferred() ||                 // Events must be processed +  return typebuf_was_filled ||                    // API call filled typeahead +         event_has_deferred() ||                  // Events must be processed           (!embedded_mode && ( -            rstream_pending(read_stream) > 0 ||  // Stdin input -            eof));                               // Stdin closed +            rbuffer_pending(input_buffer) > 0 ||  // Stdin input +            eof));                                // Stdin closed  } diff --git a/src/nvim/os/job.c b/src/nvim/os/job.c index 9a11ecd1fd..f8ad6874c9 100644 --- a/src/nvim/os/job.c +++ b/src/nvim/os/job.c @@ -15,7 +15,6 @@  #include "nvim/os/shell.h"  #include "nvim/vim.h"  #include "nvim/memory.h" -#include "nvim/term.h"  #define EXIT_TIMEOUT 25  #define MAX_RUNNING_JOBS 100 @@ -277,10 +276,6 @@ void job_stop(Job *job)  ///         is possible on some OS.  int job_wait(Job *job, int ms) FUNC_ATTR_NONNULL_ALL  { -  // switch to cooked so `got_int` will be set if the user interrupts -  int old_mode = cur_tmode; -  settmode(TMODE_COOK); -    // Increase refcount to stop the job from being freed before we have a    // chance to get the status.    job->refcount++; @@ -296,8 +291,6 @@ int job_wait(Job *job, int ms) FUNC_ATTR_NONNULL_ALL      event_poll(0);    } -  settmode(old_mode); -    if (!--job->refcount) {      int status = (int) job->status;      // Manually invoke close_cb to free the job resources | 
