New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] api: nvim_get_mode() #6247

Merged
merged 4 commits into from Apr 28, 2017

Conversation

Projects
None yet
5 participants
@justinmk
Member

justinmk commented Mar 10, 2017

Until now, asynchronous API functions never flush the input queue. nvim_get_mode() is different:

  • if RPCs are known to be blocked, it responds immediately (without flushing the input/event queue)
  • else it flushes the input/event queue in order to determine whether pending input would cause RPCs to block, then responds with the result

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 function.

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

Note that this PR doesn't address #6166, and nvim_get_mode() will provoke #6166 if e.g. d is operator-pending. That will be the next thing I look at.

Comments from anyone who groks the event loop (@bfredl @tarruda @oni-link) would be very welcome.

Closes #6159
cc @lunixbochs

@justinmk justinmk changed the title from api: nvim_get_mode() to [WIP/RFC] api: nvim_get_mode() Mar 10, 2017

char buf[256] = { 0 };
memcpy(buf, method->via.bin.ptr, MIN(255, method->via.bin.size));
bool is_get_mode = strcmp("nvim_get_mode", buf) == 0;
handler.async = is_get_mode && input_blocking();

This comment has been minimized.

@justinmk

justinmk Mar 10, 2017

Member

special case nvim_get_mode: If we know RPC will be blocked, it can (and must) be asynchronous.

&& !(events_enabled || input_ready() || input_eof)
) {
blocking = true;
multiqueue_process_events(main_loop.events);

This comment has been minimized.

@justinmk

justinmk Mar 10, 2017

Member

We found out that the pending input will provoke a blocking wait, so here we process queued events (which may include the synchronous nvim_get_mode) once before blocking.

@tarruda

This comment has been minimized.

Member

tarruda commented Mar 10, 2017

It's been quite some time since I looked through the code, so I may be missing something and if so, please let me know.

I don't think I understand this PR, why do you need a function marked with FUNC_API_ASYNC to be sync in some cases? If the goal is simply allow embedder to determine the current editor mode (and I assume the reason for that is to know if a certain request would block) why do you need to flush the input buffer?

{
return (size_t)(buf->end_ptr - buf->start_ptr);
}

size_t rbuffer_space(RBuffer *buf) FUNC_ATTR_NONNULL_ALL
size_t rbuffer_space(RBuffer *buf)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE

This comment has been minimized.

@tarruda

tarruda Mar 10, 2017

Member

Are you sure it is safe to mark these functions as pure? Considering RBuffer is used by both the main thread and the ui thread, the compiler may not be able to when RBuffer is changed by another thread.

This comment has been minimized.

@justinmk

justinmk Mar 10, 2017

Member

Thanks for mentioning that. I didn't know that pure is not allowed to be used if the parameter is used by multiple threads, that makes it extremely difficult to ever know if a function can safely be marked pure. @ZyX-I can you confirm?

This comment has been minimized.

@tarruda

tarruda Mar 10, 2017

Member

Maybe the compiler will consider the memory as changed if we use locks to access RBuffer(which we do, if I remember correctly), but then this attribute won't be of much help. In any case, since the computation is very trivial, it is better to be safe than sorry(trying to debug it in a far future, where we forgot about this)

This comment has been minimized.

@justinmk

justinmk Mar 10, 2017

Member

Agreed, I'll remove this change. Just curious for future reference, though.

@justinmk

This comment has been minimized.

Member

justinmk commented Mar 10, 2017

If the goal is simply allow embedder to determine the current editor mode (and I assume the reason for that is to know if a certain request would block) why do you need to flush the input buffer?

That is the goal, in particular the RPC client needs to know if the next synchronous RPC will block. There could be input in the queue which wasn't flushed yet, which will cause the next synchronous to RPC block. For example:

nvim_input('g')
nvim_get_mode()      // "g" hasn't been processed yet
nvim_command('foo')  // this will block

In the above sequence, if nvim_get_mode() does not flush the input queue, it will incorrectly return blocking=false. Based on that result, the client thinks it can safely call nvim_command()... but in fact it will be blocked after the "g" input is flushed.

For single-threaded clients like actualvim, this is a problem because user input is sent by the client. If the client is blocked then it's stuck.

Another use-case is the neovim test suite: currently the tests have no way to detect a press-enter prompt before it happens.

static bool input_poll(int ms)
{
if (do_profiling == PROF_YES && ms) {
prof_inchar_enter();
}

if ((ms == - 1 || ms > 0)
&& !(events_enabled || input_ready() || input_eof)

This comment has been minimized.

@tarruda

tarruda Mar 10, 2017

Member

Because it has been quite some time since I've maintained this code, I'm not sure what are the implications of adding this multiqueue_process_events() call, but consider that input_poll is called no matter what state nvim is in, so it may not be safe to process events.

In any case, this condition is the same as (ms == - 1 || ms > 0) && !events_enabled && !input_ready() && !input_eof, but input_ready() cannot be true for this function to be called(See input_poll below), so it could be simplified to (ms == - 1 || ms > 0) && !events_enabled && !input_eof

This comment has been minimized.

@justinmk

justinmk Mar 10, 2017

Member

I was afraid of that. The only other option I can think of is to manage the nvim_get_mode requests in a child queue, and then process only those calls here. E.g.

channel_process_safe_events()

or something like that. And that would iterate through nvim_get_mode events.

I thought maybe main_loop.fast_events could be used for this purpose somehow, but didn't have success.

@tarruda

This comment has been minimized.

Member

tarruda commented Mar 10, 2017

There could be input in the queue which wasn't flushed yet, which will cause the next synchronous to RPC block.

OK I understand the issue now. Even so, I'm unsure if this is the best approach.

When I started the pushdown automaton refactor(@8d93621c6368fb6e3e3f7138bff50e08585f347b), the goal was to add explicit support for K_EVENT in more states, in the hopes we can eventually remove FUNC_ATTR_ASYNC. Maybe we can try to follow this direction instead?

For now I suggest to investigate the amount of work required to add support for K_EVENT to the various operator pending modes(assuming operator pending is the main source of problems here), and if it is a lot of work, try to create a plan for refactoring. I actually had a lot of ideas on how to remodel the code to make this easier, but I need to refresh memory first before elaborating further.

@justinmk

This comment has been minimized.

Member

justinmk commented Mar 10, 2017

I didn't forget about the K_EVENT refactoring intentions, but that's a high-risk task. Adding a new API function is much lower risk, and also forward-compatible with whatever future refactoring may occur.

We also need to un-block https://github.com/lunixbochs/actualvim (and who-knows-what else: this has been a known issue for ~2 years).

@justinmk

This comment has been minimized.

Member

justinmk commented Mar 10, 2017

Any comments on #6247 (comment) ? Could fast_events be leveraged somehow?

@tarruda

This comment has been minimized.

Member

tarruda commented Mar 10, 2017

I didn't forget about the K_EVENT refactoring intentions, but that's a high-risk task. Adding a new API function is much lower risk, and also forward-compatible with whatever future refactoring may occur.

It may not be as high-risk as you think, I actually had written down a plan on how to incrementally move vim implicit modes into the state_enter loop(the plan is written in the commit message for(@8d93621). In fact, I think it is safer to create an explicit states for some of the operator-pending modes than to process events in API calls marked as async.

Any comments on #6247 (comment) ? Could fast_events be leveraged somehow?

I'm currently doing some reading on the code and on the related issues to refresh my memory and will come back with a response later today.

@lunixbochs

This comment has been minimized.

lunixbochs commented Mar 10, 2017

ActualVim will now detect and use this function if available. It works great for me, and is reliably faster than my heuristic method.

lunixbochs/ActualVim@8a21e68#diff-b00fc497b0226e8afc26fccf90e2c4b0R300

@tarruda

This comment has been minimized.

Member

tarruda commented Mar 13, 2017

A small update: I'm currently working on a PR that aims to fix #6166/#6159 by doing a ambitious refactoring of normal mode, but still need some days before have something to show. This is something I had planned in 2015 but ended up never finishing, and reading the code on friday/saturday helped me refresh my memory.

It is not the simple refactoring I commented about, but I strongly believe it is the best solution for all problems related to async integration with nvim's main loop(it might even allow removing the distinction between immediate/deferred RPC calls in the short term). It is also something that will greatly help in cleaning up some other very old pieces of code.

Right now it is hard to estimate how many more days I need to finish this, but I will have another update by the end of the week.

@justinmk justinmk force-pushed the justinmk:api branch from b8cccbe to 8bfe8ec Mar 14, 2017

@justinmk justinmk changed the title from [WIP/RFC] api: nvim_get_mode() to [RFC] api: nvim_get_mode() Mar 14, 2017

@marvim marvim added the RFC label Mar 14, 2017

@justinmk justinmk force-pushed the justinmk:api branch from 8bfe8ec to 0707650 Mar 14, 2017

@justinmk

This comment has been minimized.

Member

justinmk commented Mar 14, 2017

@tarruda That is great news.

I pushed an update to this PR that abuses Event.priority so that input_poll() only processes async events. That should be safe, right?

If that is sound I'm thinking we should merge this and can remove the ugly stuff once the pretty stuff is ready.

@justinmk justinmk force-pushed the justinmk:api branch 2 times, most recently from dc3bac5 to ebfe49d Mar 14, 2017

char* buf = get_mode();
bool blocked = input_blocking();

ADD(rv, STRING_OBJ(cstr_to_string(buf)));

This comment has been minimized.

@oni-link

oni-link Mar 14, 2017

Contributor

cstr_as_string() should be used to prevent leaking the buf string.

@tarruda

This comment has been minimized.

Member

tarruda commented Mar 14, 2017

I pushed an update to this PR that abuses Event.priority so that input_poll() only processes async events. That should be safe, right?

It is difficult to tell with certainty. Apparently it is safe, but I think it is irrelevant.

I suspect solution implemented here doesn't work. If I understood correctly, you are trying to ensure nvim_get_mode is only handled after nvim main loop has fully processed all pending input, but the code you added here doesn't seem to guarantee that. Let's consider the example you gave before:

nvim_input('g')
nvim_get_mode()      // "g" hasn't been processed yet
nvim_command('foo')  // this will block

Imagine the following chain of events:

  • Nvim calls os_inchar to wait for input or events
  • RPC for nvim_input is received, which is handled immediately by posting data to the input buffer

What happens next depends on OS races that are out of our control. The two possible scenarios are:

  • The OS buffered nvim_get_mode before libuv poll returns to process nvim_input. In this case, nvim_get_mode will be processed in the same loop as nvim_input.
  • The OS buffered nvim_get_mode after libuv poll returns to process nvim_input. In this case, nvim_get_mode will be processed in the next os_inchar call.

The only way you will get the result you expect(nvim_get_mode returns the correct mode, which is pending 'g' command), is in the second scenario, but calling multiqueue_process_event is irrelevant since the queue will be empty in any of the two situations. Not only the processing of nvim_input happened before nvim_get_mode, but even if it was after, processing nvim_input would simply put data to input buffer, not force the main loop to process it.

I could be missing something, of course(again, it has been a long time :)), but my theory can be verified by making sure that the requests for nvim_input and nvim_get_mode are written to nvim pipe in a single batch(assuming the OS pipe buffer is large enough, which is probably true).

Note: Right now Event.priority is not used, and if I remember correctly it was created it before the parent/child queue concept, which gives a better way to selectively process events. The reason Event.priority still exists is because forgot to remove it, so it should be removed it in a future PR.

@justinmk

This comment has been minimized.

Member

justinmk commented Mar 14, 2017

The only way you will get the result you expect(nvim_get_mode returns the correct mode, which is pending 'g' command), is in the second scenario, but calling multiqueue_process_event is irrelevant since the queue will be empty in any of the two situations.

It can't be irrelevant, because commenting out that line (multiqueue_process_priority in the latest commit) in input.c causes the tests to hang (at the nvim_get_mode RPC call--i.e. #6159)--which is exactly the thing the tests are verifying. And the queue definitely isn't empty, this can be observed by adding ILOG in multiqueue_process_priority to see the processed event(s).

Regarding scenario 1:

The OS buffered nvim_get_mode before libuv poll returns to process nvim_input. In this case, nvim_get_mode will be processed in the same loop as nvim_input.

In that case IIUC nvim_get_mode() will return blocking=false, but the input will block. Right? Which means in that scenario (which hasn't been observed in the tests, yet) the worst that can happen is what already happens 100% of the time on current master.

@justinmk justinmk force-pushed the justinmk:api branch from 150b235 to 36a7d3d Mar 14, 2017

@justinmk

This comment has been minimized.

Member

justinmk commented Mar 14, 2017

my theory can be verified by making sure that the requests for nvim_input and nvim_get_mode are written to nvim pipe in a single batch(assuming the OS pipe buffer is large enough, which is probably true).

Confirmed. If nvim_get_mode is batched with a blocking nvim_input, it incorrectly returns blocked=false. Demonstrated via nvim_call_atomic:

36a7d3d#diff-5bf434f0a1fee647b4b121473e3410bfR280

@tarruda

This comment has been minimized.

Member

tarruda commented Mar 14, 2017

It can't be irrelevant, because commenting out that line in input.c causes the tests to hang (at the nvim_get_mode RPC call--i.e. #6166).

Maybe because of the logic you added that makes nvim_get_mode not be an async call in some situations?

@justinmk

This comment has been minimized.

Member

justinmk commented Mar 14, 2017

Maybe because of the logic you added that makes nvim_get_mode not be an async call in some situations?

Well, yes. And the purpose of that logic is to flush the input queue. If input_blocking() is false and there is pending input, asynchronous nvim_get_mode is useless.

@tarruda

This comment has been minimized.

Member

tarruda commented Mar 14, 2017

Which means in that scenario (which hasn't been observed in the tests, yet) the worst that can happen is what already happens 100% of the time on current master.

True, but why add an API whose purpose is to test if the next call would block, but that has a possibility of returning wrong information? If the user can't rely on the return value 100% of times, he will probably not use it.

Even if you still want to add an API that allows the user to sometimes know if the next call would block, I think there's a much simpler way: You can implement a function marked as ASYNC that returns the state of the events_enabled variable.

Here's an example(patch to master):

diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index bf11795..fcd20a7 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -127,6 +127,12 @@ Integer nvim_input(String keys)
   return (Integer)input_enqueue(keys);
 }

+Boolean nvim_can_process_events(void)
+  FUNC_API_ASYNC
+{
+  return input_events_enabled();
+}
+
 /// Replaces any terminal codes with the internal representation
 ///
 /// @see replace_termcodes
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c
index 5f0f2ec..d454750 100644
--- a/src/nvim/os/input.c
+++ b/src/nvim/os/input.c
@@ -165,6 +165,11 @@ void input_disable_events(void)
   events_enabled--;
 }

+bool input_events_enabled(void)
+{
+  return events_enabled;
+}
+
 /// Test whether a file descriptor refers to a terminal.
 ///
 /// @param fd File descriptor.
@justinmk

This comment has been minimized.

Member

justinmk commented Mar 15, 2017

@tarruda Does 303897b look right? Doesn't seem to work.

@justinmk justinmk force-pushed the justinmk:api branch from 36510c9 to 303897b Mar 15, 2017

@tarruda

This comment has been minimized.

Member

tarruda commented Mar 16, 2017

@tarruda Does 303897b look right? Doesn't seem to work.

I will have a look

justinmk added some commits Mar 13, 2017

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
input.c: Process only safe events before blocking.
Introduce multiqueue_process_priority() to process only events at or
above a certain priority.
event: Remove "priority" concept.
It was replaced by the "child queue" concept (MultiQueue).

@justinmk justinmk force-pushed the justinmk:api branch from 2c04c66 to 8f59d14 Apr 28, 2017

@justinmk

This comment has been minimized.

Member

justinmk commented Apr 28, 2017

@lunixbochs I changed the result of nvim_get_mode to be a dictionary:

{ "mode": String, "blocking": Boolean }

@justinmk justinmk merged commit 129f107 into neovim:master Apr 28, 2017

4 checks passed

QuickBuild Build pr-6247 finished with status SUCCESSFUL
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
coverage/coveralls Coverage increased (+0.02%) to 76.312%
Details

@justinmk justinmk deleted the justinmk:api branch Apr 28, 2017

@justinmk justinmk removed the RFC label Apr 28, 2017

justinmk added a commit to justinmk/neovim that referenced this pull request May 1, 2017

NVIM v0.2.0
FEATURES:
    bc4a2e1 help, man.vim: "outline" (TOC) feature neovim#5169
    58422f1 'guicursor' works in the TUI (and sends info to UIs) neovim#6423
    129f107 api: nvim_get_mode() neovim#6247
    0b59f98 api/ui: externalize tabline neovim#6583
    bc6d868 'listchars': `Whitespace` highlight group neovim#6367
    6afa7d6 writefile() obeys 'fsync' option neovim#6427
    c60e409 eval.c refactor (also improves some error messages) neovim#5119
    9d200cd getcompletion("cmdline") neovim#6376
    2ea7bfc terminal: Support extra arguments in 'shell'. neovim#4504
    bf51102 DirChanged autocmd neovim#5928 neovim#6262
    1743df8 'cpoptions': "_" flag to toggle `cw` behaviour neovim#6235
    22337b1 CTRL-R omits trailing ^M when pasting to cmdline neovim#6137
    0e44916 :edit allows unescaped spaces in filename neovim#6119
    abdbfd2 eval: Add id() function and make printf("%p") useful neovim#6095
    bdfa147 findfile(), :find, gf work in :terminal. neovim#6009
    2f38ed1 providers: Disable if `g:loaded_*` exists.
    b5560a6 setpos() can set lowercase marks in other buffers neovim#5753
    7c513d6 Throttle :! output, pulse "..." message. neovim#5396
    d2e8c76 v:exiting neovim#5651

    :terminal improvements neovim#6185 neovim#6142
      - cursor keeps position after leaving insert-mode.
      - 4ceec30 Follows output only if cursor is at end of buffer.
      - e7bbd35 new option: 'scrollback'
      - fedb844 quasi-support for undo and 'modifiable'
      - b45ddf7 disables 'list' by default
      - disables 'relativenumber' by default

    :help now contains full API documentation at `:help api`.

    man.vim saw numerous improvements.

    Windows support:
      - Windows is no longer "experimental", it is fully supported.
      - Windows package includes a GUI, curl.exe and other utilities.

    "Vim 8" features: partials, lambdas, packages.

FIXES:
    12fc1de ops: fix i<c-r> with multi-byte text neovim#6524
    dd391bf Windows: system() and friends neovim#6497
    13352c0 Windows: os_get_hostname() neovim#6413
    16babc6 tui: Less-noisy mouse seqs neovim#6411
    3a9dd13 (vim bug) folding edge-cases  neovim#6207
    f6946c6 job-control: set CLOEXEC on pty processes. neovim#5986
    d1afd43 rplugin: Call s:LoadRemotePlugins() on startup.
    1215084 backtick-expansion works with `shell=fish` neovim#6224
    e32ec03 tui: Improved behavior after resize. neovim#6202
    86c2adc edit.c: CTRL-SPC: Insert previously-inserted text. neovim#6090
    c318d8e b:changedtick now follows VimL rules neovim#6112
    34e24cb terminal: Initialize colors in reverse order neovim#6160
    e889917 undo: Don't set b_u_curhead in ex_undojoin() neovim#5869
    d25649f undo: :earlier, g-: Set b_u_seq_cur correctly. (neovim#6016)
    043d8ba 'Visual-mode put from @. register' neovim#5782
    42c922b open_buffer(): Do `BufEnter` for directories.
    50d0d89 inccommand: Preview :sub commands only after delimiter neovim#5932
    1420e10 CheckHealth improvements neovim#5519
    c8d5e92 jobstart(): Return -1 if cmd is not executable. neovim#5671

CHANGES:
    NVIM_TUI_ENABLE_CURSOR_SHAPE was removed. Use 'guicursor' instead.
        See https://github.com/neovim/neovim/wiki/Following-HEAD#20170402

    81525dc 'mouse=a' is no longer the default. (This will probably
                 change again after it is improved.) neovim#6022

    0c1f783 defaults: 'showcmd', 'belloff', 'ruler' neovim#6087
    eb0e94f api: {get,set}_option update local options as appropriate neovim#6405
    bdcb2a3 "Reading from stdin..." message was removed. neovim#6298

@justinmk justinmk referenced this pull request May 1, 2017

Merged

NVIM v0.2.0 #6634

justinmk added a commit to justinmk/neovim that referenced this pull request May 1, 2017

NVIM v0.2.0
FEATURES:
    bc4a2e1 help, man.vim: "outline" (TOC) feature neovim#5169
    58422f1 'guicursor' works in the TUI (and sends info to UIs) neovim#6423
    129f107 api: nvim_get_mode() neovim#6247
    0b59f98 api/ui: externalize tabline neovim#6583
    bc6d868 'listchars': `Whitespace` highlight group neovim#6367
    6afa7d6 writefile() obeys 'fsync' option neovim#6427
    c60e409 eval.c refactor (also improves some error messages) neovim#5119
    9d200cd getcompletion("cmdline") neovim#6376
    2ea7bfc terminal: Support extra arguments in 'shell'. neovim#4504
    bf51102 DirChanged autocmd neovim#5928 neovim#6262
    1743df8 'cpoptions': "_" flag to toggle `cw` behaviour neovim#6235
    22337b1 CTRL-R omits trailing ^M when pasting to cmdline neovim#6137
    0e44916 :edit allows unescaped spaces in filename neovim#6119
    abdbfd2 eval: Add id() function and make printf("%p") useful neovim#6095
    bdfa147 findfile(), :find, gf work in :terminal. neovim#6009
    2f38ed1 providers: Disable if `g:loaded_*` exists.
    b5560a6 setpos() can set lowercase marks in other buffers neovim#5753
    7c513d6 Throttle :! output, pulse "..." message. neovim#5396
    d2e8c76 v:exiting neovim#5651

    :terminal improvements neovim#6185 neovim#6142
      - cursor keeps position after leaving insert-mode.
      - 4ceec30 Follows output only if cursor is at end of buffer.
      - e7bbd35 new option: 'scrollback'
      - fedb844 quasi-support for undo and 'modifiable'
      - b45ddf7 disables 'list' by default
      - disables 'relativenumber' by default

    :help now contains full API documentation at `:help api`.

    man.vim saw numerous improvements.

    Windows support:
      - Windows is no longer "experimental", it is fully supported.
      - Windows package includes a GUI, curl.exe and other utilities.

    "Vim 8" features: partials, lambdas.

SECURITY FIXES:
    CVE-2017-5953 CVE-2017-6349 CVE-2017-6350 neovim#6485

CHANGES:
    NVIM_TUI_ENABLE_CURSOR_SHAPE was removed. Use 'guicursor' instead.
        See https://github.com/neovim/neovim/wiki/Following-HEAD#20170402

    81525dc 'mouse=a' is no longer the default. (This will probably
                 change again after it is improved.) neovim#6022

    0c1f783 defaults: 'showcmd', 'belloff', 'ruler' neovim#6087
    eb0e94f api: {get,set}_option update local options as appropriate neovim#6405
    bdcb2a3 "Reading from stdin..." message was removed. neovim#6298

FIXES:
    12fc1de ops: fix i<c-r> with multi-byte text neovim#6524
    dd391bf Windows: system() and friends neovim#6497
    13352c0 Windows: os_get_hostname() neovim#6413
    16babc6 tui: Less-noisy mouse seqs neovim#6411
    3a9dd13 (vim bug) folding edge-cases  neovim#6207
    f6946c6 job-control: set CLOEXEC on pty processes. neovim#5986
    d1afd43 rplugin: Call s:LoadRemotePlugins() on startup.
    1215084 backtick-expansion works with `shell=fish` neovim#6224
    e32ec03 tui: Improved behavior after resize. neovim#6202
    86c2adc edit.c: CTRL-SPC: Insert previously-inserted text. neovim#6090
    c318d8e b:changedtick now follows VimL rules neovim#6112
    34e24cb terminal: Initialize colors in reverse order neovim#6160
    e889917 undo: Don't set b_u_curhead in ex_undojoin() neovim#5869
    d25649f undo: :earlier, g-: Set b_u_seq_cur correctly. (neovim#6016)
    043d8ba 'Visual-mode put from @. register' neovim#5782
    42c922b open_buffer(): Do `BufEnter` for directories.
    50d0d89 inccommand: Preview :sub commands only after delimiter neovim#5932
    1420e10 CheckHealth improvements neovim#5519
    c8d5e92 jobstart(): Return -1 if cmd is not executable. neovim#5671

justinmk added a commit to justinmk/neovim that referenced this pull request May 1, 2017

NVIM v0.2.0
FEATURES:
    bc4a2e1 help, man.vim: "outline" (TOC) feature neovim#5169
    58422f1 'guicursor' works in the TUI (and sends info to UIs) neovim#6423
    129f107 api: nvim_get_mode() neovim#6247
    0b59f98 api/ui: externalize tabline neovim#6583
    bc6d868 'listchars': `Whitespace` highlight group neovim#6367
    6afa7d6 writefile() obeys 'fsync' option neovim#6427
    c60e409 eval.c refactor (also improves some error messages) neovim#5119
    9d200cd getcompletion("cmdline") neovim#6376
    2ea7bfc terminal: Support extra arguments in 'shell'. neovim#4504
    bf51102 DirChanged autocmd neovim#5928 neovim#6262
    1743df8 'cpoptions': "_" flag to toggle `cw` behaviour neovim#6235
    22337b1 CTRL-R omits trailing ^M when pasting to cmdline neovim#6137
    0e44916 :edit allows unescaped spaces in filename neovim#6119
    abdbfd2 eval: Add id() function and make printf("%p") useful neovim#6095
    bdfa147 findfile(), :find, gf work in :terminal. neovim#6009
    2f38ed1 providers: Disable if `g:loaded_*` exists.
    b5560a6 setpos() can set lowercase marks in other buffers neovim#5753
    7c513d6 Throttle :! output, pulse "..." message. neovim#5396
    d2e8c76 v:exiting neovim#5651

    :terminal improvements neovim#6185 neovim#6142
      - cursor keeps position after leaving insert-mode.
      - 4ceec30 Follows output only if cursor is at end of buffer.
      - e7bbd35 new option: 'scrollback'
      - fedb844 quasi-support for undo and 'modifiable'
      - b45ddf7 disables 'list' by default
      - disables 'relativenumber' by default

    :help now contains full API documentation at `:help api`.

    man.vim saw numerous improvements.

    Windows support:
      - Windows is no longer "experimental", it is fully supported.
      - Windows package includes a GUI, curl.exe and other utilities.

    "Vim 8" features: partials, lambdas.

SECURITY FIXES:
    CVE-2017-5953 CVE-2017-6349 CVE-2017-6350 neovim#6485

CHANGES:
    NVIM_TUI_ENABLE_CURSOR_SHAPE was removed. Use 'guicursor' instead.
        See https://github.com/neovim/neovim/wiki/Following-HEAD#20170402

    81525dc 'mouse=a' is no longer the default. (This will probably
                 change again after it is improved.) neovim#6022

    0c1f783 defaults: 'showcmd', 'belloff', 'ruler' neovim#6087
    eb0e94f api: {get,set}_option update local options as appropriate neovim#6405
    bdcb2a3 "Reading from stdin..." message was removed. neovim#6298

FIXES:
    12fc1de ops: fix i<c-r> with multi-byte text neovim#6524
    dd391bf Windows: system() and friends neovim#6497
    13352c0 Windows: os_get_hostname() neovim#6413
    16babc6 tui: Less-noisy mouse seqs neovim#6411
    3a9dd13 (vim bug) folding edge-cases  neovim#6207
    f6946c6 job-control: set CLOEXEC on pty processes. neovim#5986
    d1afd43 rplugin: Call s:LoadRemotePlugins() on startup.
    1215084 backtick-expansion works with `shell=fish` neovim#6224
    e32ec03 tui: Improved behavior after resize. neovim#6202
    86c2adc edit.c: CTRL-SPC: Insert previously-inserted text. neovim#6090
    c318d8e b:changedtick now follows VimL rules neovim#6112
    34e24cb terminal: Initialize colors in reverse order neovim#6160
    e889917 undo: Don't set b_u_curhead in ex_undojoin() neovim#5869
    d25649f undo: :earlier, g-: Set b_u_seq_cur correctly. (neovim#6016)
    043d8ba 'Visual-mode put from @. register' neovim#5782
    42c922b open_buffer(): Do `BufEnter` for directories.
    50d0d89 inccommand: Preview :sub commands only after delimiter neovim#5932
    1420e10 CheckHealth improvements neovim#5519
    c8d5e92 jobstart(): Return -1 if cmd is not executable. neovim#5671
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment