mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 05:05:00 -07:00
feat(tui): support Super and Meta modifiers (#24357)
This commit is contained in:
parent
33e1a8cd70
commit
622ae2f53e
@ -229,6 +229,44 @@ static void tinput_enqueue(TermInput *input, char *buf, size_t size)
|
|||||||
rbuffer_write(input->key_buffer, buf, size);
|
rbuffer_write(input->key_buffer, buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle TERMKEY_KEYMOD_* modifiers, i.e. Shift, Alt and Ctrl.
|
||||||
|
///
|
||||||
|
/// @return The number of bytes written into "buf", excluding the final NUL.
|
||||||
|
static size_t handle_termkey_modifiers(TermKeyKey *key, char *buf, size_t buflen)
|
||||||
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
if (key->modifiers & TERMKEY_KEYMOD_SHIFT) { // Shift
|
||||||
|
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "S-");
|
||||||
|
}
|
||||||
|
if (key->modifiers & TERMKEY_KEYMOD_ALT) { // Alt
|
||||||
|
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "A-");
|
||||||
|
}
|
||||||
|
if (key->modifiers & TERMKEY_KEYMOD_CTRL) { // Ctrl
|
||||||
|
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "C-");
|
||||||
|
}
|
||||||
|
assert(len < buflen);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handle modifiers not handled by libtermkey.
|
||||||
|
/// Currently only Super ("D-") and Meta ("T-") are supported in Nvim.
|
||||||
|
///
|
||||||
|
/// @return The number of bytes written into "buf", excluding the final NUL.
|
||||||
|
static size_t handle_more_modifiers(TermKeyKey *key, char *buf, size_t buflen)
|
||||||
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
if (key->modifiers & 8) { // Super
|
||||||
|
len += (size_t)snprintf(buf + len, buflen - len, "D-");
|
||||||
|
}
|
||||||
|
if (key->modifiers & 32) { // Meta
|
||||||
|
len += (size_t)snprintf(buf + len, buflen - len, "T-");
|
||||||
|
}
|
||||||
|
assert(len < buflen);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_kitty_key_protocol(TermInput *input, TermKeyKey *key)
|
static void handle_kitty_key_protocol(TermInput *input, TermKeyKey *key)
|
||||||
{
|
{
|
||||||
const char *name = map_get(int, cstr_t)(&kitty_key_map, (int)key->code.codepoint);
|
const char *name = map_get(int, cstr_t)(&kitty_key_map, (int)key->code.codepoint);
|
||||||
@ -236,16 +274,10 @@ static void handle_kitty_key_protocol(TermInput *input, TermKeyKey *key)
|
|||||||
char buf[64];
|
char buf[64];
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
buf[len++] = '<';
|
buf[len++] = '<';
|
||||||
if (key->modifiers & TERMKEY_KEYMOD_SHIFT) {
|
len += handle_termkey_modifiers(key, buf + len, sizeof(buf) - len);
|
||||||
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "S-");
|
len += handle_more_modifiers(key, buf + len, sizeof(buf) - len);
|
||||||
}
|
|
||||||
if (key->modifiers & TERMKEY_KEYMOD_ALT) {
|
|
||||||
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "A-");
|
|
||||||
}
|
|
||||||
if (key->modifiers & TERMKEY_KEYMOD_CTRL) {
|
|
||||||
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "C-");
|
|
||||||
}
|
|
||||||
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "%s>", name);
|
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "%s>", name);
|
||||||
|
assert(len < sizeof(buf));
|
||||||
tinput_enqueue(input, buf, len);
|
tinput_enqueue(input, buf, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,6 +302,7 @@ static void forward_simple_utf8(TermInput *input, TermKeyKey *key)
|
|||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(len < sizeof(buf));
|
||||||
tinput_enqueue(input, buf, len);
|
tinput_enqueue(input, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +330,7 @@ static void forward_modified_utf8(TermInput *input, TermKeyKey *key)
|
|||||||
if ((key->modifiers & TERMKEY_KEYMOD_CTRL)
|
if ((key->modifiers & TERMKEY_KEYMOD_CTRL)
|
||||||
&& !(key->modifiers & TERMKEY_KEYMOD_SHIFT)
|
&& !(key->modifiers & TERMKEY_KEYMOD_SHIFT)
|
||||||
&& ASCII_ISUPPER(key->code.codepoint)) {
|
&& ASCII_ISUPPER(key->code.codepoint)) {
|
||||||
assert(len <= 62);
|
assert(len + 2 < sizeof(buf));
|
||||||
// Make room for the S-
|
// Make room for the S-
|
||||||
memmove(buf + 3, buf + 1, len - 1);
|
memmove(buf + 3, buf + 1, len - 1);
|
||||||
buf[1] = 'S';
|
buf[1] = 'S';
|
||||||
@ -306,6 +339,16 @@ static void forward_modified_utf8(TermInput *input, TermKeyKey *key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char more_buf[25];
|
||||||
|
size_t more_len = handle_more_modifiers(key, more_buf, sizeof(more_buf));
|
||||||
|
if (more_len > 0) {
|
||||||
|
assert(len + more_len < sizeof(buf));
|
||||||
|
memmove(buf + 1 + more_len, buf + 1, len - 1);
|
||||||
|
memcpy(buf + 1, more_buf, more_len);
|
||||||
|
len += more_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(len < sizeof(buf));
|
||||||
tinput_enqueue(input, buf, len);
|
tinput_enqueue(input, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,17 +386,9 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key)
|
|||||||
row--; col--; // Termkey uses 1-based coordinates
|
row--; col--; // Termkey uses 1-based coordinates
|
||||||
buf[len++] = '<';
|
buf[len++] = '<';
|
||||||
|
|
||||||
if (key->modifiers & TERMKEY_KEYMOD_SHIFT) {
|
len += handle_termkey_modifiers(key, buf + len, sizeof(buf) - len);
|
||||||
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "S-");
|
// Doesn't actually work because there are only 3 bits (0x1c) for modifiers.
|
||||||
}
|
// len += handle_more_modifiers(key, buf + len, sizeof(buf) - len);
|
||||||
|
|
||||||
if (key->modifiers & TERMKEY_KEYMOD_CTRL) {
|
|
||||||
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "C-");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key->modifiers & TERMKEY_KEYMOD_ALT) {
|
|
||||||
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "A-");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (button == 1) {
|
if (button == 1) {
|
||||||
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Left");
|
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Left");
|
||||||
@ -390,6 +425,7 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "><%d,%d>", col, row);
|
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "><%d,%d>", col, row);
|
||||||
|
assert(len < sizeof(buf));
|
||||||
tinput_enqueue(input, buf, len);
|
tinput_enqueue(input, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,6 +697,28 @@ describe('TUI', function()
|
|||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('supports Super and Meta modifiers', function()
|
||||||
|
feed_data('i')
|
||||||
|
feed_data('\022\027[106;9u') -- Super + j
|
||||||
|
feed_data('\022\027[107;33u') -- Meta + k
|
||||||
|
feed_data('\022\027[13;41u') -- Super + Meta + Enter
|
||||||
|
feed_data('\022\027[127;48u') -- Shift + Alt + Ctrl + Super + Meta + Backspace
|
||||||
|
feed('\n')
|
||||||
|
feed_data('\022\027[57376;9u') -- Super + F13
|
||||||
|
feed_data('\022\027[57377;33u') -- Meta + F14
|
||||||
|
feed_data('\022\027[57378;41u') -- Super + Meta + F15
|
||||||
|
feed_data('\022\027[57379;48u') -- Shift + Alt + Ctrl + Super + Meta + F16
|
||||||
|
screen:expect([[
|
||||||
|
<D-j><T-k><T-D-CR><M-T-C-S-D-BS> |
|
||||||
|
<D-F13><T-F14><T-D-F15><M-T-C-S-D-F16>{1: } |
|
||||||
|
{4:~ }|
|
||||||
|
{4:~ }|
|
||||||
|
{5:[No Name] [+] }|
|
||||||
|
{3:-- INSERT --} |
|
||||||
|
{3:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
it('mouse events work with right-click menu', function()
|
it('mouse events work with right-click menu', function()
|
||||||
child_session:request('nvim_exec', [[
|
child_session:request('nvim_exec', [[
|
||||||
call setline(1, 'popup menu test')
|
call setline(1, 'popup menu test')
|
||||||
|
Loading…
Reference in New Issue
Block a user