mirror of
https://github.com/neovim/neovim
synced 2025-07-16 09:11:51 +00:00
Merge pull request #29114 from bfredl/key_buffer
refactor(tui): use a linear buffer for buffered keys
This commit is contained in:
@ -28,7 +28,6 @@
|
||||
#include "nvim/msgpack_rpc/channel.h"
|
||||
|
||||
#define READ_STREAM_SIZE 0xfff
|
||||
#define KEY_BUFFER_SIZE 0xfff
|
||||
|
||||
/// Size of libtermkey's internal input buffer. The buffer may grow larger than
|
||||
/// this when processing very long escape sequences, but will shrink back to
|
||||
@ -132,7 +131,6 @@ void tinput_init(TermInput *input, Loop *loop)
|
||||
input->key_encoding = kKeyEncodingLegacy;
|
||||
input->ttimeout = (bool)p_ttimeout;
|
||||
input->ttimeoutlen = p_ttm;
|
||||
input->key_buffer = rbuffer_new(KEY_BUFFER_SIZE);
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(kitty_key_map_entry); i++) {
|
||||
pmap_put(int)(&kitty_key_map, kitty_key_map_entry[i].key, (ptr_t)kitty_key_map_entry[i].name);
|
||||
@ -165,7 +163,6 @@ void tinput_init(TermInput *input, Loop *loop)
|
||||
void tinput_destroy(TermInput *input)
|
||||
{
|
||||
map_destroy(int, &kitty_key_map);
|
||||
rbuffer_free(input->key_buffer);
|
||||
uv_close((uv_handle_t *)&input->timer_handle, NULL);
|
||||
rstream_may_close(&input->read_stream);
|
||||
termkey_destroy(input->tk);
|
||||
@ -191,44 +188,38 @@ static void tinput_done_event(void **argv)
|
||||
/// Send all pending input in key buffer to Nvim server.
|
||||
static void tinput_flush(TermInput *input)
|
||||
{
|
||||
String keys = { .data = input->key_buffer, .size = input->key_buffer_len };
|
||||
if (input->paste) { // produce exactly one paste event
|
||||
const size_t len = rbuffer_size(input->key_buffer);
|
||||
String keys = { .data = xmallocz(len), .size = len };
|
||||
rbuffer_read(input->key_buffer, keys.data, len);
|
||||
MAXSIZE_TEMP_ARRAY(args, 3);
|
||||
ADD_C(args, STRING_OBJ(keys)); // 'data'
|
||||
ADD_C(args, BOOLEAN_OBJ(true)); // 'crlf'
|
||||
ADD_C(args, INTEGER_OBJ(input->paste)); // 'phase'
|
||||
rpc_send_event(ui_client_channel_id, "nvim_paste", args);
|
||||
api_free_string(keys);
|
||||
if (input->paste == 1) {
|
||||
// Paste phase: "continue"
|
||||
input->paste = 2;
|
||||
}
|
||||
rbuffer_reset(input->key_buffer);
|
||||
} else { // enqueue input
|
||||
RBUFFER_UNTIL_EMPTY(input->key_buffer, buf, len) {
|
||||
const String keys = { .data = buf, .size = len };
|
||||
if (input->key_buffer_len > 0) {
|
||||
MAXSIZE_TEMP_ARRAY(args, 1);
|
||||
ADD_C(args, STRING_OBJ(keys));
|
||||
// NOTE: This is non-blocking and won't check partially processed input,
|
||||
// but should be fine as all big sends are handled with nvim_paste, not nvim_input
|
||||
rpc_send_event(ui_client_channel_id, "nvim_input", args);
|
||||
rbuffer_consumed(input->key_buffer, len);
|
||||
rbuffer_reset(input->key_buffer);
|
||||
}
|
||||
}
|
||||
input->key_buffer_len = 0;
|
||||
}
|
||||
|
||||
static void tinput_enqueue(TermInput *input, char *buf, size_t size)
|
||||
{
|
||||
if (rbuffer_size(input->key_buffer) >
|
||||
rbuffer_capacity(input->key_buffer) - 0xff) {
|
||||
// don't ever let the buffer get too full or we risk putting incomplete keys
|
||||
// into it
|
||||
if (input->key_buffer_len > KEY_BUFFER_SIZE - 0xff) {
|
||||
// don't ever let the buffer get too full or we risk putting incomplete keys into it
|
||||
tinput_flush(input);
|
||||
}
|
||||
rbuffer_write(input->key_buffer, buf, size);
|
||||
size_t to_copy = MIN(size, KEY_BUFFER_SIZE - input->key_buffer_len);
|
||||
memcpy(input->key_buffer + input->key_buffer_len, buf, to_copy);
|
||||
input->key_buffer_len += to_copy;
|
||||
}
|
||||
|
||||
/// Handle TERMKEY_KEYMOD_* modifiers, i.e. Shift, Alt and Ctrl.
|
||||
|
@ -17,6 +17,7 @@ typedef enum {
|
||||
kKeyEncodingXterm, ///< Xterm's modifyOtherKeys encoding (XTMODKEYS)
|
||||
} KeyEncoding;
|
||||
|
||||
#define KEY_BUFFER_SIZE 0xfff
|
||||
typedef struct {
|
||||
int in_fd;
|
||||
// Phases: -1=all 0=disabled 1=first-chunk 2=continue 3=last-chunk
|
||||
@ -34,8 +35,9 @@ typedef struct {
|
||||
uv_timer_t timer_handle;
|
||||
Loop *loop;
|
||||
RStream read_stream;
|
||||
RBuffer *key_buffer;
|
||||
TUIData *tui_data;
|
||||
char key_buffer[KEY_BUFFER_SIZE];
|
||||
size_t key_buffer_len;
|
||||
} TermInput;
|
||||
|
||||
typedef enum {
|
||||
|
Reference in New Issue
Block a user