diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/api/ui.c | 1 | ||||
| -rw-r--r-- | src/nvim/api/vim.c | 28 | ||||
| -rw-r--r-- | src/nvim/aucmd.c | 41 | ||||
| -rw-r--r-- | src/nvim/aucmd.h | 9 | ||||
| -rw-r--r-- | src/nvim/edit.c | 11 | ||||
| -rw-r--r-- | src/nvim/event/loop.c | 27 | ||||
| -rw-r--r-- | src/nvim/event/loop.h | 22 | ||||
| -rw-r--r-- | src/nvim/ex_getln.c | 8 | ||||
| -rw-r--r-- | src/nvim/keymap.c | 294 | ||||
| -rw-r--r-- | src/nvim/keymap.h | 2 | ||||
| -rw-r--r-- | src/nvim/log.c | 40 | ||||
| -rw-r--r-- | src/nvim/log.h | 18 | ||||
| -rw-r--r-- | src/nvim/msgpack_rpc/channel.c | 10 | ||||
| -rw-r--r-- | src/nvim/normal.c | 14 | ||||
| -rw-r--r-- | src/nvim/state.c | 13 | ||||
| -rw-r--r-- | src/nvim/terminal.c | 8 | ||||
| -rw-r--r-- | src/nvim/tui/input.c | 13 | ||||
| -rw-r--r-- | src/nvim/ui.c | 4 | 
18 files changed, 306 insertions, 257 deletions
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 573be23d8e..bbbd5ab2dc 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -215,6 +215,7 @@ static void ui_set_option(UI *ui, String name, Object value, Error *error)  #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)  {    Array call = ARRAY_DICT_INIT; diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index cfbe34b848..ab893a4c0f 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -255,12 +255,11 @@ free_vim_args:    return rv;  } -/// Execute lua code. Parameters might be passed, they are available inside -/// the chunk as `...`. The chunk can return a value. +/// Execute lua code. Parameters (if any) are available as `...` inside the +/// chunk. The chunk can return a value.  /// -/// To evaluate an expression, it must be prefixed with "return ". For -/// instance, to call a lua function with arguments sent in and get its -/// return value back, use the code "return my_function(...)". +/// Only statements are executed. To evaluate an expression, prefix it +/// with `return`: return my_function(...)  ///  /// @param code       lua code to execute  /// @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);  } -/// Sets a global variable -///  /// @deprecated -/// -/// @param name     Variable name -/// @param value    Variable value -/// @param[out] err Error details, if any +/// @see nvim_set_var  /// @return Old value or 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`. +/// @warning May return nil if there was no previous value +///          OR if previous value was `v:null`.  Object vim_set_var(String name, Object value, Error *err)  {    return dict_set_var(&globvardict, name, value, false, true, err);  } -/// Removes a global variable -///  /// @deprecated -/// -/// @param name     Variable name -/// @param[out] err Error details, if any -/// @return Old value +/// @see nvim_del_var  Object vim_del_var(String name, Error *err)  {    return dict_set_var(&globvardict, name, NIL, true, true, err); diff --git a/src/nvim/aucmd.c b/src/nvim/aucmd.c new file mode 100644 index 0000000000..fc421116ea --- /dev/null +++ b/src/nvim/aucmd.c @@ -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; +} + diff --git a/src/nvim/aucmd.h b/src/nvim/aucmd.h new file mode 100644 index 0000000000..6570ba7a92 --- /dev/null +++ b/src/nvim/aucmd.h @@ -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 + diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 17f0b8ef82..2bafb77fef 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -974,14 +974,6 @@ static int insert_handle_key(InsertState *s)      multiqueue_process_events(main_loop.events);      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_KHOME:    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. */    if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP -      || c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT -      || c == K_FOCUSGAINED || c == K_FOCUSLOST) { +      || c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT) {      return retval;    } diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 25701a1621..5adf16c0f3 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -59,7 +59,14 @@ void loop_poll_events(Loop *loop, int ms)    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)  {    uv_mutex_lock(&loop->mutex); @@ -68,6 +75,24 @@ void loop_schedule(Loop *loop, Event event)    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)  {    Loop *loop = data; diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index e7d7bdd483..b0ddc59469 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -16,10 +16,28 @@ KLIST_INIT(WatcherPtr, WatcherPtr, _noop)  typedef struct loop {    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;    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;    uv_async_t async;    uv_mutex_t mutex; diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 5e216925df..fd7ad7a4b5 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1620,14 +1620,6 @@ static int command_line_handle_key(CommandLineState *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:      // Normal character with no special meaning.  Just set mod_mask      // to 0x0 so that typing Shift-Space in the GUI doesn't enter diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index 3d7ebb6382..a75fe793ac 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -140,155 +140,153 @@ static char_u modifier_keys_table[] =  };  static struct key_name_entry { -  int key;              /* Special key code or ascii value */ -  char_u  *name;        /* Name of key */ +  int key;              // Special key code or ascii value +  char *name;           // Name of key  } key_names_table[] =  { -  {' ',               (char_u *)"Space"}, -  {TAB,               (char_u *)"Tab"}, -  {K_TAB,             (char_u *)"Tab"}, -  {NL,                (char_u *)"NL"}, -  {NL,                (char_u *)"NewLine"},     /* Alternative name */ -  {NL,                (char_u *)"LineFeed"},    /* Alternative name */ -  {NL,                (char_u *)"LF"},          /* Alternative name */ -  {CAR,               (char_u *)"CR"}, -  {CAR,               (char_u *)"Return"},      /* Alternative name */ -  {CAR,               (char_u *)"Enter"},       /* Alternative name */ -  {K_BS,              (char_u *)"BS"}, -  {K_BS,              (char_u *)"BackSpace"},   /* Alternative name */ -  {ESC,               (char_u *)"Esc"}, -  {CSI,               (char_u *)"CSI"}, -  {K_CSI,             (char_u *)"xCSI"}, -  {'|',               (char_u *)"Bar"}, -  {'\\',              (char_u *)"Bslash"}, -  {K_DEL,             (char_u *)"Del"}, -  {K_DEL,             (char_u *)"Delete"},      /* Alternative name */ -  {K_KDEL,            (char_u *)"kDel"}, -  {K_UP,              (char_u *)"Up"}, -  {K_DOWN,            (char_u *)"Down"}, -  {K_LEFT,            (char_u *)"Left"}, -  {K_RIGHT,           (char_u *)"Right"}, -  {K_XUP,             (char_u *)"xUp"}, -  {K_XDOWN,           (char_u *)"xDown"}, -  {K_XLEFT,           (char_u *)"xLeft"}, -  {K_XRIGHT,          (char_u *)"xRight"}, - -  {K_F1,              (char_u *)"F1"}, -  {K_F2,              (char_u *)"F2"}, -  {K_F3,              (char_u *)"F3"}, -  {K_F4,              (char_u *)"F4"}, -  {K_F5,              (char_u *)"F5"}, -  {K_F6,              (char_u *)"F6"}, -  {K_F7,              (char_u *)"F7"}, -  {K_F8,              (char_u *)"F8"}, -  {K_F9,              (char_u *)"F9"}, -  {K_F10,             (char_u *)"F10"}, - -  {K_F11,             (char_u *)"F11"}, -  {K_F12,             (char_u *)"F12"}, -  {K_F13,             (char_u *)"F13"}, -  {K_F14,             (char_u *)"F14"}, -  {K_F15,             (char_u *)"F15"}, -  {K_F16,             (char_u *)"F16"}, -  {K_F17,             (char_u *)"F17"}, -  {K_F18,             (char_u *)"F18"}, -  {K_F19,             (char_u *)"F19"}, -  {K_F20,             (char_u *)"F20"}, - -  {K_F21,             (char_u *)"F21"}, -  {K_F22,             (char_u *)"F22"}, -  {K_F23,             (char_u *)"F23"}, -  {K_F24,             (char_u *)"F24"}, -  {K_F25,             (char_u *)"F25"}, -  {K_F26,             (char_u *)"F26"}, -  {K_F27,             (char_u *)"F27"}, -  {K_F28,             (char_u *)"F28"}, -  {K_F29,             (char_u *)"F29"}, -  {K_F30,             (char_u *)"F30"}, - -  {K_F31,             (char_u *)"F31"}, -  {K_F32,             (char_u *)"F32"}, -  {K_F33,             (char_u *)"F33"}, -  {K_F34,             (char_u *)"F34"}, -  {K_F35,             (char_u *)"F35"}, -  {K_F36,             (char_u *)"F36"}, -  {K_F37,             (char_u *)"F37"}, - -  {K_XF1,             (char_u *)"xF1"}, -  {K_XF2,             (char_u *)"xF2"}, -  {K_XF3,             (char_u *)"xF3"}, -  {K_XF4,             (char_u *)"xF4"}, - -  {K_HELP,            (char_u *)"Help"}, -  {K_UNDO,            (char_u *)"Undo"}, -  {K_INS,             (char_u *)"Insert"}, -  {K_INS,             (char_u *)"Ins"},         /* Alternative name */ -  {K_KINS,            (char_u *)"kInsert"}, -  {K_HOME,            (char_u *)"Home"}, -  {K_KHOME,           (char_u *)"kHome"}, -  {K_XHOME,           (char_u *)"xHome"}, -  {K_ZHOME,           (char_u *)"zHome"}, -  {K_END,             (char_u *)"End"}, -  {K_KEND,            (char_u *)"kEnd"}, -  {K_XEND,            (char_u *)"xEnd"}, -  {K_ZEND,            (char_u *)"zEnd"}, -  {K_PAGEUP,          (char_u *)"PageUp"}, -  {K_PAGEDOWN,        (char_u *)"PageDown"}, -  {K_KPAGEUP,         (char_u *)"kPageUp"}, -  {K_KPAGEDOWN,       (char_u *)"kPageDown"}, - -  {K_KPLUS,           (char_u *)"kPlus"}, -  {K_KMINUS,          (char_u *)"kMinus"}, -  {K_KDIVIDE,         (char_u *)"kDivide"}, -  {K_KMULTIPLY,       (char_u *)"kMultiply"}, -  {K_KENTER,          (char_u *)"kEnter"}, -  {K_KPOINT,          (char_u *)"kPoint"}, - -  {K_K0,              (char_u *)"k0"}, -  {K_K1,              (char_u *)"k1"}, -  {K_K2,              (char_u *)"k2"}, -  {K_K3,              (char_u *)"k3"}, -  {K_K4,              (char_u *)"k4"}, -  {K_K5,              (char_u *)"k5"}, -  {K_K6,              (char_u *)"k6"}, -  {K_K7,              (char_u *)"k7"}, -  {K_K8,              (char_u *)"k8"}, -  {K_K9,              (char_u *)"k9"}, - -  {'<',               (char_u *)"lt"}, - -  {K_MOUSE,           (char_u *)"Mouse"}, -  {K_LEFTMOUSE,       (char_u *)"LeftMouse"}, -  {K_LEFTMOUSE_NM,    (char_u *)"LeftMouseNM"}, -  {K_LEFTDRAG,        (char_u *)"LeftDrag"}, -  {K_LEFTRELEASE,     (char_u *)"LeftRelease"}, -  {K_LEFTRELEASE_NM,  (char_u *)"LeftReleaseNM"}, -  {K_MIDDLEMOUSE,     (char_u *)"MiddleMouse"}, -  {K_MIDDLEDRAG,      (char_u *)"MiddleDrag"}, -  {K_MIDDLERELEASE,   (char_u *)"MiddleRelease"}, -  {K_RIGHTMOUSE,      (char_u *)"RightMouse"}, -  {K_RIGHTDRAG,       (char_u *)"RightDrag"}, -  {K_RIGHTRELEASE,    (char_u *)"RightRelease"}, -  {K_MOUSEDOWN,       (char_u *)"ScrollWheelUp"}, -  {K_MOUSEUP,         (char_u *)"ScrollWheelDown"}, -  {K_MOUSELEFT,       (char_u *)"ScrollWheelRight"}, -  {K_MOUSERIGHT,      (char_u *)"ScrollWheelLeft"}, -  {K_MOUSEDOWN,       (char_u *)"MouseDown"},   /* OBSOLETE: Use	  */ -  {K_MOUSEUP,         (char_u *)"MouseUp"},     /* ScrollWheelXXX instead */ -  {K_X1MOUSE,         (char_u *)"X1Mouse"}, -  {K_X1DRAG,          (char_u *)"X1Drag"}, -  {K_X1RELEASE,               (char_u *)"X1Release"}, -  {K_X2MOUSE,         (char_u *)"X2Mouse"}, -  {K_X2DRAG,          (char_u *)"X2Drag"}, -  {K_X2RELEASE,               (char_u *)"X2Release"}, -  {K_DROP,            (char_u *)"Drop"}, -  {K_ZERO,            (char_u *)"Nul"}, -  {K_SNR,             (char_u *)"SNR"}, -  {K_PLUG,            (char_u *)"Plug"}, -  {K_PASTE,           (char_u *)"Paste"}, -  {K_FOCUSGAINED,     (char_u *)"FocusGained"}, -  {K_FOCUSLOST,       (char_u *)"FocusLost"}, -  {0,                 NULL} +  { ' ',               "Space" }, +  { TAB,               "Tab" }, +  { K_TAB,             "Tab" }, +  { NL,                "NL" }, +  { NL,                "NewLine" },     // Alternative name +  { NL,                "LineFeed" },    // Alternative name +  { NL,                "LF" },          // Alternative name +  { CAR,               "CR" }, +  { CAR,               "Return" },      // Alternative name +  { CAR,               "Enter" },       // Alternative name +  { K_BS,              "BS" }, +  { K_BS,              "BackSpace" },   // Alternative name +  { ESC,               "Esc" }, +  { CSI,               "CSI" }, +  { K_CSI,             "xCSI" }, +  { '|',               "Bar" }, +  { '\\',              "Bslash" }, +  { K_DEL,             "Del" }, +  { K_DEL,             "Delete" },      // Alternative name +  { K_KDEL,            "kDel" }, +  { K_UP,              "Up" }, +  { K_DOWN,            "Down" }, +  { K_LEFT,            "Left" }, +  { K_RIGHT,           "Right" }, +  { K_XUP,             "xUp" }, +  { K_XDOWN,           "xDown" }, +  { K_XLEFT,           "xLeft" }, +  { K_XRIGHT,          "xRight" }, + +  { K_F1,              "F1" }, +  { K_F2,              "F2" }, +  { K_F3,              "F3" }, +  { K_F4,              "F4" }, +  { K_F5,              "F5" }, +  { K_F6,              "F6" }, +  { K_F7,              "F7" }, +  { K_F8,              "F8" }, +  { K_F9,              "F9" }, +  { K_F10,             "F10" }, + +  { K_F11,             "F11" }, +  { K_F12,             "F12" }, +  { K_F13,             "F13" }, +  { K_F14,             "F14" }, +  { K_F15,             "F15" }, +  { K_F16,             "F16" }, +  { K_F17,             "F17" }, +  { K_F18,             "F18" }, +  { K_F19,             "F19" }, +  { K_F20,             "F20" }, + +  { K_F21,             "F21" }, +  { K_F22,             "F22" }, +  { K_F23,             "F23" }, +  { K_F24,             "F24" }, +  { K_F25,             "F25" }, +  { K_F26,             "F26" }, +  { K_F27,             "F27" }, +  { K_F28,             "F28" }, +  { K_F29,             "F29" }, +  { K_F30,             "F30" }, + +  { K_F31,             "F31" }, +  { K_F32,             "F32" }, +  { K_F33,             "F33" }, +  { K_F34,             "F34" }, +  { K_F35,             "F35" }, +  { K_F36,             "F36" }, +  { K_F37,             "F37" }, + +  { K_XF1,             "xF1" }, +  { K_XF2,             "xF2" }, +  { K_XF3,             "xF3" }, +  { K_XF4,             "xF4" }, + +  { K_HELP,            "Help" }, +  { K_UNDO,            "Undo" }, +  { K_INS,             "Insert" }, +  { K_INS,             "Ins" },         // Alternative name +  { K_KINS,            "kInsert" }, +  { K_HOME,            "Home" }, +  { K_KHOME,           "kHome" }, +  { K_XHOME,           "xHome" }, +  { K_ZHOME,           "zHome" }, +  { K_END,             "End" }, +  { K_KEND,            "kEnd" }, +  { K_XEND,            "xEnd" }, +  { K_ZEND,            "zEnd" }, +  { K_PAGEUP,          "PageUp" }, +  { K_PAGEDOWN,        "PageDown" }, +  { K_KPAGEUP,         "kPageUp" }, +  { K_KPAGEDOWN,       "kPageDown" }, + +  { K_KPLUS,           "kPlus" }, +  { K_KMINUS,          "kMinus" }, +  { K_KDIVIDE,         "kDivide" }, +  { K_KMULTIPLY,       "kMultiply" }, +  { K_KENTER,          "kEnter" }, +  { K_KPOINT,          "kPoint" }, + +  { K_K0,              "k0" }, +  { K_K1,              "k1" }, +  { K_K2,              "k2" }, +  { K_K3,              "k3" }, +  { K_K4,              "k4" }, +  { K_K5,              "k5" }, +  { K_K6,              "k6" }, +  { K_K7,              "k7" }, +  { K_K8,              "k8" }, +  { K_K9,              "k9" }, + +  { '<',               "lt" }, + +  { K_MOUSE,           "Mouse" }, +  { K_LEFTMOUSE,       "LeftMouse" }, +  { K_LEFTMOUSE_NM,    "LeftMouseNM" }, +  { K_LEFTDRAG,        "LeftDrag" }, +  { K_LEFTRELEASE,     "LeftRelease" }, +  { K_LEFTRELEASE_NM,  "LeftReleaseNM" }, +  { K_MIDDLEMOUSE,     "MiddleMouse" }, +  { K_MIDDLEDRAG,      "MiddleDrag" }, +  { K_MIDDLERELEASE,   "MiddleRelease" }, +  { K_RIGHTMOUSE,      "RightMouse" }, +  { K_RIGHTDRAG,       "RightDrag" }, +  { K_RIGHTRELEASE,    "RightRelease" }, +  { K_MOUSEDOWN,       "ScrollWheelUp" }, +  { K_MOUSEUP,         "ScrollWheelDown" }, +  { K_MOUSELEFT,       "ScrollWheelRight" }, +  { K_MOUSERIGHT,      "ScrollWheelLeft" }, +  { K_MOUSEDOWN,       "MouseDown" },   // OBSOLETE: Use +  { K_MOUSEUP,         "MouseUp" },     // ScrollWheelXXX instead +  { K_X1MOUSE,         "X1Mouse" }, +  { K_X1DRAG,          "X1Drag" }, +  { K_X1RELEASE,       "X1Release" }, +  { K_X2MOUSE,         "X2Mouse" }, +  { K_X2DRAG,          "X2Drag" }, +  { K_X2RELEASE,       "X2Release" }, +  { K_DROP,            "Drop" }, +  { K_ZERO,            "Nul" }, +  { K_SNR,             "SNR" }, +  { K_PLUG,            "Plug" }, +  { K_PASTE,           "Paste" }, +  { 0,                 NULL }  };  static struct mousetable { @@ -721,7 +719,7 @@ int find_special_key_in_table(int c)   */  int get_special_key_code(const char_u *name)  { -  char_u  *table_name; +  char *table_name;    int i, j;    for (i = 0; key_names_table[i].name != NULL; i++) { diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h index b8fed77a90..ee64854c98 100644 --- a/src/nvim/keymap.h +++ b/src/nvim/keymap.h @@ -428,8 +428,6 @@ enum key_extra {  #define K_CMDWIN        TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)  #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_PASTE         TERMCAP2KEY(KS_EXTRA, KE_PASTE) diff --git a/src/nvim/log.c b/src/nvim/log.c index 436a8a4079..7bfe5c4089 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -95,8 +95,12 @@ void log_unlock(void)    uv_mutex_unlock(&mutex);  } -bool do_log(int log_level, const char *func_name, int line_num, bool eol, -            const char* fmt, ...) FUNC_ATTR_UNUSED +/// @param context    description of a shared context or subsystem +/// @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) {      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_start(args, fmt); -  ret = v_do_log_to_file(log_file, log_level, func_name, line_num, eol, -                              fmt, args); +  ret = v_do_log_to_file(log_file, log_level, context, func_name, line_num, +                         eol, fmt, args);    va_end(args);    if (log_file != stderr && log_file != stdout) { @@ -151,7 +155,7 @@ FILE *open_log_file(void)    static bool opening_log_file = false;    // check if it's a recursive call    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.");      return stderr;    } @@ -171,7 +175,7 @@ FILE *open_log_file(void)    //  - LOG() is called before early_init()    //  - Directory does not exist    //  - 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",                   log_file_path);    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:    //    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:");    FILE *fp = popen(cmdbuf, "r");    char linebuf[IOSIZE]; @@ -230,22 +234,23 @@ end:  }  #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* fmt, ...)  {    va_list args;    va_start(args, fmt); -  bool ret = v_do_log_to_file(log_file, log_level, func_name, line_num, eol, -                              fmt, args); +  bool ret = v_do_log_to_file(log_file, log_level, context, func_name, +                              line_num, eol, fmt, args);    va_end(args);    return ret;  }  static bool v_do_log_to_file(FILE *log_file, int log_level, -                             const char *func_name, int line_num, bool eol, -                             const char* fmt, va_list args) +                             const char *context, const char *func_name, +                             int line_num, bool eol, const char *fmt, +                             va_list args)  {    static const char *log_levels[] = {      [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    int64_t pid = os_get_pid(); -  if (fprintf(log_file, "%s %s %" PRId64 "/%s:%d: ", date_time, -              log_levels[log_level], pid, func_name, line_num) < 0) { +  int rv = (line_num == -1 || func_name == NULL) +    ? 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;    }    if (vfprintf(log_file, fmt, args) < 0) { diff --git a/src/nvim/log.h b/src/nvim/log.h index d63bcc366c..f378b92039 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -22,42 +22,42 @@  #  define MIN_LOG_LEVEL INFO_LOG_LEVEL  #endif -#define LOG(level, ...) do_log((level), __func__, __LINE__, true, \ +#define LOG(level, ...) do_log((level), NULL, __func__, __LINE__, true, \                                 __VA_ARGS__)  #if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL  # undef DLOG  # 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__) -# define DLOGN(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, false, \ +# define DLOGN(...) do_log(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, false, \                             __VA_ARGS__)  #endif  #if MIN_LOG_LEVEL <= INFO_LOG_LEVEL  # undef ILOG  # 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__) -# define ILOGN(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, false, \ +# define ILOGN(...) do_log(INFO_LOG_LEVEL, NULL, __func__, __LINE__, false, \                             __VA_ARGS__)  #endif  #if MIN_LOG_LEVEL <= WARN_LOG_LEVEL  # undef WLOG  # 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__) -# define WLOGN(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, false, \ +# define WLOGN(...) do_log(WARN_LOG_LEVEL, NULL, __func__, __LINE__, false, \                             __VA_ARGS__)  #endif  #if MIN_LOG_LEVEL <= ERROR_LOG_LEVEL  # undef ELOG  # 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__) -# define ELOGN(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, false, \ +# define ELOGN(...) do_log(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, false, \                             __VA_ARGS__)  #endif diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 02f3854f47..88232a55de 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -188,12 +188,11 @@ uint64_t channel_connect(bool tcp, const char *address, int timeout,    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 -///        channels that have subscribed to the event type -/// @param name The event name, an arbitrary string -/// @param args Array with event arguments +/// @param id Channel id. 0 means "broadcast to all subscribed channels" +/// @param name Event name (application-defined) +/// @param args Array of event arguments  /// @return True if the event was sent successfully, false otherwise.  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);      }    }  else { -    // TODO(tarruda): Implement event broadcasting in vimscript      broadcast_event(name, args);    } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index f9017164af..6415bec846 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -345,8 +345,6 @@ static const struct nv_cmd {    { K_F8,      farsi_f8,       0,                      0 },    { K_F9,      farsi_f9,       0,                      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[]. */ @@ -7961,18 +7959,6 @@ static void nv_event(cmdarg_T *cap)    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".   */ diff --git a/src/nvim/state.c b/src/nvim/state.c index eb0b590a9b..4d9032b7a5 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -26,10 +26,11 @@ void state_enter(VimState *s)      int check_result = s->check ? s->check(s) : 1;      if (!check_result) { -      break; +      break;     // Terminate this state.      } else if (check_result == -1) { -      continue; +      continue;  // check() again.      } +    // Execute this state.      int key; @@ -48,11 +49,13 @@ getkey:        ui_flush();        // Call `os_inchar` directly to block for events or user input without        // 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 -      // directly. +      // mapping engine.        (void)os_inchar(NULL, 0, -1, 0);        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) { diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index deec930ebd..1c764d302d 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -432,14 +432,6 @@ static int terminal_execute(VimState *state, int key)    TerminalState *s = (TerminalState *)state;    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      case K_PASTE:        break; diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 03587d68f0..8bb5971bd4 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -8,6 +8,7 @@  #include "nvim/api/private/helpers.h"  #include "nvim/ascii.h"  #include "nvim/main.h" +#include "nvim/aucmd.h"  #include "nvim/os/os.h"  #include "nvim/os/input.h"  #include "nvim/event/rstream.h" @@ -280,9 +281,9 @@ static void timer_cb(TimeWatcher *watcher, void *data)  /// Handle focus events.  /// -/// If the upcoming sequence of bytes in the input stream matches either the -/// escape code for focus gained `<ESC>[I` or focus lost `<ESC>[O` then consume -/// that sequence and push the appropriate event into the input queue +/// If the upcoming sequence of bytes in the input stream matches the termcode +/// for "focus gained" or "focus lost", consume that sequence and schedule an +/// event on the main loop.  ///  /// @param input the input stream  /// @return true iff handle_focus_event consumed some input @@ -294,11 +295,7 @@ static bool handle_focus_event(TermInput *input)      // Advance past the sequence      bool focus_gained = *rbuffer_get(input->read_stream.buffer, 2) == 'I';      rbuffer_consumed(input->read_stream.buffer, 3); -    if (focus_gained) { -      enqueue_input(input, FOCUSGAINED_KEY, sizeof(FOCUSGAINED_KEY) - 1); -    } else { -      enqueue_input(input, FOCUSLOST_KEY, sizeof(FOCUSLOST_KEY) - 1); -    } +    aucmd_schedule_focusgained(focus_gained);      return true;    }    return false; diff --git a/src/nvim/ui.c b/src/nvim/ui.c index b85a01814d..01d3604159 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -71,10 +71,10 @@ static char uilog_last_event[1024] = { 0 };        uilog_seen++; \      } else { \        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); \        } \ -      DLOG("ui: " STR(funname)); \ +      do_log(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, STR(funname)); \        uilog_seen = 0; \        xstrlcpy(uilog_last_event, STR(funname), sizeof(uilog_last_event)); \      } \  | 
