api: Add vim_input function and mark vim_feedkeys as deferred

The `vim_feedkeys` must be deferred because it can potentially free the buffer
passed to `os_inchar`(which in turns calls `vim_feedkeys` indirectly).

The new `vim_input` function can be used to emulate user input(Since it does not
mess with the typeahead, it is safe to execute without deferring).
This commit is contained in:
Thiago de Arruda
2014-10-29 23:06:18 -03:00
parent 94527245a5
commit 3800b24c5a
2 changed files with 21 additions and 0 deletions

View File

@@ -24,6 +24,7 @@
#include "nvim/misc2.h" #include "nvim/misc2.h"
#include "nvim/term.h" #include "nvim/term.h"
#include "nvim/getchar.h" #include "nvim/getchar.h"
#include "nvim/os/input.h"
#define LINE_BUFFER_SIZE 4096 #define LINE_BUFFER_SIZE 4096
@@ -51,6 +52,7 @@ void vim_command(String str, Error *err)
/// @param mode specifies the mapping options /// @param mode specifies the mapping options
/// @see feedkeys() /// @see feedkeys()
void vim_feedkeys(String keys, String mode) void vim_feedkeys(String keys, String mode)
FUNC_ATTR_DEFERRED
{ {
bool remap = true; bool remap = true;
bool typed = false; bool typed = false;
@@ -78,6 +80,18 @@ void vim_feedkeys(String keys, String mode)
typebuf_was_filled = true; 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 /// Replace any terminal codes with the internal representation
/// ///
/// @see replace_termcodes /// @see replace_termcodes

View File

@@ -165,6 +165,13 @@ void input_buffer_restore(String str)
free(str.data); 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) static bool input_poll(int ms)
{ {
event_poll_until(ms, input_ready()); event_poll_until(ms, input_ready());