Commit Graph

364 Commits

Author SHA1 Message Date
Björn Linse
6da4548f0e api: list information about all channels/jobs.
Fire autocmd when channel opens or its info changes.
Add a way for API clients can describe themselves.
2018-05-23 18:18:16 +02:00
Justin M. Keyes
137eedb4ed API: nvim_get_commands(): return Dictionary 2018-05-12 07:29:21 +02:00
Justin M. Keyes
cb6672853a API: nvim_get_commands(): builtin is irrelevant for buffer-local
builtin commands are never buffer-local, so we can return empty for that
case.
2018-05-12 07:29:21 +02:00
Justin M. Keyes
738bffea2c API: nvim_get_commands(): more attributes
Support more :command attributes:
  -bang
  -bar
  -register
2018-05-11 13:50:00 +02:00
Justin M. Keyes
9fa7727ce0 API: nvim_get_commands(): always return keys
- Always return all keys, with at least NIL value.
- Require `opts` param to be {"builtin":false}
- Validate `opts` param
2018-05-11 13:20:43 +02:00
Nimit Bhardwaj
25b6304840 API: nvim_get_commands() 2018-05-11 13:20:19 +02:00
Justin M. Keyes
273d2cd5d5 Merge #8329 'API: Make nvim_set_option() update :verbose set …' 2018-05-11 10:08:09 +02:00
Justin M. Keyes
cb8ea55d71 nvim_eval: fix memory leak 2018-05-10 04:01:25 +02:00
Justin M. Keyes
2326a4ac3a API: nvim_eval(): return non-generic VimL errors
Use the same pattern as nvim_call_function (_call_function).
2018-05-09 23:18:39 +02:00
Justin M. Keyes
32b0470b03 API: better way to capture abort-causing non-exception errors
This condition is not perfectly reliable:
    (did_emsg && force_abort && !current_exception)

The more proper way to check for abort-causing non-exception errors is
to set up `msg_list` using the "pattern" given by do_cmdline().
2018-05-09 23:18:38 +02:00
Justin M. Keyes
c9f3174075 API: return non-generic VimL errors
- Return VimL errors instead of generic errors for:
  - nvim_call_function
  - nvim_call_dict_function
- Fix tests which were silently broken before this change.

This violates #6150 where we agreed not to translate API errors.  But
that can be fixed later.
2018-05-09 23:18:38 +02:00
Justin M. Keyes
34b6a3d944 doc 2018-05-09 23:18:38 +02:00
Justin M. Keyes
cabffb0182 API: nvim_call_dict_function: expect actual function, not name 2018-05-06 14:52:21 +02:00
Justin M. Keyes
fe7ab60af7 API: nvim_call_dict_function: eliminate internal param
The `internal` param is difficult to explain, and will rarely be
anything but `true`.  To avoid it, use a hack: check if the resolved
dict value starts with "function(".
2018-05-06 14:38:26 +02:00
Justin M. Keyes
19c2ce1901 refactor: nvim_call_dict_function
- Add test coverage for errors.
- Rename, rearrange.
2018-05-06 14:38:26 +02:00
Sebastian Witte
124275dd58 API: nvim_call_dict_function #3032 2018-05-06 14:38:26 +02:00
b-r-o-c-k
7170de1971 api: Make nvim_set_option() update :verbose set ...
Make `:verbose set ...` show when an option was last modified by an
API client or Lua script/chunk. In the case of an API client, the
channel ID is displayed.
2018-05-03 21:05:20 -05:00
Justin M. Keyes
53f11dcfc7 Merge #8218 'Fix errors reported by PVS'
closes #4983
2018-04-27 09:25:02 +02:00
Justin M. Keyes
77cb14cc6d API: nvim__stats()
Use it to verify fsync() behavior.
2018-04-24 00:44:06 +02:00
ZyX
d9c010e45d api/vim: Fix PVS/V547: node was already dereferenced, so can’t be NULL 2018-04-22 20:23:50 +03:00
Björn Linse
c8189096e8 ui_events: correct wrong argument order 2018-04-17 19:09:18 +02:00
Justin M. Keyes
1c3a849881 API/nvim_command_output: handle :echon capture (#8265)
ref https://github.com/neovim/python-client/pull/290
2018-04-13 00:49:37 +02:00
Justin M. Keyes
2cbeb7ca56 ui_set_option: pass String.data, not String 2018-04-12 12:58:27 +02:00
Justin M. Keyes
87f4d2592c test/util: expect_err() (#8257)
other cleanup, ref #8245
2018-04-11 22:07:00 +02:00
Justin M. Keyes
fa6415f13f test/API: validate channel arg (#8245) 2018-04-08 03:01:15 +02:00
ZyX
5660482406 api/buffer: Fix PVS/V547: use correct border for lnum
Should actually be silencing that for the sake of the case when `long` is 
actually not 64-bit. But it appears that Vim had already defined maximal line 
number. And even declared that exact value invalid, so no need in silencing.
2018-04-02 00:41:00 +03:00
ZyX
201a4ef11c *: Replace did_throw checks with current_exception checks
Removes obsolete did_throw after that.
2018-03-25 15:13:05 +03:00
ZyX
79b4b6fc86 *: Make sure that !did_throw implies !current_exception
Fixes #7876
2018-03-25 14:50:48 +03:00
Justin M. Keyes
4e02f1ab87 Merge #8107 'jobs: separate process-group' 2018-03-18 18:36:02 +01:00
Justin M. Keyes
26b84a8b3e build/MSVC: fix "C4003: not enough actual parameters for macro"
For the case of TV_DICTITEM_STRUCT, we can't just pass `1` because:
https://github.com/neovim/neovim/pull/8142#discussion_r175262436
> this variant will trigger array overrun warnings from various static analyzers.
2018-03-18 14:30:05 +01:00
Justin M. Keyes
960f093625 build/MSVC: fix "C4028: formal parameter different from declaration" 2018-03-18 14:11:39 +01:00
Justin M. Keyes
a034d4b69d API: nvim_get_proc()
TODO: "exepath" field (win32: QueryFullProcessImageName())

On unix-likes `ps` is used because the platform-specific APIs are
a nightmare.  For reference, below is a (incomplete) attempt:

diff --git a/src/nvim/os/process.c b/src/nvim/os/process.c
index 09769925aca5..99afbbf290c1 100644
--- a/src/nvim/os/process.c
+++ b/src/nvim/os/process.c
@@ -208,3 +210,60 @@ int os_proc_children(int ppid, int **proc_list, size_t *proc_count)
   return 0;
 }

+/// Gets various properties of the process identified by `pid`.
+///
+/// @param pid Process to inspect.
+/// @return Map of process properties, empty on error.
+Dictionary os_proc_info(int pid)
+{
+  Dictionary pinfo = ARRAY_DICT_INIT;
+#ifdef WIN32
+
+#elif defined(__APPLE__)
+  char buf[PROC_PIDPATHINFO_MAXSIZE];
+  if (proc_pidpath(pid, buf, sizeof(buf))) {
+    name = getName(buf);
+    PUT(pinfo, "exepath", STRING_OBJ(cstr_to_string(buf)));
+    return name;
+  } else {
+    ILOG("proc_pidpath() failed for pid: %d", pid);
+  }
+#elif defined(BSD)
+# if defined(__FreeBSD__)
+#  define KP_COMM(o) o.ki_comm
+# else
+#  define KP_COMM(o) o.p_comm
+# endif
+  struct kinfo_proc *proc = kinfo_getproc(pid);
+  if (proc) {
+    PUT(pinfo, "name", cstr_to_string(KP_COMM(proc)));
+    xfree(proc);
+  } else {
+    ILOG("kinfo_getproc() failed for pid: %d", pid);
+  }
+
+#elif defined(__linux__)
+  char fname[256] = { 0 };
+  char buf[MAXPATHL];
+  snprintf(fname, sizeof(fname), "/proc/%d/comm", pid);
+  FILE *fp = fopen(fname, "r");
+  // FileDescriptor *f = file_open_new(&error, fname, kFileReadOnly, 0);
+  // ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf,
+  //                     const size_t size)
+  if (fp == NULL) {
+    ILOG("fopen() of /proc/%d/comm failed", pid);
+  } else {
+    size_t n = fread(buf, sizeof(char), sizeof(buf) - 1, fp);
+    if (n == 0) {
+      WLOG("fread() of /proc/%d/comm failed", pid);
+    } else {
+      size_t end = MIN(sizeof(buf) - 1, n);
+      end = (end > 0 && buf[end - 1] == '\n') ? end - 1 : end;
+      buf[end] = '\0';
+      PUT(pinfo, "name", STRING_OBJ(cstr_to_string(buf)));
+    }
+  }
+  fclose(fp);
+#endif
+  return pinfo;
+}
2018-03-18 00:11:45 +01:00
Justin M. Keyes
12af7016e2 nvim_get_proc_children: fallback to shell
/proc/…/children may be unavailable because of an unset kernel option.
Fallback to `pgrep` invoked in a shell.
2018-03-16 10:55:12 +01:00
Justin M. Keyes
dbad797edd API: nvim_get_proc_children()
ref https://github.com/libuv/libuv/pull/836
2018-03-16 10:55:12 +01:00
geekodour
9f994bb699 api: nvim_list_uis #8004
ref #7438
closes #4842
2018-03-03 15:06:24 +01:00
Björn Linse
6e5cb0debd ui: refactor ui options 2018-02-13 20:48:51 +01:00
Björn Linse
5d8da126d0 ui/tui: highlighting refactor
Make HlAttr contain highlighting state for both color modes (cterm and rgb).
This allows us to implement termguicolors completely in the TUI.

Simplify some logic duplicated between ui.c and screen.c. Also avoid
some superfluous highlighting reset events.
2018-02-11 10:29:32 +01:00
Justin M. Keyes
c6fe06bbc0 tui: fix use-after-free after UI stop event #7922
ui_bridge:ui_bridge_stop() calls ui_detach_impl() last, so the check for
ui_active() in ui:ui_refresh() doesn't help: tui_main() already freed
the `ui` object.

There is a race between ui_bridge_stop (thread T0) and tui_main (thread T1).
UIBridgeData.stopped could be set while ui_bridge_stop() is in the
middle of loop_poll_events(), which may invoke tui_scheduler() on T0.
The pointers in tui_scheduler() may be invalid by then.

Solution(?): Use the `UI.data` field as a "stopped" flag and check it in
tui_scheduler().

ASAN use-after-free report observed in #7908:

    = ==20066==ERROR: AddressSanitizer: heap-use-after-free on address 0x611000000cd0 at pc 0x00000182abed bp 0x7ffe23b07070 sp 0x7ffe23b07068
    = READ of size 8 at 0x611000000cd0 thread T0
    =     0 0x182abec in tui_scheduler /home/travis/build/neovim/neovim/src/nvim/tui/tui.c:393:23
    =     1 0x1876afd in ui_bridge_update_fg /home/travis/build/neovim/neovim/build/src/nvim/auto/ui_events_bridge.generated.h:205:3
    =     2 0x186c130 in ui_resize /home/travis/build/neovim/neovim/src/nvim/ui.c:310:3
    =     3 0x146b9c2 in screen_resize /home/travis/build/neovim/neovim/src/nvim/screen.c:7483:3
    =     4 0x186a6f0 in ui_refresh /home/travis/build/neovim/neovim/src/nvim/ui.c:284:3
    =     5 0x186bbe0 in ui_refresh_event /home/travis/build/neovim/neovim/src/nvim/ui.c:297:3
    =     6 0xa2219a in multiqueue_process_events /home/travis/build/neovim/neovim/src/nvim/event/multiqueue.c:150:7
    =     7 0xa1bd7f in loop_poll_events /home/travis/build/neovim/neovim/src/nvim/event/loop.c:63:3
    =     8 0x1872709 in ui_bridge_stop /home/travis/build/neovim/neovim/src/nvim/ui_bridge.c:121:5
    =     9 0x1864247 in ui_builtin_stop /home/travis/build/neovim/neovim/src/nvim/ui.c:143:3
    =     10 0x1249ec8 in mch_exit /home/travis/build/neovim/neovim/src/nvim/os_unix.c:140:3
    =     11 0xe56ba9 in getout /home/travis/build/neovim/neovim/src/nvim/main.c:671:3
    =     12 0xfc4c8f in preserve_exit /home/travis/build/neovim/neovim/src/nvim/misc1.c:2653:3
    =     13 0x1247c02 in deadly_signal /home/travis/build/neovim/neovim/src/nvim/os/signal.c:137:3
    =     14 0x1247921 in on_signal /home/travis/build/neovim/neovim/src/nvim/os/signal.c:162:9
    =     15 0xa35618 in signal_event /home/travis/build/neovim/neovim/src/nvim/event/signal.c:47:3
    =     16 0xa2219a in multiqueue_process_events /home/travis/build/neovim/neovim/src/nvim/event/multiqueue.c:150:7
    =     17 0xa1bd7f in loop_poll_events /home/travis/build/neovim/neovim/src/nvim/event/loop.c:63:3
    =     18 0x1237bd6 in input_poll /home/travis/build/neovim/neovim/src/nvim/os/input.c:349:3
    =     19 0x123334f in inbuf_poll /home/travis/build/neovim/neovim/src/nvim/os/input.c:372:24
    =     20 0x123316d in os_inchar /home/travis/build/neovim/neovim/src/nvim/os/input.c:110:19
    =     21 0x170d20e in state_enter /home/travis/build/neovim/neovim/src/nvim/state.c:55:13
    =     22 0xbd7441 in command_line_enter /home/travis/build/neovim/neovim/src/nvim/ex_getln.c:384:3
    =     23 0xbd0a60 in getcmdline /home/travis/build/neovim/neovim/src/nvim/ex_getln.c:1920:10
    =     24 0xbdb365 in getexline /home/travis/build/neovim/neovim/src/nvim/ex_getln.c:2100:10
    =     25 0xb00a6b in do_cmdline /home/travis/build/neovim/neovim/src/nvim/ex_docmd.c:528:47
    =     26 0x10a7837 in nv_colon /home/travis/build/neovim/neovim/src/nvim/normal.c:4552:18
    =     27 0x1091e15 in normal_execute /home/travis/build/neovim/neovim/src/nvim/normal.c:1136:3
    =     28 0x170d439 in state_enter /home/travis/build/neovim/neovim/src/nvim/state.c:67:26
    =     29 0x104ee14 in normal_enter /home/travis/build/neovim/neovim/src/nvim/normal.c:466:3
    =     30 0xe4295c in main /home/travis/build/neovim/neovim/src/nvim/main.c:572:3
    =     31 0x2b2ba340bf44 in __libc_start_main /build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:287
    =     32 0x44d24b in _start (/home/travis/build/neovim/neovim/build/bin/nvim+0x44d24b)
    =
    = 0x611000000cd0 is located 16 bytes inside of 240-byte region [0x611000000cc0,0x611000000db0)
    = freed by thread T1 here:
    =     0 0x4ee0e2 in __interceptor_free /local/mnt/workspace/tmp/ubuntu_rel/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:47:3
    =     1 0xf4f6d4 in xfree /home/travis/build/neovim/neovim/src/nvim/memory.c:133:3
    =     2 0x182a963 in tui_main /home/travis/build/neovim/neovim/src/nvim/tui/tui.c:383:3
    =     3 0x18792b0 in ui_thread_run /home/travis/build/neovim/neovim/src/nvim/ui_bridge.c:106:3
    =     4 0x2b2ba2697183 in start_thread /build/eglibc-ripdx6/eglibc-2.19/nptl/pthread_create.c:312
    =
    = previously allocated by thread T0 here:
    =     0 0x4ee61a in calloc /local/mnt/workspace/tmp/ubuntu_rel/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:76:3
    =     1 0xf4f787 in xcalloc /home/travis/build/neovim/neovim/src/nvim/memory.c:147:15
    =     2 0x182000a in tui_start /home/travis/build/neovim/neovim/src/nvim/tui/tui.c:127:12
    =     3 0x1863f7c in ui_builtin_start /home/travis/build/neovim/neovim/src/nvim/ui.c:125:3
    =     4 0xe41bb9 in main /home/travis/build/neovim/neovim/src/nvim/main.c:457:5
    =     5 0x2b2ba340bf44 in __libc_start_main /build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:287
    =
    = Thread T1 created by T0 here:
    =     0 0x4d774d in __interceptor_pthread_create /local/mnt/workspace/tmp/ubuntu_rel/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc:317:3
    =     1 0x1aae6b0 in uv_thread_create /home/travis/nvim-deps/build/src/libuv/src/unix/thread.c:75
    =     2 0x18217fa in tui_start /home/travis/build/neovim/neovim/src/nvim/tui/tui.c:159:10
    =     3 0x1863f7c in ui_builtin_start /home/travis/build/neovim/neovim/src/nvim/ui.c:125:3
    =     4 0xe41bb9 in main /home/travis/build/neovim/neovim/src/nvim/main.c:457:5
    =     5 0x2b2ba340bf44 in __libc_start_main /build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:287

---

Alternative attempt:

    commit 6ad9c02491606a0c31e907f38c9931f324327aa5
    Author: Justin M. Keyes <justinkz@gmail.com>
    Date:   Sat Jan 27 15:12:58 2018 +0100

        tui: fix use-after-free: swap in empty scheduler

        This should make life easier for UIs like VimR which implement their own
        in-process bridged UI: they don't need to worry that their `scheduler`
        might receive an invalid pointer.

        To avoid that, ui_bridge_stopped() swaps in an empty scheduler. Note
        that this requires the call to loop_poll_events() to be moved into the
        critical section.

    diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
    index 779585416f80..491052d19d3b 100644
    --- a/src/nvim/ui_bridge.c
    +++ b/src/nvim/ui_bridge.c
    @@ -93,10 +93,18 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
       return &rv->bridge;
     }

    +static void ui_bridge_null_scheduler(Event event, void *d)
    +{
    +  WLOG("ignoring event (bridge stopped)");
    +}
    +
     void ui_bridge_stopped(UIBridgeData *bridge)
     {
       uv_mutex_lock(&bridge->mutex);
       bridge->stopped = true;
    +  // Replace with an empty scheduler, so that the UI internal scheduler does
    +  // not get invoked with an invalid pointer. #7922
    +  bridge->scheduler = ui_bridge_null_scheduler;
       uv_mutex_unlock(&bridge->mutex);
     }

    @@ -111,14 +119,11 @@ static void ui_bridge_stop(UI *b)
       UIBridgeData *bridge = (UIBridgeData *)b;
       bool stopped = bridge->stopped = false;
       UI_BRIDGE_CALL(b, stop, 1, b);
    -  for (;;) {
    +  while (!stopped) {
         uv_mutex_lock(&bridge->mutex);
         stopped = bridge->stopped;
    -    uv_mutex_unlock(&bridge->mutex);
    -    if (stopped) {
    -      break;
    -    }
         loop_poll_events(&main_loop, 10);  // Process one event (at most).
    +    uv_mutex_unlock(&bridge->mutex);
       }
       uv_thread_join(&bridge->ui_thread);
       uv_mutex_destroy(&bridge->mutex);
2018-01-28 03:08:04 +01:00
George Zhao
06994e0e21 Fix warning about conversion on mingw64 2018-01-18 21:30:03 +08:00
Justin M. Keyes
de0a9548f7 Merge #7806 from ZyX-I/list-stat
Add a way to collect list usage statistics
2018-01-15 23:35:20 +01:00
mkotha
ac87d9de69 Fix an off-by-one error in the documentation of nvim_buf_clear_highlight (#7853) 2018-01-15 21:45:10 +01:00
ZyX
9ea1752d60 *: Provide list length when allocating lists 2018-01-14 01:33:16 +03:00
Justin M. Keyes
5055d4a755 api: nvim_command_output: direct impl 2018-01-10 23:58:56 +01:00
Justin M. Keyes
c095f83116 api: change nvim_command_output behavior
Implement nvim_command_output with `execute({cmd},"silent")`.

Behavior changes:
- does not provoke any hit-enter prompt
- no longer prepends a newline char
- does not capture some noise (like the "[New File]" message, see the
  change to tabnewentered_spec.lua)

Technically ("bug-for-bug") this a breaking change.  But the previous
behavior of nvim_command_output meant that it probably wasn't used for
anything outside of tests.

Also remove the undocumented `v:command_output` variable which was
a hack introduced only for the purposes of nvim_command_output.

closes #7726
2018-01-10 23:45:44 +01:00
Justin M. Keyes
9ad557fb2d Merge pull request #7762 from ZyX-I/remove-some-listitems
Remove some tv_list_item_…() functions
2017-12-31 01:11:50 +01:00
Justin M. Keyes
fe60fa9faa doc
vim-patch:8.0.1206: no autocmd for entering or leaving the command line
(commit a4f6cec7a3)

NA patches:
vim-patch:8.0.0320: warning for unused variable with small build
2017-12-26 03:58:28 +01:00
ZyX
0c533a488f *: Remove most calls to tv_list_item_alloc
Still left calls in eval/typval.c and test/unit/eval/helpers.lua. Latter is the 
only reason why function did not receive `static` modifier.
2017-12-24 14:09:35 +03:00
ZyX
7f3b9a4acc Merge branch 'master' into hide-container-impl 2017-12-16 14:27:41 +03:00
Björn Linse
34057045be ui: forward relevant option updates to UIs (#7520)
also make termguicolors mutable after startup
2017-12-12 18:23:19 +01:00
ZyX
45998deb5d *: Fix linter errors 2017-12-12 00:52:14 +03:00