Merge pull request #12030 from erw7/fix-tui-access-global-var

TUI: do not use nvim_get_option in tui thread
This commit is contained in:
Björn Linse 2020-03-22 19:43:21 +01:00 committed by GitHub
commit 9847306b95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 19 deletions

View File

@ -2587,6 +2587,7 @@ return {
type='bool', scope={'global'},
vi_def=true,
vim=true,
redraw={'ui_option'},
varname='p_ttimeout',
defaults={if_true={vi=true}}
},
@ -2594,6 +2595,7 @@ return {
full_name='ttimeoutlen', abbreviation='ttm',
type='number', scope={'global'},
vi_def=true,
redraw={'ui_option'},
varname='p_ttm',
defaults={if_true={vi=50}}
},

View File

@ -31,6 +31,10 @@ void tinput_init(TermInput *input, Loop *loop)
input->paste = 0;
input->in_fd = STDIN_FILENO;
input->waiting_for_bg_response = 0;
// The main thread is waiting for the UI thread to call CONTINUE, so it can
// safely access global variables.
input->ttimeout = (bool)p_ttimeout;
input->ttimeoutlen = p_ttm;
input->key_buffer = rbuffer_new(KEY_BUFFER_SIZE);
uv_mutex_init(&input->key_buffer_mutex);
uv_cond_init(&input->key_buffer_cond);
@ -285,21 +289,6 @@ static TermKeyResult tk_getkey(TermKey *tk, TermKeyKey *key, bool force)
static void tinput_timer_cb(TimeWatcher *watcher, void *data);
static int get_key_code_timeout(void)
{
Integer ms = -1;
// Check 'ttimeout' to determine if we should send ESC after 'ttimeoutlen'.
Error err = ERROR_INIT;
if (nvim_get_option(cstr_as_string("ttimeout"), &err).data.boolean) {
Object rv = nvim_get_option(cstr_as_string("ttimeoutlen"), &err);
if (!ERROR_SET(&err)) {
ms = rv.data.integer;
}
}
api_clear_error(&err);
return (int)ms;
}
static void tk_getkeys(TermInput *input, bool force)
{
TermKeyKey key;
@ -324,12 +313,11 @@ static void tk_getkeys(TermInput *input, bool force)
// yet contain all the bytes required. `key` structure indicates what
// termkey_getkey_force() would return.
int ms = get_key_code_timeout();
if (ms > 0) {
if (input->ttimeout && input->ttimeoutlen >= 0) {
// Stop the current timer if already running
time_watcher_stop(&input->timer_handle);
time_watcher_start(&input->timer_handle, tinput_timer_cb, (uint32_t)ms, 0);
time_watcher_start(&input->timer_handle, tinput_timer_cb,
(uint64_t)input->ttimeoutlen, 0);
} else {
tk_getkeys(input, true);
}

View File

@ -12,7 +12,9 @@ typedef struct term_input {
// Phases: -1=all 0=disabled 1=first-chunk 2=continue 3=last-chunk
int8_t paste;
bool waiting;
bool ttimeout;
int8_t waiting_for_bg_response;
long ttimeoutlen;
TermKey *tk;
#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
TermKey_Terminfo_Getstr_Hook *tk_ti_hook_fn; ///< libtermkey terminfo hook

View File

@ -1292,6 +1292,12 @@ static void tui_option_set(UI *ui, String name, Object value)
data->print_attr_id = -1;
invalidate(ui, 0, data->grid.height, 0, data->grid.width);
}
if (strequal(name.data, "ttimeout")) {
data->input.ttimeout = value.data.boolean;
}
if (strequal(name.data, "ttimeoutlen")) {
data->input.ttimeoutlen = (long)value.data.integer;
}
}
static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol,

View File

@ -20,6 +20,8 @@ describe('UI receives option updates', function()
pumblend=0,
showtabline=1,
termguicolors=false,
ttimeout=true,
ttimeoutlen=50,
ext_cmdline=false,
ext_popupmenu=false,
ext_tabline=false,
@ -108,6 +110,18 @@ describe('UI receives option updates', function()
eq(expected, screen.options)
end)
command("set nottimeout")
expected.ttimeout = false
screen:expect(function()
eq(expected, screen.options)
end)
command("set ttimeoutlen=100")
expected.ttimeoutlen = 100
screen:expect(function()
eq(expected, screen.options)
end)
command("set all&")
screen:expect(function()
eq(defaults, screen.options)