Commit Graph

102 Commits

Author SHA1 Message Date
Matthieu Coudron
e3a2cca387 Increased test coverage for RGB and cterm 2017-09-30 11:43:26 +09:00
Matthieu Coudron
ba7277cfb4 Adds nvim_get_hl_by_name/by_id
...in order to retrieve highlights.

Added test/functional/api/highlight_spec.lua
HL_NORMAL is not really a good name, since it's more like an empty attribute than the normal's one.
If one pays attention, syn_cterm_attr2entry is never called with attr=0 because it's always special cased before.
I suggest in subsequent PRs we remove the ATTR_OFF and just insert an EMPTY ATTR/RESET_ATTR/UNINITIALIZED for id 0.
2017-09-30 11:43:26 +09:00
Justin M. Keyes
9d6bac3219 test: more coverage for RPC + op-pending #3732 2017-09-16 12:21:31 +02:00
Justin M. Keyes
ce852bab04 eventloop: K_EVENT does not finish mapping
The "mapping" tests added in 541dde36e3 were flawed:
- Unlike op-pending mode, RPCs are _blocked_ during map-pending. So
  a synchronous RPC like nvim_get_current_buf() waits until
  'timeoutlen', then the mapping is canceled.
- helpers.expect() also performs a blocking RPC, so again that must not
  intervene the two nvim_input() calls.

closes #6166
2017-09-04 22:51:04 +02:00
Justin M. Keyes
3922237b14 test: lint 2017-09-04 10:46:10 +02:00
Matthew Malcomson
541dde36e3 eventloop: K_EVENT should not finish operator
normal_finish_command() and normal_prepare() assume that any pending
operator needs to be finished after any subsequent key.

Set `finish_op = false` in nv_event() to indicate that the pending
operator shouldn't be finished in normal_execute().

This is how nv_visual() indicates that 'v' or 'V' in operator-pending
mode should not finish the current pending operator.

fixes #5398
fixes #6166 (partially; mappings are still interrupted)
2017-09-04 08:20:04 +02:00
Justin M. Keyes
af993da435 rpc: close channel if stream was closed
f_jobstop()/f_rpcstop() .. process_stop() .. process_close_in(proc)
closes the write-stream of a RPC channel. But there might be
a pending RPC notification on the queue, which may get processed just
before the channel is closed.

To handle that case, check the Stream.closed in
channel.c:receive_msgpack().

Before this change, the above scenario could trigger
this assert(!stream->closed) in wstream_write():

    0x00007f96e1cd3428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
    0x00007f96e1cd502a in __GI_abort () at abort.c:89
    0x00007f96e1ccbbd7 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x768f9b "!stream->closed",
    file=file@entry=0x768f70 "../src/nvim/event/wstream.c", line=line@entry=77,
    function=function@entry=0x768fb0 <__PRETTY_FUNCTION__.13735> "wstream_write") at assert.c:92
    0x00007f96e1ccbc82 in __GI___assert_fail (assertion=0x768f9b "!stream->closed", file=0x768f70 "../src/nvim/event/wstream.c", line=77,
    function=0x768fb0 <__PRETTY_FUNCTION__.13735> "wstream_write") at assert.c:101
    0x00000000004d2c1f in wstream_write (stream=0x7f96e0a35078, buffer=0x7f96e09f9b40) at ../src/nvim/event/wstream.c:77
    0x00000000005857b2 in channel_write (channel=0x7f96e0ae5800, buffer=0x7f96e09f9b40) at ../src/nvim/msgpack_rpc/channel.c:551
    0x000000000058567d in on_request_event (argv=0x7ffed792efa0) at ../src/nvim/msgpack_rpc/channel.c:523
    0x00000000005854c8 in handle_request (channel=0x7f96e0ae5800, request=0x7ffed792f1b8) at ../src/nvim/msgpack_rpc/channel.c:503
    0x00000000005850cb in parse_msgpack (channel=0x7f96e0ae5800) at ../src/nvim/msgpack_rpc/channel.c:423
    0x0000000000584f90 in receive_msgpack (stream=0x7f96e0a35218, rbuf=0x7f96e0d1d4c0, c=22, data=0x7f96e0ae5800, eof=false)
    at ../src/nvim/msgpack_rpc/channel.c:389
    0x00000000004d0b20 in read_event (argv=0x7ffed792f4a8) at ../src/nvim/event/rstream.c:190
    0x00000000004ce462 in multiqueue_process_events (this=0x7f96e18172d0) at ../src/nvim/event/multiqueue.c:150
    0x000000000059b630 in nv_event (cap=0x7ffed792f620) at ../src/nvim/normal.c:7908
    0x000000000058be69 in normal_execute (state=0x7ffed792f580, key=-25341) at ../src/nvim/normal.c:1137
    0x0000000000652463 in state_enter (s=0x7ffed792f580) at ../src/nvim/state.c:61
    0x000000000058a1fe in normal_enter (cmdwin=false, noexmode=false) at ../src/nvim/normal.c:467
    0x00000000005500c2 in main (argc=2, argv=0x7ffed792f8d8) at ../src/nvim/main.c:554

Alternative approach suggested by bfredl is to use close_cb of the
process. My unsuccessful attempt is below. (It seems close_cb is queued
too late, which is the similar problem addressed by this commit):

    commit 75fc12c6ab15711bdb7b18c6d42ec9d157f5145e
    Author: Justin M. Keyes <justinkz@gmail.com>
    Date:   Fri Aug 18 01:30:41 2017 +0200

        rpc: use Stream's close_cb instead of explicit check in receive_msgpack()

    diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
    index 8371d3cd482e..e52da23cdc40 100644
    --- a/src/nvim/event/process.c
    +++ b/src/nvim/event/process.c
    @@ -416,6 +416,10 @@ static void on_process_exit(Process *proc)
     static void on_process_stream_close(Stream *stream, void *data)
     {
       Process *proc = data;
    +  ILOG("on_process_stream_close");
    +  if (proc->stream_close_cb != NULL) {
    +    proc->stream_close_cb(stream, proc->stream_close_data);
    +  }
       decref(proc);
     }

    diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
    index 5c00e8e7ecd5..34a8d54f6f8c 100644
    --- a/src/nvim/event/process.h
    +++ b/src/nvim/event/process.h
    @@ -26,6 +26,11 @@ struct process {
       Stream *in, *out, *err;
       process_exit_cb cb;
       internal_process_cb internal_exit_cb, internal_close_cb;
    +
    +  // Called when any of the process streams (in/out/err) closes.
    +  stream_close_cb stream_close_cb;
    +  void *stream_close_data;
    +
       bool closed, detach;
       MultiQueue *events;
     };
    @@ -50,6 +55,8 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
         .closed = false,
         .internal_close_cb = NULL,
         .internal_exit_cb = NULL,
    +    .stream_close_cb = NULL,
    +    .stream_close_data = NULL,
         .detach = false
       };
     }
    diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c
    index 7c865bfe1e8c..c8720d1e45d9 100644
    --- a/src/nvim/event/stream.c
    +++ b/src/nvim/event/stream.c
    @@ -95,7 +95,11 @@ void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data)
     void stream_close_handle(Stream *stream)
       FUNC_ATTR_NONNULL_ALL
     {
    +  ILOG("stream=%d", stream);
    +  // LOG_CALLSTACK();
       if (stream->uvstream) {
    +    // problem:  this schedules on the queue, but channel.c:receive_msgpack may
    +    // be processed before close_cb is called by libuv.
         uv_close((uv_handle_t *)stream->uvstream, close_cb);
       } else {
         uv_close((uv_handle_t *)&stream->uv.idle, close_cb);
    @@ -105,6 +109,7 @@ void stream_close_handle(Stream *stream)
     static void close_cb(uv_handle_t *handle)
     {
       Stream *stream = handle->data;
    +  ILOG(">>>>>>>>>>>>>>>>>>>>>>> stream=%p stream->internal_close_cb=%p", stream, stream->internal_close_cb);
       if (stream->buffer) {
         rbuffer_free(stream->buffer);
       }
    diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
    index 782eabe04e4a..dc2b794e366a 100644
    --- a/src/nvim/msgpack_rpc/channel.c
    +++ b/src/nvim/msgpack_rpc/channel.c
    @@ -128,6 +128,8 @@ uint64_t channel_from_process(Process *proc, uint64_t id, char *source)
                                           source);
       incref(channel);  // process channels are only closed by the exit_cb
       channel->data.proc = proc;
    +  channel->data.proc->stream_close_cb = close_cb2;
    +  channel->data.proc->stream_close_data = channel;

       wstream_init(proc->in, 0);
       rstream_init(proc->out, 0);
    @@ -387,17 +389,6 @@ static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c,
         goto end;
       }

    -  if ((chan_wstream(channel) != NULL && chan_wstream(channel)->closed)
    -      || (chan_rstream(channel) != NULL && chan_rstream(channel)->closed)) {
    -    char buf[256];
    -    snprintf(buf, sizeof(buf),
    -             "ch %" PRIu64 ": stream closed unexpectedly. "
    -             "closing channel",
    -             channel->id);
    -    call_set_error(channel, buf, WARN_LOG_LEVEL);
    -    goto end;
    -  }
    -
       size_t count = rbuffer_size(rbuf);
       DLOG("ch %" PRIu64 ": parsing %u bytes from msgpack Stream: %p",
            channel->id, count, stream);
    @@ -571,23 +562,6 @@ static Stream *chan_wstream(Channel *chan)
       abort();
     }

    -/// Returns the Stream that a Channel reads from.
    -static Stream *chan_rstream(Channel *chan)
    -{
    -  switch (chan->type) {
    -    case kChannelTypeSocket:
    -      return &chan->data.stream;
    -    case kChannelTypeProc:
    -      return chan->data.proc->out;
    -    case kChannelTypeStdio:
    -      return &chan->data.std.in;
    -    case kChannelTypeInternal:
    -      return NULL;
    -  }
    -  abort();
    -}
    -
    -
     static bool channel_write(Channel *channel, WBuffer *buffer)
     {
       bool success = false;
    @@ -799,6 +773,12 @@ static void close_cb(Stream *stream, void *data)
       decref(data);
     }

    +static void close_cb2(Stream *stream, void *data)
    +{
    +  ILOG("close_cb2");
    +  close_channel(data);
    +}
    +
     /// @param source description of source function, rplugin name, TCP addr, etc
     static Channel *register_channel(ChannelType type, uint64_t id,
                                      MultiQueue *events, char *source)
2017-08-21 01:04:28 +02:00
Justin M. Keyes
0ea7e45bc1 'cpoptions': remove "<" flag; ignore <special>
Closes #6937 "nvim_get_keymap output is unreliable"
2017-07-08 16:34:35 +02:00
ZyX
d5916a823a functests: Test how spaces appear in get_keymap output 2017-07-02 20:08:00 +03:00
ZyX
5fe5d712aa functests: Use more extensive testing
Fixes #6937
2017-07-02 19:50:03 +03:00
ZyX
24f0056ca5 message: Add support for replacing < to str2special 2017-07-02 19:37:21 +03:00
ZyX
a1fee487ba functests: Add tests for new behaviour
Apparently it is not working yet.
2017-07-02 19:28:44 +03:00
ZyX
4b8bdd953e functests: Remove local_copy function 2017-07-02 19:21:21 +03:00
Justin M. Keyes
ca4633bfe4 ci/quickbuild: XXX: disable server_requests test (#6851)
Temporarily disable this test which hangs quickbuild.

From #6905: The hang occurs when calling nvim_set_current_line.

References #6594 5a151555c8
2017-07-02 00:30:00 +02:00
Justin M. Keyes
f34befe74c Merge #6789 from ZyX-I/lua-path
lua: Add paths from &runtimepath to package.path and package.cpath
2017-06-27 02:29:15 +02:00
Björn Linse
5a151555c8 sockets: don't deadlock when connecting to own pipe address 2017-05-29 19:02:49 +02:00
Björn Linse
6a75938758 channels: implement sockopen() to connect to socket
Helped-By: oni-link <knil.ino@gmail.com>
2017-05-29 19:02:49 +02:00
TJ DeVries
45626de63f get_keymap API (#6236)
* Add api function get keymap

nvim_get_keymap(mode)
nvim_buf_get_keymap(buffer, mode)
2017-05-25 12:41:53 +02:00
ZyX
a5a5c83608 api/vim: Fix nvim_list_runtimepaths
It used to

1. Always omit last component in runtimepath.
2. Always omit trailing empty item and leave uninitialized memory in place of 
   it.
2017-05-23 00:16:23 +03:00
Justin M. Keyes
bdd73fc07f api/nvim_replace_termcodes: Document keycodes behavior 2017-05-20 22:20:32 +02:00
Björn Linse
f424189093 api: execute lua directly from the remote api 2017-05-13 15:03:42 +02:00
ZyX
5b6d598ca8 functests: Fix tests 2017-05-08 21:21:03 +03:00
ZyX
09f849b600 Merge branch 'master' into luaviml'/lua 2017-05-08 15:43:45 +03:00
Justin M. Keyes
acfd2a2a29 input.c: Process only safe events before blocking.
Introduce multiqueue_process_priority() to process only events at or
above a certain priority.
2017-04-28 19:19:51 +02:00
Justin M. Keyes
3ea1007753 api: nvim_get_mode()
Asynchronous API functions are served immediately, which means pending
input could change the state of Nvim shortly after an async API function
result is returned.

nvim_get_mode() is different:
  - If RPCs are known to be blocked, it responds immediately (without
    flushing the input/event queue)
  - else it is handled just-in-time before waiting for input, after
    pending input was processed. This makes the result more reliable
    (but not perfect).

Internally this is handled as a special case, but _semantically_ nothing
has changed: API users never know when input flushes, so this internal
special-case doesn't violate that. As far as API users are concerned,
nvim_get_mode() is just another asynchronous API function.

In all cases nvim_get_mode() never blocks for more than the time it
takes to flush the input/event queue (~µs).

Note: This doesn't address #6166; nvim_get_mode() will provoke #6166 if
e.g. `d` is operator-pending.

Closes #6159
2017-04-28 19:14:34 +02:00
Justin M. Keyes
086c354a0a api: Do not translate error messages.
Also re-word some error messages:
- "Key does not exist: %s"
- "Invalid channel: %<PRIu64>"
- "Request array size must be 4 (request) or 3 (notification)"
- "String cannot contain newlines"

References #6150
2017-04-24 00:11:27 +02:00
Justin M. Keyes
4524053874 test: api: Do not truncate errors <1 MB. 2017-04-23 23:24:16 +02:00
ZyX
add76592d9 functests: Test for “string cannot contain newline” set_lines error
Should make me able to determine whether they are lua bindings that contain 
a bug or set_lines.
2017-04-11 02:24:37 +03:00
ZyX
ab4d13e2fa Merge branch 'master' into luaviml'/lua 2017-04-10 22:21:06 +03:00
ZyX
69d1003bf7 functests: Fix some tests which are failing locally for unrelated reasons 2017-04-09 03:24:14 +03:00
ZyX
65fb622000 functests: Replace execute with either command or feed_command
Hope this will make people using feed_command less likely: this hides bugs.
Already found at least two:

1. msgpackparse() will show internal error: hash_add() in case of duplicate
   keys, though it will still work correctly. Currently silenced.
2. ttimeoutlen was spelled incorrectly, resulting in option not being set when
   expected. Test was still functioning somehow though. Currently fixed.
2017-04-09 03:24:08 +03:00
ZyX
043d8ff9f2 Merge branch 'master' into luaviml'/lua 2017-04-08 01:54:58 +03:00
Jakob Schnitzer
eb0e94f71b api: {get,set}_option should {get,set} global value of local options (#6405)
- nvim_get_option should return the global default of a local option.
- nvim_set_option should set the global default of a local option.
2017-03-30 22:03:52 +02:00
ZyX
ba2f615cd4 functests: Test for error conditions
During testing found the following bugs:

1. msgpack-gen.lua script is completely unprepared for Float values either in 
   return type or in arguments. Specifically:

   1. At the time of writing relevant code FLOAT_OBJ did not exist as well as 
      FLOATING_OBJ, but it would be used by msgpack-gen.lua should return type 
      be Float. I added FLOATING_OBJ macros later because did not know that 
      msgpack-gen.lua uses these _OBJ macros, otherwise it would be FLOAT_OBJ.
   2. msgpack-gen.lua should use .data.floating in place of .data.float. But it 
      did not expect that .data subattribute may have name different from 
      lowercased type name.

2. vim_replace_termcodes returned its argument as-is if it receives an empty 
   string (as well as _vim_id*() functions did). But if something in returned 
   argument lives in an allocated memory such action will cause double free: 
   once when freeing arguments, then when freeing return value. It did not cause 
   problems yet because msgpack bindings return empty string as {NULL, 0} and 
   nothing was actually allocated.
3. New code in msgpack-gen.lua popped arguments in reversed order, making lua 
   bindings’ signatures be different from API ones.
2017-03-27 00:11:28 +03:00
Björn Linse
9500ecdda5 api: add detailed checks for compatibility and correct "since" value 2017-03-15 15:01:06 +01:00
Matthew Malcomson
6fe677c108 api: nvim_buf_set_lines(): Avoid invalid ml_get. #6019
When the buffer that nvim_buf_set_lines() is changing is not in any vim
window, fix_cursor() leads to calling ml_get_buf() with an invalid line
number. The condition that fix_cursor() was called on was (buf ==
curbuf), but this is always true because of the call to
switch_to_win_for_buf() earlier in the function.

Instead this should be predicated on (save_curbuf.br_buf == NULL)
2017-03-07 01:29:08 +01:00
ZyX
9c1865c7f8 *: Fix linter errors 2017-02-23 19:48:41 +03:00
ZyX
858ac9d8e5 api: Make sure dict_set_var doesn’t edit read-only values
Fixes #6147
2017-02-23 19:48:41 +03:00
ZyX
6550caee50 functests: Destroy accidental folds in api/vim_spec 2017-02-23 19:48:41 +03:00
ZyX
4f10d42f82 buffer: Bind b:changedtick to b:['changedtick'], remove special cases 2017-02-23 19:46:44 +03:00
ZyX
0eab7ac4b9 api/buffer: Add nvim_buf_get_changedtick method 2017-02-23 19:46:44 +03:00
Justin M. Keyes
e40946a5be win: test: enable job_spec.lua
- Default to powershell.
- Avoid hardcoded "-c".
- Remove ^M character from received lines.
- pending_win32(): clear() is unnecessary and it pollutes the tests.

Closes #3973
Helped-by: Rui Abreu Ferreira <raf-ep@gmx.com>
2017-01-19 09:55:57 +01:00
Justin M. Keyes
82edcb593b Windows: enable more tests 2017-01-13 01:17:12 +01:00
Justin M. Keyes
c5f5f427c6 api: api_info()['version']
API level is disconnected from NVIM version. The API metadata holds the
current API level, and the lowest backwards-compatible level supported
by this instance.

Release 0.1.6 is the first release that reports the Nvim version and API
level.

    metadata['version'] = {
      major: 0,
      minor: 1,
      patch: 6,
      api_level: 1,
      api_compatible: 0,
      api_prerelease: false,
    }

The API level may remain unchanged across Nvim releases if the API has
not changed.

When changing the API,
    - set NVIM_API_PRERELEASE to true
    - increment NVIM_API_LEVEL (at most once per Nvim version)
    - adjust NVIM_API_LEVEL_COMPAT if backwards-compatibility was broken

api_level_0.mpack was generated from Nvim 0.1.5 with:
    nvim --api-info
2016-10-28 14:33:13 +02:00
Rui Abreu Ferreira
f25797f869 api: Nvim version, API level #5386
The API level is disconnected from the NVIM version. The API metadata
holds the current API level, and the lowest backwards-compatible level
supported by this instance.

Release 0.1.6 will be the first release reporting the Nvim version and
API level.

    metadata['version'] = {
      major: 0,
      minor: 1,
      patch: 6,
      prerelease: true,
      api_level: 1,
      api_compatible: 0,
    }

The API level may remain unchanged across Neovim releases if the API has
not changed.

When changing the API the CMake variable NVIM_API_PRERELEASE is set to
true, and  NVIM_API_CURRENT/NVIM_API_COMPATIBILITY are incremented
accordingly.

The functional tests check the API table against fixtures of past
versions of Neovim. It compares all the functions in the old table with
the new one, it does ignore some metadata attributes that do not alter
the function signature or were removed since 0.1.5.  Currently the only
fixture is 0.mpack, generated from Neovim 0.1.5 with nvim --api-info.
2016-10-26 14:23:50 +02:00
Justin M. Keyes
43309d1993 test/api: Specify handling of VimL errors, v:errmsg.
TODO: Also spec behavior of Press-Enter prompt for these API functions.
2016-10-24 01:10:23 +02:00
Björn Linse
f6968dc0f7 api: call multiple methods atomically (useful in async contexts)
remove unused response_id parameter of handle_nvim_... helpers
2016-10-22 10:51:32 +02:00
James McCoy
b268ba353a Merge pull request #5424 from jamessan/win-tab-nr
api: Support getting the number of a window/tabpage
2016-10-15 15:29:53 -04:00
Jurica Bradaric
1b61bd93ae server_requests_spec: Expect correct window ID. 2016-10-07 17:07:17 +02:00
James McCoy
1ebb75b1ec api: Support getting the number of a window/tabpage
In order to provide better compatibility with the classic bindings, the
API needs to provide the ability to query the number (really index) of
the window/tabpage.

This is needed for neovim/python-client#87, as discussed in
neovim/neovim#1898.

Signed-off-by: James McCoy <jamessan@jamessan.com>
2016-10-04 14:34:35 -04:00