aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThiago de Arruda <tpadilha84@gmail.com>2014-04-16 10:40:45 -0300
committerThiago de Arruda <tpadilha84@gmail.com>2014-04-16 19:54:57 -0300
commita53f784738647f1327aca1a3e42f348ec13ef699 (patch)
treee421dc789d059d1f725787f126a8543123a84f1b /src
parent937922271a6039866ceee9800664cab3519ef3ef (diff)
downloadrneovim-a53f784738647f1327aca1a3e42f348ec13ef699.tar.gz
rneovim-a53f784738647f1327aca1a3e42f348ec13ef699.tar.bz2
rneovim-a53f784738647f1327aca1a3e42f348ec13ef699.zip
Handle special KE_EVENT case where maxlen < 3
Possible bug reported by @oni-link [here](https://github.com/neovim/neovim/pull/485/files#r11664573). It was handled by doing a circular walk through a key buffer and saving the index between calls with a static variable. Also replaced some `char_u` occurrences by `uint8_t` and removed unused headers in input.c module.
Diffstat (limited to 'src')
-rw-r--r--src/os/input.c34
-rw-r--r--src/os/input.h5
2 files changed, 27 insertions, 12 deletions
diff --git a/src/os/input.c b/src/os/input.c
index dfbe5dcc05..4311d70e54 100644
--- a/src/os/input.c
+++ b/src/os/input.c
@@ -9,13 +9,10 @@
#include "os/rstream_defs.h"
#include "os/rstream.h"
#include "vim.h"
-#include "globals.h"
#include "ui.h"
-#include "types.h"
#include "fileio.h"
#include "getchar.h"
#include "term.h"
-#include "misc2.h"
#define READ_BUFFER_SIZE 256
@@ -31,6 +28,9 @@ static bool eof = false, started_reading = false;
static InbufPollResult inbuf_poll(int32_t ms);
static void stderr_switch(void);
static void read_cb(RStream *rstream, void *data, bool eof);
+// Helper function used to push bytes from the 'event' key sequence partially
+// between calls to os_inchar when maxlen < 3
+static int push_event_key(uint8_t *buf, int maxlen);
void input_init()
{
@@ -64,10 +64,15 @@ uint32_t input_read(char *buf, uint32_t count)
// Low level input function.
-int os_inchar(char_u *buf, int maxlen, int32_t ms, int tb_change_cnt)
+int os_inchar(uint8_t *buf, int maxlen, int32_t ms, int tb_change_cnt)
{
InbufPollResult result;
+ if (event_is_pending()) {
+ // Return pending event bytes
+ return push_event_key(buf, maxlen);
+ }
+
if (ms >= 0) {
if ((result = inbuf_poll(ms)) == kInputNone) {
return 0;
@@ -88,11 +93,8 @@ int os_inchar(char_u *buf, int maxlen, int32_t ms, int tb_change_cnt)
}
// If there are pending events, return the keys directly
- if (maxlen >= 3 && event_is_pending()) {
- buf[0] = K_SPECIAL;
- buf[1] = KS_EXTRA;
- buf[2] = KE_EVENT;
- return 3;
+ if (event_is_pending()) {
+ return push_event_key(buf, maxlen);
}
// If input was put directly in typeahead buffer bail out here.
@@ -172,3 +174,17 @@ static void read_cb(RStream *rstream, void *data, bool at_eof)
started_reading = true;
}
+
+static int push_event_key(uint8_t *buf, int maxlen)
+{
+ static const uint8_t key[3] = { K_SPECIAL, KS_EXTRA, KE_EVENT };
+ static int key_idx = 0;
+ int buf_idx = 0;
+
+ do {
+ buf[buf_idx++] = key[key_idx++];
+ key_idx %= 3;
+ } while (key_idx > 0 && buf_idx < maxlen);
+
+ return buf_idx;
+}
diff --git a/src/os/input.h b/src/os/input.h
index bff66766d7..5eed09d2ee 100644
--- a/src/os/input.h
+++ b/src/os/input.h
@@ -4,15 +4,14 @@
#include <stdint.h>
#include <stdbool.h>
-#include "types.h"
-
void input_init(void);
bool input_ready(void);
void input_start(void);
void input_stop(void);
uint32_t input_read(char *buf, uint32_t count);
-int os_inchar(char_u *, int, int32_t, int);
+int os_inchar(uint8_t *, int, int32_t, int);
bool os_char_avail(void);
void os_breakcheck(void);
#endif // NEOVIM_OS_INPUT_H
+