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.
This commit is contained in:
Thiago de Arruda 2014-04-16 10:40:45 -03:00
parent 937922271a
commit a53f784738
2 changed files with 27 additions and 12 deletions

View File

@ -9,13 +9,10 @@
#include "os/rstream_defs.h" #include "os/rstream_defs.h"
#include "os/rstream.h" #include "os/rstream.h"
#include "vim.h" #include "vim.h"
#include "globals.h"
#include "ui.h" #include "ui.h"
#include "types.h"
#include "fileio.h" #include "fileio.h"
#include "getchar.h" #include "getchar.h"
#include "term.h" #include "term.h"
#include "misc2.h"
#define READ_BUFFER_SIZE 256 #define READ_BUFFER_SIZE 256
@ -31,6 +28,9 @@ static bool eof = false, started_reading = false;
static InbufPollResult inbuf_poll(int32_t ms); static InbufPollResult inbuf_poll(int32_t ms);
static void stderr_switch(void); static void stderr_switch(void);
static void read_cb(RStream *rstream, void *data, bool eof); 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() void input_init()
{ {
@ -64,10 +64,15 @@ uint32_t input_read(char *buf, uint32_t count)
// Low level input function. // 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; InbufPollResult result;
if (event_is_pending()) {
// Return pending event bytes
return push_event_key(buf, maxlen);
}
if (ms >= 0) { if (ms >= 0) {
if ((result = inbuf_poll(ms)) == kInputNone) { if ((result = inbuf_poll(ms)) == kInputNone) {
return 0; 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 there are pending events, return the keys directly
if (maxlen >= 3 && event_is_pending()) { if (event_is_pending()) {
buf[0] = K_SPECIAL; return push_event_key(buf, maxlen);
buf[1] = KS_EXTRA;
buf[2] = KE_EVENT;
return 3;
} }
// If input was put directly in typeahead buffer bail out here. // 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; 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;
}

View File

@ -4,15 +4,14 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "types.h"
void input_init(void); void input_init(void);
bool input_ready(void); bool input_ready(void);
void input_start(void); void input_start(void);
void input_stop(void); void input_stop(void);
uint32_t input_read(char *buf, uint32_t count); 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); bool os_char_avail(void);
void os_breakcheck(void); void os_breakcheck(void);
#endif // NEOVIM_OS_INPUT_H #endif // NEOVIM_OS_INPUT_H