mirror of
https://github.com/neovim/neovim.git
synced 2024-12-29 14:41:06 -07:00
Merge #7221 from justinmk/ev-focusgained
tui: schedule event instead of <FocusGained> pseudokey
This commit is contained in:
commit
51808a244e
@ -215,6 +215,7 @@ static void ui_set_option(UI *ui, String name, Object value, Error *error)
|
|||||||
#undef UI_EXT_OPTION
|
#undef UI_EXT_OPTION
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pushes data into UI.UIData, to be consumed later by remote_ui_flush().
|
||||||
static void push_call(UI *ui, char *name, Array args)
|
static void push_call(UI *ui, char *name, Array args)
|
||||||
{
|
{
|
||||||
Array call = ARRAY_DICT_INIT;
|
Array call = ARRAY_DICT_INIT;
|
||||||
|
@ -255,12 +255,11 @@ free_vim_args:
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute lua code. Parameters might be passed, they are available inside
|
/// Execute lua code. Parameters (if any) are available as `...` inside the
|
||||||
/// the chunk as `...`. The chunk can return a value.
|
/// chunk. The chunk can return a value.
|
||||||
///
|
///
|
||||||
/// To evaluate an expression, it must be prefixed with "return ". For
|
/// Only statements are executed. To evaluate an expression, prefix it
|
||||||
/// instance, to call a lua function with arguments sent in and get its
|
/// with `return`: return my_function(...)
|
||||||
/// return value back, use the code "return my_function(...)".
|
|
||||||
///
|
///
|
||||||
/// @param code lua code to execute
|
/// @param code lua code to execute
|
||||||
/// @param args Arguments to the code
|
/// @param args Arguments to the code
|
||||||
@ -423,29 +422,18 @@ void nvim_del_var(String name, Error *err)
|
|||||||
dict_set_var(&globvardict, name, NIL, true, false, err);
|
dict_set_var(&globvardict, name, NIL, true, false, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a global variable
|
|
||||||
///
|
|
||||||
/// @deprecated
|
/// @deprecated
|
||||||
///
|
/// @see nvim_set_var
|
||||||
/// @param name Variable name
|
|
||||||
/// @param value Variable value
|
|
||||||
/// @param[out] err Error details, if any
|
|
||||||
/// @return Old value or nil if there was no previous value.
|
/// @return Old value or nil if there was no previous value.
|
||||||
///
|
/// @warning May return nil if there was no previous value
|
||||||
/// @warning It may return nil if there was no previous value
|
/// OR if previous value was `v:null`.
|
||||||
/// or if previous value was `v:null`.
|
|
||||||
Object vim_set_var(String name, Object value, Error *err)
|
Object vim_set_var(String name, Object value, Error *err)
|
||||||
{
|
{
|
||||||
return dict_set_var(&globvardict, name, value, false, true, err);
|
return dict_set_var(&globvardict, name, value, false, true, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a global variable
|
|
||||||
///
|
|
||||||
/// @deprecated
|
/// @deprecated
|
||||||
///
|
/// @see nvim_del_var
|
||||||
/// @param name Variable name
|
|
||||||
/// @param[out] err Error details, if any
|
|
||||||
/// @return Old value
|
|
||||||
Object vim_del_var(String name, Error *err)
|
Object vim_del_var(String name, Error *err)
|
||||||
{
|
{
|
||||||
return dict_set_var(&globvardict, name, NIL, true, true, err);
|
return dict_set_var(&globvardict, name, NIL, true, true, err);
|
||||||
|
41
src/nvim/aucmd.c
Normal file
41
src/nvim/aucmd.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
|
#include "nvim/os/os.h"
|
||||||
|
#include "nvim/fileio.h"
|
||||||
|
#include "nvim/vim.h"
|
||||||
|
#include "nvim/main.h"
|
||||||
|
#include "nvim/ui.h"
|
||||||
|
|
||||||
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
# include "aucmd.c.generated.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void focusgained_event(void **argv)
|
||||||
|
{
|
||||||
|
bool *gainedp = argv[0];
|
||||||
|
do_autocmd_focusgained(*gainedp);
|
||||||
|
xfree(gainedp);
|
||||||
|
}
|
||||||
|
void aucmd_schedule_focusgained(bool gained)
|
||||||
|
{
|
||||||
|
bool *gainedp = xmalloc(sizeof(*gainedp));
|
||||||
|
*gainedp = gained;
|
||||||
|
loop_schedule_deferred(&main_loop,
|
||||||
|
event_create(focusgained_event, 1, gainedp));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_autocmd_focusgained(bool gained)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
static bool recursive = false;
|
||||||
|
|
||||||
|
if (recursive) {
|
||||||
|
return; // disallow recursion
|
||||||
|
}
|
||||||
|
recursive = true;
|
||||||
|
apply_autocmds((gained ? EVENT_FOCUSGAINED : EVENT_FOCUSLOST),
|
||||||
|
NULL, NULL, false, curbuf);
|
||||||
|
recursive = false;
|
||||||
|
}
|
||||||
|
|
9
src/nvim/aucmd.h
Normal file
9
src/nvim/aucmd.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef NVIM_AUCMD_H
|
||||||
|
#define NVIM_AUCMD_H
|
||||||
|
|
||||||
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
# include "aucmd.h.generated.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // NVIM_AUCMD_H
|
||||||
|
|
@ -974,14 +974,6 @@ static int insert_handle_key(InsertState *s)
|
|||||||
multiqueue_process_events(main_loop.events);
|
multiqueue_process_events(main_loop.events);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case K_FOCUSGAINED: // Neovim has been given focus
|
|
||||||
apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case K_FOCUSLOST: // Neovim has lost focus
|
|
||||||
apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case K_HOME: // <Home>
|
case K_HOME: // <Home>
|
||||||
case K_KHOME:
|
case K_KHOME:
|
||||||
case K_S_HOME:
|
case K_S_HOME:
|
||||||
@ -3167,8 +3159,7 @@ static bool ins_compl_prep(int c)
|
|||||||
|
|
||||||
/* Ignore end of Select mode mapping and mouse scroll buttons. */
|
/* Ignore end of Select mode mapping and mouse scroll buttons. */
|
||||||
if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
|
if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
|
||||||
|| c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT
|
|| c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT) {
|
||||||
|| c == K_FOCUSGAINED || c == K_FOCUSLOST) {
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,14 @@ void loop_poll_events(Loop *loop, int ms)
|
|||||||
multiqueue_process_events(loop->fast_events);
|
multiqueue_process_events(loop->fast_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule an event from another thread
|
/// Schedules an event from another thread.
|
||||||
|
///
|
||||||
|
/// @note Event is queued into `fast_events`, which is processed outside of the
|
||||||
|
/// primary `events` queue by loop_poll_events(). For `main_loop`, that
|
||||||
|
/// means `fast_events` is NOT processed in an "editor mode"
|
||||||
|
/// (VimState.execute), so redraw and other side-effects are likely to be
|
||||||
|
/// skipped.
|
||||||
|
/// @see loop_schedule_deferred
|
||||||
void loop_schedule(Loop *loop, Event event)
|
void loop_schedule(Loop *loop, Event event)
|
||||||
{
|
{
|
||||||
uv_mutex_lock(&loop->mutex);
|
uv_mutex_lock(&loop->mutex);
|
||||||
@ -68,6 +75,24 @@ void loop_schedule(Loop *loop, Event event)
|
|||||||
uv_mutex_unlock(&loop->mutex);
|
uv_mutex_unlock(&loop->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Schedules an event from another thread. Unlike loop_schedule(), the event
|
||||||
|
/// is forwarded to `Loop.events`, instead of being processed immediately.
|
||||||
|
///
|
||||||
|
/// @see loop_schedule
|
||||||
|
void loop_schedule_deferred(Loop *loop, Event event)
|
||||||
|
{
|
||||||
|
Event *eventp = xmalloc(sizeof(*eventp));
|
||||||
|
*eventp = event;
|
||||||
|
loop_schedule(loop, event_create(loop_deferred_event, 2, loop, eventp));
|
||||||
|
}
|
||||||
|
static void loop_deferred_event(void **argv)
|
||||||
|
{
|
||||||
|
Loop *loop = argv[0];
|
||||||
|
Event *eventp = argv[1];
|
||||||
|
multiqueue_put_event(loop->events, *eventp);
|
||||||
|
xfree(eventp);
|
||||||
|
}
|
||||||
|
|
||||||
void loop_on_put(MultiQueue *queue, void *data)
|
void loop_on_put(MultiQueue *queue, void *data)
|
||||||
{
|
{
|
||||||
Loop *loop = data;
|
Loop *loop = data;
|
||||||
|
@ -16,10 +16,28 @@ KLIST_INIT(WatcherPtr, WatcherPtr, _noop)
|
|||||||
|
|
||||||
typedef struct loop {
|
typedef struct loop {
|
||||||
uv_loop_t uv;
|
uv_loop_t uv;
|
||||||
MultiQueue *events, *fast_events, *thread_events;
|
MultiQueue *events;
|
||||||
|
MultiQueue *thread_events;
|
||||||
|
// Immediate events:
|
||||||
|
// "Events that should be processed after exiting uv_run() (to avoid
|
||||||
|
// recursion), but before returning from loop_poll_events()."
|
||||||
|
// 502aee690c980fcb3cfcb3f211dcfad06103db46
|
||||||
|
// Practical consequence: these events are processed by
|
||||||
|
// state_enter()..os_inchar()
|
||||||
|
// whereas "regular" (main_loop.events) events are processed by
|
||||||
|
// state_enter()..VimState.execute()
|
||||||
|
// But state_enter()..os_inchar() can be "too early" if you want the event
|
||||||
|
// to trigger UI updates and other user-activity-related side-effects.
|
||||||
|
MultiQueue *fast_events;
|
||||||
|
|
||||||
|
// used by process/job-control subsystem
|
||||||
klist_t(WatcherPtr) *children;
|
klist_t(WatcherPtr) *children;
|
||||||
uv_signal_t children_watcher;
|
uv_signal_t children_watcher;
|
||||||
uv_timer_t children_kill_timer, poll_timer;
|
uv_timer_t children_kill_timer;
|
||||||
|
|
||||||
|
// generic timer, used by loop_poll_events()
|
||||||
|
uv_timer_t poll_timer;
|
||||||
|
|
||||||
size_t children_stop_requests;
|
size_t children_stop_requests;
|
||||||
uv_async_t async;
|
uv_async_t async;
|
||||||
uv_mutex_t mutex;
|
uv_mutex_t mutex;
|
||||||
|
@ -1620,14 +1620,6 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
}
|
}
|
||||||
return command_line_not_changed(s);
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
case K_FOCUSGAINED: // Neovim has been given focus
|
|
||||||
apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
|
|
||||||
case K_FOCUSLOST: // Neovim has lost focus
|
|
||||||
apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Normal character with no special meaning. Just set mod_mask
|
// Normal character with no special meaning. Just set mod_mask
|
||||||
// to 0x0 so that typing Shift-Space in the GUI doesn't enter
|
// to 0x0 so that typing Shift-Space in the GUI doesn't enter
|
||||||
|
@ -140,155 +140,153 @@ static char_u modifier_keys_table[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct key_name_entry {
|
static struct key_name_entry {
|
||||||
int key; /* Special key code or ascii value */
|
int key; // Special key code or ascii value
|
||||||
char_u *name; /* Name of key */
|
char *name; // Name of key
|
||||||
} key_names_table[] =
|
} key_names_table[] =
|
||||||
{
|
{
|
||||||
{' ', (char_u *)"Space"},
|
{ ' ', "Space" },
|
||||||
{TAB, (char_u *)"Tab"},
|
{ TAB, "Tab" },
|
||||||
{K_TAB, (char_u *)"Tab"},
|
{ K_TAB, "Tab" },
|
||||||
{NL, (char_u *)"NL"},
|
{ NL, "NL" },
|
||||||
{NL, (char_u *)"NewLine"}, /* Alternative name */
|
{ NL, "NewLine" }, // Alternative name
|
||||||
{NL, (char_u *)"LineFeed"}, /* Alternative name */
|
{ NL, "LineFeed" }, // Alternative name
|
||||||
{NL, (char_u *)"LF"}, /* Alternative name */
|
{ NL, "LF" }, // Alternative name
|
||||||
{CAR, (char_u *)"CR"},
|
{ CAR, "CR" },
|
||||||
{CAR, (char_u *)"Return"}, /* Alternative name */
|
{ CAR, "Return" }, // Alternative name
|
||||||
{CAR, (char_u *)"Enter"}, /* Alternative name */
|
{ CAR, "Enter" }, // Alternative name
|
||||||
{K_BS, (char_u *)"BS"},
|
{ K_BS, "BS" },
|
||||||
{K_BS, (char_u *)"BackSpace"}, /* Alternative name */
|
{ K_BS, "BackSpace" }, // Alternative name
|
||||||
{ESC, (char_u *)"Esc"},
|
{ ESC, "Esc" },
|
||||||
{CSI, (char_u *)"CSI"},
|
{ CSI, "CSI" },
|
||||||
{K_CSI, (char_u *)"xCSI"},
|
{ K_CSI, "xCSI" },
|
||||||
{'|', (char_u *)"Bar"},
|
{ '|', "Bar" },
|
||||||
{'\\', (char_u *)"Bslash"},
|
{ '\\', "Bslash" },
|
||||||
{K_DEL, (char_u *)"Del"},
|
{ K_DEL, "Del" },
|
||||||
{K_DEL, (char_u *)"Delete"}, /* Alternative name */
|
{ K_DEL, "Delete" }, // Alternative name
|
||||||
{K_KDEL, (char_u *)"kDel"},
|
{ K_KDEL, "kDel" },
|
||||||
{K_UP, (char_u *)"Up"},
|
{ K_UP, "Up" },
|
||||||
{K_DOWN, (char_u *)"Down"},
|
{ K_DOWN, "Down" },
|
||||||
{K_LEFT, (char_u *)"Left"},
|
{ K_LEFT, "Left" },
|
||||||
{K_RIGHT, (char_u *)"Right"},
|
{ K_RIGHT, "Right" },
|
||||||
{K_XUP, (char_u *)"xUp"},
|
{ K_XUP, "xUp" },
|
||||||
{K_XDOWN, (char_u *)"xDown"},
|
{ K_XDOWN, "xDown" },
|
||||||
{K_XLEFT, (char_u *)"xLeft"},
|
{ K_XLEFT, "xLeft" },
|
||||||
{K_XRIGHT, (char_u *)"xRight"},
|
{ K_XRIGHT, "xRight" },
|
||||||
|
|
||||||
{K_F1, (char_u *)"F1"},
|
{ K_F1, "F1" },
|
||||||
{K_F2, (char_u *)"F2"},
|
{ K_F2, "F2" },
|
||||||
{K_F3, (char_u *)"F3"},
|
{ K_F3, "F3" },
|
||||||
{K_F4, (char_u *)"F4"},
|
{ K_F4, "F4" },
|
||||||
{K_F5, (char_u *)"F5"},
|
{ K_F5, "F5" },
|
||||||
{K_F6, (char_u *)"F6"},
|
{ K_F6, "F6" },
|
||||||
{K_F7, (char_u *)"F7"},
|
{ K_F7, "F7" },
|
||||||
{K_F8, (char_u *)"F8"},
|
{ K_F8, "F8" },
|
||||||
{K_F9, (char_u *)"F9"},
|
{ K_F9, "F9" },
|
||||||
{K_F10, (char_u *)"F10"},
|
{ K_F10, "F10" },
|
||||||
|
|
||||||
{K_F11, (char_u *)"F11"},
|
{ K_F11, "F11" },
|
||||||
{K_F12, (char_u *)"F12"},
|
{ K_F12, "F12" },
|
||||||
{K_F13, (char_u *)"F13"},
|
{ K_F13, "F13" },
|
||||||
{K_F14, (char_u *)"F14"},
|
{ K_F14, "F14" },
|
||||||
{K_F15, (char_u *)"F15"},
|
{ K_F15, "F15" },
|
||||||
{K_F16, (char_u *)"F16"},
|
{ K_F16, "F16" },
|
||||||
{K_F17, (char_u *)"F17"},
|
{ K_F17, "F17" },
|
||||||
{K_F18, (char_u *)"F18"},
|
{ K_F18, "F18" },
|
||||||
{K_F19, (char_u *)"F19"},
|
{ K_F19, "F19" },
|
||||||
{K_F20, (char_u *)"F20"},
|
{ K_F20, "F20" },
|
||||||
|
|
||||||
{K_F21, (char_u *)"F21"},
|
{ K_F21, "F21" },
|
||||||
{K_F22, (char_u *)"F22"},
|
{ K_F22, "F22" },
|
||||||
{K_F23, (char_u *)"F23"},
|
{ K_F23, "F23" },
|
||||||
{K_F24, (char_u *)"F24"},
|
{ K_F24, "F24" },
|
||||||
{K_F25, (char_u *)"F25"},
|
{ K_F25, "F25" },
|
||||||
{K_F26, (char_u *)"F26"},
|
{ K_F26, "F26" },
|
||||||
{K_F27, (char_u *)"F27"},
|
{ K_F27, "F27" },
|
||||||
{K_F28, (char_u *)"F28"},
|
{ K_F28, "F28" },
|
||||||
{K_F29, (char_u *)"F29"},
|
{ K_F29, "F29" },
|
||||||
{K_F30, (char_u *)"F30"},
|
{ K_F30, "F30" },
|
||||||
|
|
||||||
{K_F31, (char_u *)"F31"},
|
{ K_F31, "F31" },
|
||||||
{K_F32, (char_u *)"F32"},
|
{ K_F32, "F32" },
|
||||||
{K_F33, (char_u *)"F33"},
|
{ K_F33, "F33" },
|
||||||
{K_F34, (char_u *)"F34"},
|
{ K_F34, "F34" },
|
||||||
{K_F35, (char_u *)"F35"},
|
{ K_F35, "F35" },
|
||||||
{K_F36, (char_u *)"F36"},
|
{ K_F36, "F36" },
|
||||||
{K_F37, (char_u *)"F37"},
|
{ K_F37, "F37" },
|
||||||
|
|
||||||
{K_XF1, (char_u *)"xF1"},
|
{ K_XF1, "xF1" },
|
||||||
{K_XF2, (char_u *)"xF2"},
|
{ K_XF2, "xF2" },
|
||||||
{K_XF3, (char_u *)"xF3"},
|
{ K_XF3, "xF3" },
|
||||||
{K_XF4, (char_u *)"xF4"},
|
{ K_XF4, "xF4" },
|
||||||
|
|
||||||
{K_HELP, (char_u *)"Help"},
|
{ K_HELP, "Help" },
|
||||||
{K_UNDO, (char_u *)"Undo"},
|
{ K_UNDO, "Undo" },
|
||||||
{K_INS, (char_u *)"Insert"},
|
{ K_INS, "Insert" },
|
||||||
{K_INS, (char_u *)"Ins"}, /* Alternative name */
|
{ K_INS, "Ins" }, // Alternative name
|
||||||
{K_KINS, (char_u *)"kInsert"},
|
{ K_KINS, "kInsert" },
|
||||||
{K_HOME, (char_u *)"Home"},
|
{ K_HOME, "Home" },
|
||||||
{K_KHOME, (char_u *)"kHome"},
|
{ K_KHOME, "kHome" },
|
||||||
{K_XHOME, (char_u *)"xHome"},
|
{ K_XHOME, "xHome" },
|
||||||
{K_ZHOME, (char_u *)"zHome"},
|
{ K_ZHOME, "zHome" },
|
||||||
{K_END, (char_u *)"End"},
|
{ K_END, "End" },
|
||||||
{K_KEND, (char_u *)"kEnd"},
|
{ K_KEND, "kEnd" },
|
||||||
{K_XEND, (char_u *)"xEnd"},
|
{ K_XEND, "xEnd" },
|
||||||
{K_ZEND, (char_u *)"zEnd"},
|
{ K_ZEND, "zEnd" },
|
||||||
{K_PAGEUP, (char_u *)"PageUp"},
|
{ K_PAGEUP, "PageUp" },
|
||||||
{K_PAGEDOWN, (char_u *)"PageDown"},
|
{ K_PAGEDOWN, "PageDown" },
|
||||||
{K_KPAGEUP, (char_u *)"kPageUp"},
|
{ K_KPAGEUP, "kPageUp" },
|
||||||
{K_KPAGEDOWN, (char_u *)"kPageDown"},
|
{ K_KPAGEDOWN, "kPageDown" },
|
||||||
|
|
||||||
{K_KPLUS, (char_u *)"kPlus"},
|
{ K_KPLUS, "kPlus" },
|
||||||
{K_KMINUS, (char_u *)"kMinus"},
|
{ K_KMINUS, "kMinus" },
|
||||||
{K_KDIVIDE, (char_u *)"kDivide"},
|
{ K_KDIVIDE, "kDivide" },
|
||||||
{K_KMULTIPLY, (char_u *)"kMultiply"},
|
{ K_KMULTIPLY, "kMultiply" },
|
||||||
{K_KENTER, (char_u *)"kEnter"},
|
{ K_KENTER, "kEnter" },
|
||||||
{K_KPOINT, (char_u *)"kPoint"},
|
{ K_KPOINT, "kPoint" },
|
||||||
|
|
||||||
{K_K0, (char_u *)"k0"},
|
{ K_K0, "k0" },
|
||||||
{K_K1, (char_u *)"k1"},
|
{ K_K1, "k1" },
|
||||||
{K_K2, (char_u *)"k2"},
|
{ K_K2, "k2" },
|
||||||
{K_K3, (char_u *)"k3"},
|
{ K_K3, "k3" },
|
||||||
{K_K4, (char_u *)"k4"},
|
{ K_K4, "k4" },
|
||||||
{K_K5, (char_u *)"k5"},
|
{ K_K5, "k5" },
|
||||||
{K_K6, (char_u *)"k6"},
|
{ K_K6, "k6" },
|
||||||
{K_K7, (char_u *)"k7"},
|
{ K_K7, "k7" },
|
||||||
{K_K8, (char_u *)"k8"},
|
{ K_K8, "k8" },
|
||||||
{K_K9, (char_u *)"k9"},
|
{ K_K9, "k9" },
|
||||||
|
|
||||||
{'<', (char_u *)"lt"},
|
{ '<', "lt" },
|
||||||
|
|
||||||
{K_MOUSE, (char_u *)"Mouse"},
|
{ K_MOUSE, "Mouse" },
|
||||||
{K_LEFTMOUSE, (char_u *)"LeftMouse"},
|
{ K_LEFTMOUSE, "LeftMouse" },
|
||||||
{K_LEFTMOUSE_NM, (char_u *)"LeftMouseNM"},
|
{ K_LEFTMOUSE_NM, "LeftMouseNM" },
|
||||||
{K_LEFTDRAG, (char_u *)"LeftDrag"},
|
{ K_LEFTDRAG, "LeftDrag" },
|
||||||
{K_LEFTRELEASE, (char_u *)"LeftRelease"},
|
{ K_LEFTRELEASE, "LeftRelease" },
|
||||||
{K_LEFTRELEASE_NM, (char_u *)"LeftReleaseNM"},
|
{ K_LEFTRELEASE_NM, "LeftReleaseNM" },
|
||||||
{K_MIDDLEMOUSE, (char_u *)"MiddleMouse"},
|
{ K_MIDDLEMOUSE, "MiddleMouse" },
|
||||||
{K_MIDDLEDRAG, (char_u *)"MiddleDrag"},
|
{ K_MIDDLEDRAG, "MiddleDrag" },
|
||||||
{K_MIDDLERELEASE, (char_u *)"MiddleRelease"},
|
{ K_MIDDLERELEASE, "MiddleRelease" },
|
||||||
{K_RIGHTMOUSE, (char_u *)"RightMouse"},
|
{ K_RIGHTMOUSE, "RightMouse" },
|
||||||
{K_RIGHTDRAG, (char_u *)"RightDrag"},
|
{ K_RIGHTDRAG, "RightDrag" },
|
||||||
{K_RIGHTRELEASE, (char_u *)"RightRelease"},
|
{ K_RIGHTRELEASE, "RightRelease" },
|
||||||
{K_MOUSEDOWN, (char_u *)"ScrollWheelUp"},
|
{ K_MOUSEDOWN, "ScrollWheelUp" },
|
||||||
{K_MOUSEUP, (char_u *)"ScrollWheelDown"},
|
{ K_MOUSEUP, "ScrollWheelDown" },
|
||||||
{K_MOUSELEFT, (char_u *)"ScrollWheelRight"},
|
{ K_MOUSELEFT, "ScrollWheelRight" },
|
||||||
{K_MOUSERIGHT, (char_u *)"ScrollWheelLeft"},
|
{ K_MOUSERIGHT, "ScrollWheelLeft" },
|
||||||
{K_MOUSEDOWN, (char_u *)"MouseDown"}, /* OBSOLETE: Use */
|
{ K_MOUSEDOWN, "MouseDown" }, // OBSOLETE: Use
|
||||||
{K_MOUSEUP, (char_u *)"MouseUp"}, /* ScrollWheelXXX instead */
|
{ K_MOUSEUP, "MouseUp" }, // ScrollWheelXXX instead
|
||||||
{K_X1MOUSE, (char_u *)"X1Mouse"},
|
{ K_X1MOUSE, "X1Mouse" },
|
||||||
{K_X1DRAG, (char_u *)"X1Drag"},
|
{ K_X1DRAG, "X1Drag" },
|
||||||
{K_X1RELEASE, (char_u *)"X1Release"},
|
{ K_X1RELEASE, "X1Release" },
|
||||||
{K_X2MOUSE, (char_u *)"X2Mouse"},
|
{ K_X2MOUSE, "X2Mouse" },
|
||||||
{K_X2DRAG, (char_u *)"X2Drag"},
|
{ K_X2DRAG, "X2Drag" },
|
||||||
{K_X2RELEASE, (char_u *)"X2Release"},
|
{ K_X2RELEASE, "X2Release" },
|
||||||
{K_DROP, (char_u *)"Drop"},
|
{ K_DROP, "Drop" },
|
||||||
{K_ZERO, (char_u *)"Nul"},
|
{ K_ZERO, "Nul" },
|
||||||
{K_SNR, (char_u *)"SNR"},
|
{ K_SNR, "SNR" },
|
||||||
{K_PLUG, (char_u *)"Plug"},
|
{ K_PLUG, "Plug" },
|
||||||
{K_PASTE, (char_u *)"Paste"},
|
{ K_PASTE, "Paste" },
|
||||||
{K_FOCUSGAINED, (char_u *)"FocusGained"},
|
{ 0, NULL }
|
||||||
{K_FOCUSLOST, (char_u *)"FocusLost"},
|
|
||||||
{0, NULL}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mousetable {
|
static struct mousetable {
|
||||||
@ -721,7 +719,7 @@ int find_special_key_in_table(int c)
|
|||||||
*/
|
*/
|
||||||
int get_special_key_code(const char_u *name)
|
int get_special_key_code(const char_u *name)
|
||||||
{
|
{
|
||||||
char_u *table_name;
|
char *table_name;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
for (i = 0; key_names_table[i].name != NULL; i++) {
|
for (i = 0; key_names_table[i].name != NULL; i++) {
|
||||||
|
@ -428,8 +428,6 @@ enum key_extra {
|
|||||||
#define K_CMDWIN TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
|
#define K_CMDWIN TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
|
||||||
|
|
||||||
#define K_DROP TERMCAP2KEY(KS_EXTRA, KE_DROP)
|
#define K_DROP TERMCAP2KEY(KS_EXTRA, KE_DROP)
|
||||||
#define K_FOCUSGAINED TERMCAP2KEY(KS_EXTRA, KE_FOCUSGAINED)
|
|
||||||
#define K_FOCUSLOST TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST)
|
|
||||||
|
|
||||||
#define K_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT)
|
#define K_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT)
|
||||||
#define K_PASTE TERMCAP2KEY(KS_EXTRA, KE_PASTE)
|
#define K_PASTE TERMCAP2KEY(KS_EXTRA, KE_PASTE)
|
||||||
|
@ -95,8 +95,12 @@ void log_unlock(void)
|
|||||||
uv_mutex_unlock(&mutex);
|
uv_mutex_unlock(&mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool do_log(int log_level, const char *func_name, int line_num, bool eol,
|
/// @param context description of a shared context or subsystem
|
||||||
const char* fmt, ...) FUNC_ATTR_UNUSED
|
/// @param func_name function name, or NULL
|
||||||
|
/// @param line_num source line number, or -1
|
||||||
|
bool do_log(int log_level, const char *context, const char *func_name,
|
||||||
|
int line_num, bool eol, const char *fmt, ...)
|
||||||
|
FUNC_ATTR_UNUSED
|
||||||
{
|
{
|
||||||
if (log_level < MIN_LOG_LEVEL) {
|
if (log_level < MIN_LOG_LEVEL) {
|
||||||
return false;
|
return false;
|
||||||
@ -112,8 +116,8 @@ bool do_log(int log_level, const char *func_name, int line_num, bool eol,
|
|||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
ret = v_do_log_to_file(log_file, log_level, func_name, line_num, eol,
|
ret = v_do_log_to_file(log_file, log_level, context, func_name, line_num,
|
||||||
fmt, args);
|
eol, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
if (log_file != stderr && log_file != stdout) {
|
if (log_file != stderr && log_file != stdout) {
|
||||||
@ -151,7 +155,7 @@ FILE *open_log_file(void)
|
|||||||
static bool opening_log_file = false;
|
static bool opening_log_file = false;
|
||||||
// check if it's a recursive call
|
// check if it's a recursive call
|
||||||
if (opening_log_file) {
|
if (opening_log_file) {
|
||||||
do_log_to_file(stderr, ERROR_LOG_LEVEL, __func__, __LINE__, true,
|
do_log_to_file(stderr, ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true,
|
||||||
"Cannot LOG() recursively.");
|
"Cannot LOG() recursively.");
|
||||||
return stderr;
|
return stderr;
|
||||||
}
|
}
|
||||||
@ -171,7 +175,7 @@ FILE *open_log_file(void)
|
|||||||
// - LOG() is called before early_init()
|
// - LOG() is called before early_init()
|
||||||
// - Directory does not exist
|
// - Directory does not exist
|
||||||
// - File is not writable
|
// - File is not writable
|
||||||
do_log_to_file(stderr, ERROR_LOG_LEVEL, __func__, __LINE__, true,
|
do_log_to_file(stderr, ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true,
|
||||||
"Logging to stderr, failed to open $" LOG_FILE_ENV ": %s",
|
"Logging to stderr, failed to open $" LOG_FILE_ENV ": %s",
|
||||||
log_file_path);
|
log_file_path);
|
||||||
return stderr;
|
return stderr;
|
||||||
@ -201,7 +205,7 @@ void log_callstack_to_file(FILE *log_file, const char *const func_name,
|
|||||||
// Now we have a command string like:
|
// Now we have a command string like:
|
||||||
// addr2line -e /path/to/exe -f -p 0x123 0x456 ...
|
// addr2line -e /path/to/exe -f -p 0x123 0x456 ...
|
||||||
|
|
||||||
do_log_to_file(log_file, DEBUG_LOG_LEVEL, func_name, line_num, true,
|
do_log_to_file(log_file, DEBUG_LOG_LEVEL, NULL, func_name, line_num, true,
|
||||||
"trace:");
|
"trace:");
|
||||||
FILE *fp = popen(cmdbuf, "r");
|
FILE *fp = popen(cmdbuf, "r");
|
||||||
char linebuf[IOSIZE];
|
char linebuf[IOSIZE];
|
||||||
@ -230,22 +234,23 @@ end:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool do_log_to_file(FILE *log_file, int log_level,
|
static bool do_log_to_file(FILE *log_file, int log_level, const char *context,
|
||||||
const char *func_name, int line_num, bool eol,
|
const char *func_name, int line_num, bool eol,
|
||||||
const char* fmt, ...)
|
const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
bool ret = v_do_log_to_file(log_file, log_level, func_name, line_num, eol,
|
bool ret = v_do_log_to_file(log_file, log_level, context, func_name,
|
||||||
fmt, args);
|
line_num, eol, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool v_do_log_to_file(FILE *log_file, int log_level,
|
static bool v_do_log_to_file(FILE *log_file, int log_level,
|
||||||
const char *func_name, int line_num, bool eol,
|
const char *context, const char *func_name,
|
||||||
const char* fmt, va_list args)
|
int line_num, bool eol, const char *fmt,
|
||||||
|
va_list args)
|
||||||
{
|
{
|
||||||
static const char *log_levels[] = {
|
static const char *log_levels[] = {
|
||||||
[DEBUG_LOG_LEVEL] = "DEBUG",
|
[DEBUG_LOG_LEVEL] = "DEBUG",
|
||||||
@ -268,8 +273,15 @@ static bool v_do_log_to_file(FILE *log_file, int log_level,
|
|||||||
|
|
||||||
// print the log message prefixed by the current timestamp and pid
|
// print the log message prefixed by the current timestamp and pid
|
||||||
int64_t pid = os_get_pid();
|
int64_t pid = os_get_pid();
|
||||||
if (fprintf(log_file, "%s %s %" PRId64 "/%s:%d: ", date_time,
|
int rv = (line_num == -1 || func_name == NULL)
|
||||||
log_levels[log_level], pid, func_name, line_num) < 0) {
|
? fprintf(log_file, "%s %s %" PRId64 " %s", date_time,
|
||||||
|
log_levels[log_level], pid,
|
||||||
|
(context == NULL ? "?:" : context))
|
||||||
|
: fprintf(log_file, "%s %s %" PRId64 " %s%s:%d: ", date_time,
|
||||||
|
log_levels[log_level], pid,
|
||||||
|
(context == NULL ? "" : context),
|
||||||
|
func_name, line_num);
|
||||||
|
if (rv < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (vfprintf(log_file, fmt, args) < 0) {
|
if (vfprintf(log_file, fmt, args) < 0) {
|
||||||
|
@ -22,42 +22,42 @@
|
|||||||
# define MIN_LOG_LEVEL INFO_LOG_LEVEL
|
# define MIN_LOG_LEVEL INFO_LOG_LEVEL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LOG(level, ...) do_log((level), __func__, __LINE__, true, \
|
#define LOG(level, ...) do_log((level), NULL, __func__, __LINE__, true, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
|
|
||||||
#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
|
#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
|
||||||
# undef DLOG
|
# undef DLOG
|
||||||
# undef DLOGN
|
# undef DLOGN
|
||||||
# define DLOG(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, true, \
|
# define DLOG(...) do_log(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, true, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
# define DLOGN(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, false, \
|
# define DLOGN(...) do_log(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, false, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MIN_LOG_LEVEL <= INFO_LOG_LEVEL
|
#if MIN_LOG_LEVEL <= INFO_LOG_LEVEL
|
||||||
# undef ILOG
|
# undef ILOG
|
||||||
# undef ILOGN
|
# undef ILOGN
|
||||||
# define ILOG(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, true, \
|
# define ILOG(...) do_log(INFO_LOG_LEVEL, NULL, __func__, __LINE__, true, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
# define ILOGN(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, false, \
|
# define ILOGN(...) do_log(INFO_LOG_LEVEL, NULL, __func__, __LINE__, false, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MIN_LOG_LEVEL <= WARN_LOG_LEVEL
|
#if MIN_LOG_LEVEL <= WARN_LOG_LEVEL
|
||||||
# undef WLOG
|
# undef WLOG
|
||||||
# undef WLOGN
|
# undef WLOGN
|
||||||
# define WLOG(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, true, \
|
# define WLOG(...) do_log(WARN_LOG_LEVEL, NULL, __func__, __LINE__, true, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
# define WLOGN(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, false, \
|
# define WLOGN(...) do_log(WARN_LOG_LEVEL, NULL, __func__, __LINE__, false, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MIN_LOG_LEVEL <= ERROR_LOG_LEVEL
|
#if MIN_LOG_LEVEL <= ERROR_LOG_LEVEL
|
||||||
# undef ELOG
|
# undef ELOG
|
||||||
# undef ELOGN
|
# undef ELOGN
|
||||||
# define ELOG(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, true, \
|
# define ELOG(...) do_log(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
# define ELOGN(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, false, \
|
# define ELOGN(...) do_log(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, false, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -188,12 +188,11 @@ uint64_t channel_connect(bool tcp, const char *address, int timeout,
|
|||||||
return channel->id;
|
return channel->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends event/arguments to channel
|
/// Publishes an event to a channel.
|
||||||
///
|
///
|
||||||
/// @param id The channel id. If 0, the event will be sent to all
|
/// @param id Channel id. 0 means "broadcast to all subscribed channels"
|
||||||
/// channels that have subscribed to the event type
|
/// @param name Event name (application-defined)
|
||||||
/// @param name The event name, an arbitrary string
|
/// @param args Array of event arguments
|
||||||
/// @param args Array with event arguments
|
|
||||||
/// @return True if the event was sent successfully, false otherwise.
|
/// @return True if the event was sent successfully, false otherwise.
|
||||||
bool channel_send_event(uint64_t id, const char *name, Array args)
|
bool channel_send_event(uint64_t id, const char *name, Array args)
|
||||||
{
|
{
|
||||||
@ -215,7 +214,6 @@ bool channel_send_event(uint64_t id, const char *name, Array args)
|
|||||||
send_event(channel, name, args);
|
send_event(channel, name, args);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO(tarruda): Implement event broadcasting in vimscript
|
|
||||||
broadcast_event(name, args);
|
broadcast_event(name, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,8 +345,6 @@ static const struct nv_cmd {
|
|||||||
{ K_F8, farsi_f8, 0, 0 },
|
{ K_F8, farsi_f8, 0, 0 },
|
||||||
{ K_F9, farsi_f9, 0, 0 },
|
{ K_F9, farsi_f9, 0, 0 },
|
||||||
{ K_EVENT, nv_event, NV_KEEPREG, 0 },
|
{ K_EVENT, nv_event, NV_KEEPREG, 0 },
|
||||||
{ K_FOCUSGAINED, nv_focusgained, NV_KEEPREG, 0 },
|
|
||||||
{ K_FOCUSLOST, nv_focuslost, NV_KEEPREG, 0 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Number of commands in nv_cmds[]. */
|
/* Number of commands in nv_cmds[]. */
|
||||||
@ -7961,18 +7959,6 @@ static void nv_event(cmdarg_T *cap)
|
|||||||
finish_op = false;
|
finish_op = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trigger FocusGained event.
|
|
||||||
static void nv_focusgained(cmdarg_T *cap)
|
|
||||||
{
|
|
||||||
apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trigger FocusLost event.
|
|
||||||
static void nv_focuslost(cmdarg_T *cap)
|
|
||||||
{
|
|
||||||
apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
|
* Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
|
||||||
*/
|
*/
|
||||||
|
@ -26,10 +26,11 @@ void state_enter(VimState *s)
|
|||||||
int check_result = s->check ? s->check(s) : 1;
|
int check_result = s->check ? s->check(s) : 1;
|
||||||
|
|
||||||
if (!check_result) {
|
if (!check_result) {
|
||||||
break;
|
break; // Terminate this state.
|
||||||
} else if (check_result == -1) {
|
} else if (check_result == -1) {
|
||||||
continue;
|
continue; // check() again.
|
||||||
}
|
}
|
||||||
|
// Execute this state.
|
||||||
|
|
||||||
int key;
|
int key;
|
||||||
|
|
||||||
@ -48,11 +49,13 @@ getkey:
|
|||||||
ui_flush();
|
ui_flush();
|
||||||
// Call `os_inchar` directly to block for events or user input without
|
// Call `os_inchar` directly to block for events or user input without
|
||||||
// consuming anything from `input_buffer`(os/input.c) or calling the
|
// consuming anything from `input_buffer`(os/input.c) or calling the
|
||||||
// mapping engine. If an event was put into the queue, we send K_EVENT
|
// mapping engine.
|
||||||
// directly.
|
|
||||||
(void)os_inchar(NULL, 0, -1, 0);
|
(void)os_inchar(NULL, 0, -1, 0);
|
||||||
input_disable_events();
|
input_disable_events();
|
||||||
key = !multiqueue_empty(main_loop.events) ? K_EVENT : safe_vgetc();
|
// If an event was put into the queue, we send K_EVENT directly.
|
||||||
|
key = !multiqueue_empty(main_loop.events)
|
||||||
|
? K_EVENT
|
||||||
|
: safe_vgetc();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == K_EVENT) {
|
if (key == K_EVENT) {
|
||||||
|
@ -432,14 +432,6 @@ static int terminal_execute(VimState *state, int key)
|
|||||||
TerminalState *s = (TerminalState *)state;
|
TerminalState *s = (TerminalState *)state;
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case K_FOCUSGAINED: // nvim has been given focus
|
|
||||||
apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case K_FOCUSLOST: // nvim has lost focus
|
|
||||||
apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Temporary fix until paste events gets implemented
|
// Temporary fix until paste events gets implemented
|
||||||
case K_PASTE:
|
case K_PASTE:
|
||||||
break;
|
break;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/main.h"
|
#include "nvim/main.h"
|
||||||
|
#include "nvim/aucmd.h"
|
||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/os/input.h"
|
#include "nvim/os/input.h"
|
||||||
#include "nvim/event/rstream.h"
|
#include "nvim/event/rstream.h"
|
||||||
@ -280,9 +281,9 @@ static void timer_cb(TimeWatcher *watcher, void *data)
|
|||||||
|
|
||||||
/// Handle focus events.
|
/// Handle focus events.
|
||||||
///
|
///
|
||||||
/// If the upcoming sequence of bytes in the input stream matches either the
|
/// If the upcoming sequence of bytes in the input stream matches the termcode
|
||||||
/// escape code for focus gained `<ESC>[I` or focus lost `<ESC>[O` then consume
|
/// for "focus gained" or "focus lost", consume that sequence and schedule an
|
||||||
/// that sequence and push the appropriate event into the input queue
|
/// event on the main loop.
|
||||||
///
|
///
|
||||||
/// @param input the input stream
|
/// @param input the input stream
|
||||||
/// @return true iff handle_focus_event consumed some input
|
/// @return true iff handle_focus_event consumed some input
|
||||||
@ -294,11 +295,7 @@ static bool handle_focus_event(TermInput *input)
|
|||||||
// Advance past the sequence
|
// Advance past the sequence
|
||||||
bool focus_gained = *rbuffer_get(input->read_stream.buffer, 2) == 'I';
|
bool focus_gained = *rbuffer_get(input->read_stream.buffer, 2) == 'I';
|
||||||
rbuffer_consumed(input->read_stream.buffer, 3);
|
rbuffer_consumed(input->read_stream.buffer, 3);
|
||||||
if (focus_gained) {
|
aucmd_schedule_focusgained(focus_gained);
|
||||||
enqueue_input(input, FOCUSGAINED_KEY, sizeof(FOCUSGAINED_KEY) - 1);
|
|
||||||
} else {
|
|
||||||
enqueue_input(input, FOCUSLOST_KEY, sizeof(FOCUSLOST_KEY) - 1);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -71,10 +71,10 @@ static char uilog_last_event[1024] = { 0 };
|
|||||||
uilog_seen++; \
|
uilog_seen++; \
|
||||||
} else { \
|
} else { \
|
||||||
if (uilog_seen > 0) { \
|
if (uilog_seen > 0) { \
|
||||||
do_log(DEBUG_LOG_LEVEL, "ui", 0, true, \
|
do_log(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, \
|
||||||
"%s (+%zu times...)", uilog_last_event, uilog_seen); \
|
"%s (+%zu times...)", uilog_last_event, uilog_seen); \
|
||||||
} \
|
} \
|
||||||
DLOG("ui: " STR(funname)); \
|
do_log(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, STR(funname)); \
|
||||||
uilog_seen = 0; \
|
uilog_seen = 0; \
|
||||||
xstrlcpy(uilog_last_event, STR(funname), sizeof(uilog_last_event)); \
|
xstrlcpy(uilog_last_event, STR(funname), sizeof(uilog_last_event)); \
|
||||||
} \
|
} \
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
-- Some sanity checks for the TUI using the builtin terminal emulator
|
-- TUI acceptance tests.
|
||||||
-- as a simple way to send keys and assert screen state.
|
-- Uses :terminal as a way to send keys and assert screen state.
|
||||||
|
local global_helpers = require('test.helpers')
|
||||||
local helpers = require('test.functional.helpers')(after_each)
|
local helpers = require('test.functional.helpers')(after_each)
|
||||||
local thelpers = require('test.functional.terminal.helpers')
|
local thelpers = require('test.functional.terminal.helpers')
|
||||||
local feed_data = thelpers.feed_data
|
local feed_data = thelpers.feed_data
|
||||||
@ -194,7 +195,7 @@ describe('tui with non-tty file descriptors', function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('tui focus event handling', function()
|
describe('tui FocusGained/FocusLost', function()
|
||||||
local screen
|
local screen
|
||||||
|
|
||||||
before_each(function()
|
before_each(function()
|
||||||
@ -206,7 +207,8 @@ describe('tui focus event handling', function()
|
|||||||
feed_data("\034\016") -- CTRL-\ CTRL-N
|
feed_data("\034\016") -- CTRL-\ CTRL-N
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('can handle focus events in normal mode', function()
|
it('in normal-mode', function()
|
||||||
|
retry(2, 3 * screen.timeout, function()
|
||||||
feed_data('\027[I')
|
feed_data('\027[I')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{1: } |
|
{1: } |
|
||||||
@ -228,11 +230,13 @@ describe('tui focus event handling', function()
|
|||||||
lost |
|
lost |
|
||||||
{3:-- TERMINAL --} |
|
{3:-- TERMINAL --} |
|
||||||
]])
|
]])
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('can handle focus events in insert mode', function()
|
it('in insert-mode', function()
|
||||||
feed_command('set noshowmode')
|
feed_command('set noshowmode')
|
||||||
feed_data('i')
|
feed_data('i')
|
||||||
|
retry(2, 3 * screen.timeout, function()
|
||||||
feed_data('\027[I')
|
feed_data('\027[I')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{1: } |
|
{1: } |
|
||||||
@ -253,9 +257,12 @@ describe('tui focus event handling', function()
|
|||||||
lost |
|
lost |
|
||||||
{3:-- TERMINAL --} |
|
{3:-- TERMINAL --} |
|
||||||
]])
|
]])
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('can handle focus events in cmdline mode', function()
|
-- During cmdline-mode we ignore :echo invoked by timers/events.
|
||||||
|
-- See commit: 5cc87d4dabd02167117be7a978b5c8faaa975419.
|
||||||
|
it('in cmdline-mode does NOT :echo', function()
|
||||||
feed_data(':')
|
feed_data(':')
|
||||||
feed_data('\027[I')
|
feed_data('\027[I')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
@ -264,7 +271,7 @@ describe('tui focus event handling', function()
|
|||||||
{4:~ }|
|
{4:~ }|
|
||||||
{4:~ }|
|
{4:~ }|
|
||||||
{5:[No Name] }|
|
{5:[No Name] }|
|
||||||
g{1:a}ined |
|
:{1: } |
|
||||||
{3:-- TERMINAL --} |
|
{3:-- TERMINAL --} |
|
||||||
]])
|
]])
|
||||||
feed_data('\027[O')
|
feed_data('\027[O')
|
||||||
@ -274,17 +281,46 @@ describe('tui focus event handling', function()
|
|||||||
{4:~ }|
|
{4:~ }|
|
||||||
{4:~ }|
|
{4:~ }|
|
||||||
{5:[No Name] }|
|
{5:[No Name] }|
|
||||||
l{1:o}st |
|
:{1: } |
|
||||||
{3:-- TERMINAL --} |
|
{3:-- TERMINAL --} |
|
||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('can handle focus events in terminal mode', function()
|
it('in cmdline-mode', function()
|
||||||
|
-- Set up autocmds that modify the buffer, instead of just calling :echo.
|
||||||
|
-- This is how we can test handling of focus gained/lost during cmdline-mode.
|
||||||
|
-- See commit: 5cc87d4dabd02167117be7a978b5c8faaa975419.
|
||||||
|
feed_data(":autocmd!\n")
|
||||||
|
feed_data(":autocmd FocusLost * call append(line('$'), 'lost')\n")
|
||||||
|
feed_data(":autocmd FocusGained * call append(line('$'), 'gained')\n")
|
||||||
|
-- Enter cmdline-mode.
|
||||||
|
feed_data(':')
|
||||||
|
screen:sleep(1)
|
||||||
|
-- Send focus lost/gained termcodes.
|
||||||
|
feed_data('\027[O')
|
||||||
|
feed_data('\027[I')
|
||||||
|
screen:sleep(1)
|
||||||
|
-- Exit cmdline-mode. Redraws from timers/events are blocked during
|
||||||
|
-- cmdline-mode, so the buffer won't be updated until we exit cmdline-mode.
|
||||||
|
feed_data('\n')
|
||||||
|
screen:expect([[
|
||||||
|
{1: } |
|
||||||
|
lost |
|
||||||
|
gained |
|
||||||
|
{4:~ }|
|
||||||
|
{5:[No Name] [+] }|
|
||||||
|
: |
|
||||||
|
{3:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('in terminal-mode', function()
|
||||||
feed_data(':set shell='..nvim_dir..'/shell-test\n')
|
feed_data(':set shell='..nvim_dir..'/shell-test\n')
|
||||||
feed_data(':set noshowmode laststatus=0\n')
|
feed_data(':set noshowmode laststatus=0\n')
|
||||||
|
|
||||||
retry(2, 3 * screen.timeout, function()
|
retry(2, 3 * screen.timeout, function()
|
||||||
feed_data(':terminal\n')
|
feed_data(':terminal\n')
|
||||||
|
screen:sleep(1)
|
||||||
feed_data('\027[I')
|
feed_data('\027[I')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{1:r}eady $ |
|
{1:r}eady $ |
|
||||||
@ -311,13 +347,30 @@ describe('tui focus event handling', function()
|
|||||||
feed_data(':bwipeout!\n')
|
feed_data(':bwipeout!\n')
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('in press-enter prompt', function()
|
||||||
|
feed_data(":echom 'msg1'|echom 'msg2'|echom 'msg3'|echom 'msg4'|echom 'msg5'\n")
|
||||||
|
-- Execute :messages to provoke the press-enter prompt.
|
||||||
|
feed_data(":messages\n")
|
||||||
|
feed_data('\027[I')
|
||||||
|
feed_data('\027[I')
|
||||||
|
screen:expect([[
|
||||||
|
msg1 |
|
||||||
|
msg2 |
|
||||||
|
msg3 |
|
||||||
|
msg4 |
|
||||||
|
msg5 |
|
||||||
|
{10:Press ENTER or type command to continue}{1: } |
|
||||||
|
{3:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- These tests require `thelpers` because --headless/--embed
|
-- These tests require `thelpers` because --headless/--embed
|
||||||
-- does not initialize the TUI.
|
-- does not initialize the TUI.
|
||||||
describe("tui 't_Co' (terminal colors)", function()
|
describe("tui 't_Co' (terminal colors)", function()
|
||||||
local screen
|
local screen
|
||||||
local is_freebsd = (helpers.eval("system('uname') =~? 'FreeBSD'") == 1)
|
local is_freebsd = (string.lower(global_helpers.uname()) == 'freebsd')
|
||||||
|
|
||||||
local function assert_term_colors(term, colorterm, maxcolors)
|
local function assert_term_colors(term, colorterm, maxcolors)
|
||||||
helpers.clear({env={TERM=term}, args={}})
|
helpers.clear({env={TERM=term}, args={}})
|
||||||
|
Loading…
Reference in New Issue
Block a user