| Commit message (Collapse) | Author | Age |
|
|
|
|
|
|
|
|
|
| |
- Add event loop abstraction module under src/nvim/event. The
src/nvim/event/loop module replaces src/nvim/os/event
- Remove direct dependency on libuv signal/timer API and use the new abstraction
instead.
- Replace all references to uv_default_loop() by &loop.uv, a new global variable
that wraps libuv main event loop but allows the event loop functions to be
reused in other contexts.
|
|
|
|
|
|
|
|
|
|
|
| |
- Add `kl_shift_at` macro and backing function. This can be used to shift
elements at arbitrary positions. `kl_shift` is now defined on top of the new
macro.
- Change shift/push API, now `kl_push` accepts an object as parameter and
`kl_shift` returns the object instead of a status. An assertion against
shifting at the end of a list(or empty lists) was added.
- Add `kl_iter` and `kl_iter_at` macros. `kl_iter_at` is for starting the
iteration at arbitrary positions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
abort() causes a bad exit; retry uv_loop_close() instead.
Before this change, this ruby script will cause nvim to abort() instead
of exiting cleanly:
```
require 'open3'
require 'base64'
Open3.popen3('nvim --embed -u -NONE') {|stdin, stdout, stderr, wait_thr|
# base64-encoded msgpack message for the vim_command "qa!".
stdin.write Base64.decode64('kwKrdmltX2NvbW1hbmSRo3FhIQ==')
puts wait_thr.value
}
```
References ##2663
Closes #2466
Closes #2648
Helped-by: Rui Abreu Ferreira <raf-ep@gmx.com>
|
|
|
|
|
| |
- "stdin" is misleading because it may read from stdout or stderr
- also remove some unused includes
|
|
|
|
|
|
| |
Klib pools were used to improve allocation efficiency for some small objects,
but it is not a thread-safe approach. Thread safety in allocations will be
required for implementing #2371).
|
|
|
|
|
|
|
|
|
| |
Reported by @fourjay, a codepath that causes event_poll() to run before
event_init() will trigger a segfault as the events list will not have
been initialized. Exiting immediately from event_init() causes nvim to
hang, so just exit before running the events.
fixes #2339
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
event_poll() always leaves the libuv I/O loop after one iteration. The
duration for how long the loop polls for I/O is given by the shortest
timeout of all active timers. Is no timer active, I/O is/could be polled
indefinitely.
To make sure our timer is still active when I/O polling begins,
a prepare handle is used to start the timer right before the polling.
But by only using a timer that restarts after its timeout was reached,
we also can assure that polling is done with (nearly) the same finite
timeout.
For a short explanation how the I/O loop is working, see
http://docs.libuv.org/en/latest/design.html#the-i-o-loop.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit integrates libvterm with Neovim and implements a terminal emulator
with nvim buffers as the display mechanism. Terminal buffers can be created
using any of the following methods:
- Opening a file with name following the "term://[${cwd}//[${pid}:]]${cmd}"
URI pattern where:
- cwd is the working directory of the process
- pid is the process id. This is just for use in session files where a pid
would have been assigned to the saved buffer title.
- cmd is the command to run
- Invoking the `:terminal` ex command
- Invoking the `termopen` function which returns a job id for automating the
terminal window.
Some extra changes were also implemented to adapt with terminal buffers. Here's
an overview:
- The `main` function now sets a BufReadCmd autocmd to intercept the term:// URI
and spawn the terminal buffer instead of reading the file.
- terminal buffers behave as if the following local buffer options were set:
- `nomodifiable`
- `swapfile`
- `undolevels=-1`
- `bufhidden=hide`
- All commands that delete buffers(`:bun`, `:bd` and `:bw`) behave the same for
terminal buffers, but only work when bang is passed(eg: `:bwipeout!`)
- A new "terminal" mode was added. A consequence is that a new set of mapping
commands were implemented with the "t" prefix(tmap, tunmap, tnoremap...)
- The `edit` function(which enters insert mode) will actually enter terminal
mode if the current buffer is a terminal
- The `put` operator was adapted to send data to the terminal instead of
modifying the buffer directly.
- A window being resized will also trigger a terminal resize if the window
displays the terminal.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Removed term.c, term.h and term_defs.h
- Tests for T_* values were removed. screen.c was simplified as a
consequence(the best strategy for drawing is implemented in the UI layer)
- Redraw functions now call ui.c functions directly. Updates are flushed with
`ui_flush()`
- Removed all termcap options(they now return empty strings for compatibility)
- &term/&ttybuiltin options return a constant value(nvim)
- &t_Co is still available, but it mirrors t_colors directly
- Remove cursor tracking from screen.c and the `screen_start` function. Now the
UI is expected to maintain cursor state across any call, and reset it when
resized.
- Remove unused code
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Remove abstract_ui global, now it is always active
- Remove some terminal handling code
- Remove unused functions
- Remove HAVE_TGETENT/TERMINFO/TERMIOS/IOCTL #ifdefs
- Remove tgetent/terminfo from version.c
- Remove curses/terminfo dependencies
- Only start/stop termcap when starting/exiting the program
- msg_use_printf will return true if there are no attached UIs(
messages will be written to stdout)
- Remove `ex_winpos`(implement `:winpos` with `ex_ni`)
|
|
|
|
|
|
|
|
|
| |
Problem : Read from pointer after free @ {242, 391}.
Diagnostic : Real issues.
Rationale : Channel gets indeed freed on error case, producing
incorrect accesses to freed pointer later on.
Resolution : Implement reference counting mechanism to know when to free
channel.
|
|
|
|
|
|
|
| |
Two new functions, `event_enable_deferred()`/`event_disable_deferred()` have to
be called by code that is capable of handling asynchronicity. User-dialog states
like "press ENTER to continue" or the swap file confirmation no longer will
generate K_EVENT.
|
| |
|
|
|
|
|
| |
Travis build will now fail when core files are dumped, so call `abort()` when
the event loop is not fully released before exiting.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
- Add input_teardown/signal_teardown to take care of closing signal/stdin
handles.
- Call those functions in event_teardown, and ensure there are no active handles
by entering an infinite loop when there are unclosed handles(think of this as
an assertion that can't go unoticed on travis).
- Move event_teardown call to the end of mch_exit. That is required because
event_poll may still be called in that function.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit @264e0d872c("Remove automatic event deferral") removed the immediate
event queue because event deferral now had to be explicit. The problem is that
while some events don't need to be deferred, they still can result in recursive
`event_poll` calls, and recursion is not supported by libuv. Examples of those
are msgpack-rpc requests while a server->client request is pending, or signals
which can call `mch_exit`(and that will result in `uv_run` calls).
To fix the problem, this reintroduces the immediate event queue for events that
can potentially result in event loop recursion. The non-deferred events are
still processed in `event_poll`, but only after `uv_run` returns.
|
| |
|
|
|
|
|
|
| |
- Rename WriteData to WRequest
- Inline uv_write_t into WRequest, avoiding an extra allocation
- Manage WBuffer/WRequest instances using klib memory pools
|
|
|
|
|
|
|
| |
A pattern that is becoming common across the project is to poll for events until
a certain condition is true, optionally passing a timeout. To address this
scenario, the event_poll_until macro was created and the job/channel/input
modules were refactored to use it on their blocking functions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is how asynchronous events are currently handled by Nvim:
- Libuv event loop is entered when Nvim blocks for user input(os_inchar is
called)
- Any event delivered by libuv that is not user input is queued for processing
- The `K_EVENT` special key code is returned by os_inchar
- `K_EVENT` is returned to a loop that is reading keys for the current Nvim
mode, which will be handled by calling event_process()
This approach has the advantage of integrating nicely with the current
codebase, eg: vimscript code can be executed asynchronously with little
surprises(Its the same as if the user typed a key).
The problem with using keys to represent any event is that it also interferes with
operators, and not every event needs or should do that. For example, consider
this scenario:
- A msgpack-rpc client calls vim_feedkeys("d")
- Nvim processes K_EVENT, pushing "d" to the input queue
- Nvim processes "d", entering operator-pending mode to wait for a motion
- The client calls vim_feedkeys("w"), expecting Nvim to delete a word
- Nvim processes K_EVENT, breaking out of operator-pending and pushing "w"
- Nvim processes "w", moving a word
This commit fixes the above problem by removing all automatic calls to
`event_push`(which is what generates K_EVENT input). Right now this also breaks
redrawing initiated by asynchronous events(and possibly other stuff too, Nvim is
a complex state machine and we can't simply run vimscript code anywhere).
In future commits the calls to `event_push` will be inserted only where it's
absolutely necessary to run code in "key reading loops", such as when executing
vimscript code or mutating editor data structures in ways that currently can
only be done by the user.
|
|
|
|
|
|
| |
This approach is more flexible because we don't need to support a fixed set of
"event types", any module can push events to be handled in main loop by simply
passing a callback to the Event structure.
|
|
|
|
|
| |
Create the msgpack_rpc subdirectory and move all modules that deal with
msgpack-rpc to it. Also merge msgpack_rpc.c into msgpack_rpc/helpers.c
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Remove all *_set_defer methods and the 'defer' flag from rstream/jobs
- Added {signal,rstream,job}_event_source functions. Each return a pointer that
represent the event source for the object in question(For signals, a static
pointer is returned)
- Added a 'source' field to the Event struct, which is set to the appropriate
value by the code that created the event.
- Added a 'sources' parameter to `event_poll`. It should point to a
NULL-terminated array of event sources that will be used to decide which
events should be processed immediately
- Added a 'source_override' parameter to `rstream_new`. This was required to use
jobs as event sources of RStream instances(When "focusing" on a job, for
example).
- Extracted `process_from` static function from `event_process`.
- Remove 'defer' parameter from `event_process`, which now operates only on
deferred events.
- Refactor `channel_send_call` to use the new lock mechanism
What changed in a single sentence: Code that calls `event_poll` have to specify
which event sources should NOT be deferred. This change was necessary for a
number of reasons:
- To fix a bug where due to race conditions, a client request
could end in the deferred queue in the middle of a `channel_send_call`
invocation, resulting in a deadlock since the client process would never
receive a response, and channel_send_call would never return because
the client would still be waiting for the response.
- To handle "event locking" correctly in recursive `channel_send_call`
invocations when the frames are waiting for responses from different
clients. Not much of an issue now since there's only a python client, but
could break things later.
- To simplify the process of implementing synchronous functions that depend on
asynchronous events.
|
|
|
|
|
|
| |
Also changed the default log level to INFO so developers won't end up with big
log files without asking explicitly(DLOG statements were placed in really "hot"
code)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Introducing the concept of providers: co-processes that talk with the editor
through the remote API and provide implementation for one or more core
services.
The `provider_register` function and it's API wrapper can be used by channels
that want to self-register as a service provider.
Some old builtin vim features will be re-implemented as providers. The
`provider_has_feature` function is used to check if a provider
implementing a certain feature is available(It will be called by the `has`
vimscript function to check for features in a vim-compatible way)
This implements the provider module without exposing any extension points, which
will be done in future commits.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`-Wstrict-prototypes` warn if a function is declared or defined without
specifying the argument types.
This warning disallow function prototypes with empty parameter list.
In C, a function declared with an empty parameter list accepts an
arbitrary number of arguments when being called. This is for historic
reasons; originally, C functions didn't have prototypes, as C evolved
from B, a typeless language. When prototypes were added, the original
typeless declarations were left in the language for backwards
compatibility.
Instead we should provide `void` in argument list to state
that function doesn't have arguments.
Also this warning disallow declaring type of the parameters after the
parentheses because Neovim header generator produce no declarations for
old-stlyle prototypes: it expects to find `{` after prototype.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This was done to generalize the usage of `event_poll`, which will now return
`true` only if a event has been processed/deferred before the timeout(if not
-1).
To do that, the `input_ready` calls have been extracted to the input.c
module(the `event_poll` call has been surrounded by `input_ready` calls,
resulting in the same behavior).
The `input_start`/`input_stop` calls still present in `event_poll` are
temporary: When the API becomes the only way to read user input, it will no
longer be necessary to start/stop the input stream.
|
|
|
|
|
| |
The loop condition was set to only exit when user input is processed, but we
must exit on any event to properly notify `event_poll` callers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
To make it possible reuse `event_poll` recursively and in other blocking
function calls, this changes how deferred/immediate events are processed:
- There are two queues in event.c, one for immediate events and another for
deferred events. The queue used when pushing/processing events is determined
with boolean arguments passed to `event_push`/`event_process` respectively.
- Events pushed to the immediate queue are processed inside `event_poll` but
after the `uv_run` call. This is required because libuv event loop does not
support recursion, and processing events may result in other `event_poll`
calls.
- Events pushed to the deferred queue are processed later by calling
`event_process(true)`. This is required to "trick" vim into treating all
asynchronous events as special keypresses, which is the least obtrusive
way of introducing asynchronicity into the editor.
- RStream instances will now forward the `defer` flag to the `event_push` call.
|
| |
|
| |
|
|
|
|
| |
So that they do the last nvim/func_attr.h include
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- The 'stripdecls.py' script replaces declarations in all headers by includes to
generated headers.
`ag '#\s*if(?!ndef NEOVIM_).*((?!#\s*endif).*\n)*#ifdef INCLUDE_GENERATED'`
was used for this.
- Add and integrate gendeclarations.lua into the build system to generate the
required includes.
- Add -Wno-unused-function
- Made a bunch of old-style definitions ANSI
This adds a requirement: all type and structure definitions must be present
before INCLUDE_GENERATED_DECLARATIONS-protected include.
Warning: mch_expandpath (path.h.generated.h) was moved manually. So far it is
the only exception.
|
|
|
|
| |
Prepend 'nvim/' in all project-local (non-system) includes.
|
|
Move files from src/ to src/nvim/.
- src/nvim/ becomes the new root dir for nvim executable sources.
- src/libnvim/ is planned to become root dir of the neovim library.
|