aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os/event.c
Commit message (Collapse)AuthorAge
* event loop: New abstraction layer with refactored time/signal APIThiago de Arruda2015-07-17
| | | | | | | | | | - 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.
* klib: Improve klist.hThiago de Arruda2015-07-01
| | | | | | | | | | | - 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.
* event_teardown(): retry uv_loop_close() instead of abort. #2903oni-link2015-06-25
| | | | | | | | | | | | | | | | | | | | | | | 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>
* input: rename input_{start,stop}_stdin()Justin M. Keyes2015-05-27
| | | | | - "stdin" is misleading because it may read from stdout or stderr - also remove some unused includes
* memory: Replace klib memory pools by malloc/freeThiago de Arruda2015-04-12
| | | | | | 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).
* event: Only process if event_init has been run.Scott Prager2015-04-08
| | | | | | | | | 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.c: Simplify timer use in event_poll()oni-link2015-04-08
| | | | | | | | | | | | | | | | | 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.
* terminal: New module that implements a terminal emulatorThiago de Arruda2015-03-25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* event: Ensure the loop is stopped when a event is pushed.Thiago de Arruda2015-03-25
|
* refactor: Remove term modules and termcap optionsThiago de Arruda2015-02-21
| | | | | | | | | | | | | | | - 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
* ui: Remove/adapt some old code for a big UI refactorThiago de Arruda2015-02-16
| | | | | | | | | | | | | - 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`)
* coverity/{68484,68485}: Read from pointer after free: RI.Thiago de Arruda2015-02-11
| | | | | | | | | 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.
* event: No longer process K_EVENT automaticallyThiago de Arruda2014-11-21
| | | | | | | 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.
* Remove os/provider.{c,h} and all of its referencesThiago de Arruda2014-11-18
|
* event: Assert that all libuv handles are closed on exit.Thiago de Arruda2014-11-03
| | | | | Travis build will now fail when core files are dumped, so call `abort()` when the event loop is not fully released before exiting.
* event: Do an early return from event_teardown when not initializedThiago de Arruda2014-11-03
|
* event: Ensure the event loop has been cleaned up in event_teardownThiago de Arruda2014-11-02
| | | | | | | | | | - 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.
* event: Reintroduce the immediate event queueThiago de Arruda2014-11-02
| | | | | | | | | | | | | 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.
* event: Rename pending_events to deferred_eventsThiago de Arruda2014-11-02
|
* wstream: Memory allocation improvementsThiago de Arruda2014-11-02
| | | | | | - Rename WriteData to WRequest - Inline uv_write_t into WRequest, avoiding an extra allocation - Manage WBuffer/WRequest instances using klib memory pools
* event: Extract event_poll loops to `event_poll_until` macroThiago de Arruda2014-10-21
| | | | | | | 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.
* event: Remove automatic event deferallThiago de Arruda2014-10-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* event: Remove EventType enum and pass a callback to `event_push`Thiago de Arruda2014-10-21
| | | | | | 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.
* msgpack-rpc: Create subdirectory for msgpack-rpc modulesThiago de Arruda2014-10-21
| | | | | 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
* events: Refactor how event deferral is handledThiago de Arruda2014-07-17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - 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.
* api/events/msgpack: Insert log statements to improve debuggingThiago de Arruda2014-07-17
| | | | | | 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)
* provider: New module used to expose extension points for core servicesThiago de Arruda2014-07-17
| | | | | | | | | | | | | | | | | 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.
* Use strict function prototypes #945Pavel Platto2014-07-14
| | | | | | | | | | | | | | | | | | | `-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.
* move assert.h include out of vim.hBrandon Coleman2014-07-09
|
* event: Decouple user input checks from `event_poll`Thiago de Arruda2014-06-24
| | | | | | | | | | | | | | 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.
* event: Bail out of event_poll when any event is processedThiago de Arruda2014-06-24
| | | | | 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
* events: Refactor how events are queued for processingThiago de Arruda2014-06-18
| | | | | | | | | | | | | | | | | | 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.
* events: Refactor event_poll to use stack-allocated timer handlesThiago de Arruda2014-06-18
|
* spelling fixes #827Will Stamper2014-06-12
|
* Make nvim/lib/k*.h headers be the last one in the listZyX2014-06-02
| | | | So that they do the last nvim/func_attr.h include
* Add automatic generation of headersZyX2014-06-02
| | | | | | | | | | | | | | | | | - 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.
* Introduce nvim namespace: Fix project-local includes.Eliseo Martínez2014-05-15
| | | | Prepend 'nvim/' in all project-local (non-system) includes.
* Introduce nvim namespace: Move files.Eliseo Martínez2014-05-15
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.