aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/state.c
Commit message (Collapse)AuthorAge
* vim-patch:8.2.3236: mode() does not indicate using CTRL-O in Select modezeertzjq2021-07-29
| | | | | | Problem: mode() does not indicate using CTRL-O in Select mode. Solution: Use "vs" and similar. (closes vim/vim#8640) https://github.com/vim/vim/commit/eaf3f36168f85c8e0ab7083cd996b9fbe937045d
* Remove EXMODE_NORMALmatveyt2021-07-23
|
* state: throttle batched event processing when input is availableBjörn Linse2021-03-08
| | | | | | | before, calling vim.schedule() from inside an event would execute the scheduled callback immediately after this event without checking for user input in between. Break event processing whenever user input or an interrupt is available.
* doc + extmarks tweaks #11421Justin M. Keyes2019-11-25
| | | | - nvim_buf_get_extmarks: rename "amount" => "limit" - rename `set_extmark_index_from_obj`
* refactor: allow us to process a child queue only while waiting on inputBjörn Linse2019-09-08
|
* log: log_key()Justin M. Keyes2019-08-27
|
* vim-patch:8.0.1480: patch missing changeJan Edmund Lazo2019-06-23
| | | | | | Problem: Patch missing change. Solution: Add missing change. https://github.com/vim/vim/commit/0562532c2eee6205d225aa1dc7e3e89af0dfd990
* vim-patch:8.1.0225: mode() does not indicate using CTRL-O from Insert mode ↵Justin M. Keyes2019-02-24
| | | | | | | (#9644) Problem: Mode() does not indicate using CTRL-O from Insert mode. Solution: Add "niI", "niR" and "niV" to mode() result. (closes vim/vim#3000) https://github.com/vim/vim/commit/612cc3888b136e80485132d9f997ed457dbc5501
* vim-patch:8.1.0648: custom operators can't act upon forced motionPedro L. Ramos2019-01-10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Custom operators can't act upon a forced motion. (Christian Wellenbrock) Solution: Add the forced motion to the mode() result. (Christian Brabandt, closes vim/vim#3490) https://github.com/vim/vim/commit/5976f8ff00efcb3e155a89346e44f2ad43d2405a closes #8667 closes #9476 Christian Wellenbrock: > For (most) built in text objects it's possible to force operation on > them to be linewise, for example by using `dVab` (`:h o_V`, > `motion_force`). When using custom text objects (defined as mappings > by plugins for example), this doesn't currently work. > > Example: > > onoremap x viw > > Open a file with a few lines each containing some words. With the > cursor on any word, try: > > 1. `dw` (builtin) deletes some characters > 2. `dVw` (builtin) deletes linewise > 3. `dx` (from mapping) deletes some characters > 4. `dVx` (from mapping) deletes some characters, but should delete > linewise ref: https://github.com/wellle/targets.vim/issues/214 ref: https://gitter.im/neovim/neovim?at=5b379ff7f1664406610e7483
* log: RPC, input, other eventsJustin M. Keyes2018-09-19
|
* globals: virtual_op is TriStateJan Edmund Lazo2018-08-01
|
* Merge #7587 'vim-patch:8.0.0283'Justin M. Keyes2017-11-19
|\
| * vim-patch:8.0.0283ckelsel2017-11-19
|/ | | | | | | | | Problem: The return value of mode() does not indicate that completion is active in Replace and Insert mode. (Zhen-Huan (Kenny) Hu) Solution: Add "c" or "x" for two kinds of completion. (Yegappan Lakshmanan, closes vim/vim#1397) Test some more modes. https://github.com/vim/vim/commit/e90858d0229444b3cd16b1cd3a8d61a24c435705
* doc: eventloopJustin M. Keyes2017-09-05
|
* eventloop: FocusGained: schedule event instead of pseudokeyJustin M. Keyes2017-09-05
| | | | | closes #4840 closes #6164
* terminal: block redraw during c_CTRL-DJustin M. Keyes2017-08-05
| | | | | | | | Unlike the normal wildmenu, the CTRL-D wild-list is not restored by statusline redraw. (Semantics: ^D is controlled by 'wildoptions' option, so it's in the "wild..." family.) TODO: externalize the c_CTRL-D wild-list.
* api: nvim_get_mode()Justin M. Keyes2017-04-28
| | | | | | | | | | | | | | | | | | | | | | | | | | 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
* *: Add comment to all C filesZyX2017-04-19
|
* event/multiqueue.c: Rename "queue" to "multiqueue".Justin M. Keyes2016-10-02
| | | | | | | | | | | | | | `lib/queue.h` implements a basic queue. `event/queue.c` implements a specialized data structure on top of lib/queue.h; it is not a "normal" queue. Rename the specialized multi-level queue implemented in event/queue.c to "multiqueue", to avoid confusion when reading the code. Before this change one can eventually notice that "macros (uppercase symbols) are for the normal queue, lowercase operations are for the multi-level queue", but that is unnecessary friction for new developers (or existing developers just visiting this part of the codebase).
* refactor: eliminate misc2.cJustin M. Keyes2016-09-13
| | | | | | | | | | move `call_shell` to misc1.c Move some fns to state.c Move some fns to option.c Move some fns to memline.c Move `vim_chdir*` fns to file_search.c Move some fns to new module, bytes.c Move some fns to fileio.c
* *: Rename main loop variable from loop to main_loopZyX2016-05-30
| | | | | | | | | | | | | | | | Current name is inappropriate for the following reasons: 1. It is often masked by local `loop` variables. 2. It cannot be searched for. There are many `loop` variables where `loop` is some local variable. There are many cases when “loop” word is used in a comment. 3. It is in any case bad idea to use a generic name as a name of the global variable. Best if global has module prefix: this is why it is in `main.h`: `main_loop` both stands for “a main loop” and “a loop defined in `main.*`”. Since I have no idea how to list every occurrence of this variable method used to rename it is “remove it from globals.h, try to compile, fix errors”. Thus if some occurrence was hidden under false `#if` branch it was not replaced.
* main: Start modeling Nvim as pushdown automatonThiago de Arruda2015-10-26
From a very high level point of view, Vim/Nvim can be described as state machines following these instructions in a loop: - Read user input - Peform some action. The action is determined by the current state and can switch states. - Possibly display some feedback to the user. This is not immediately visible because these instructions spread across dozens of nested loops and function calls, making it very hard to modify the state machine(to support more event types, for example). So far, the approach Nvim has taken to allow more events is this: - At the very core function that blocks for input, poll for arbitrary events. - If the event received from the OS is user input, just return it normally to the callers. - If the event is not direct result of user input(possibly a vimscript function call coming from a msgpack-rpc socket or a job control callback), return a special key code(`K_EVENT`) that is handled by callers where it is safer to perform arbitrary actions. One problem with this approach is that the `K_EVENT` signal is being sent across multiple states that may be unaware of it. This was partially fixed with the `input_enable_events`/`input_disable_events` functions, which were added as a mechanism that the upper layers can use to tell the core input functions that it is ready to accept `K_EVENT`. Another problem is that the mapping engine is implemented in getchar.c which is called from every state, but the mapping engine is not aware of `K_EVENT` so events can break mappings. While it is theoretically possible to modify getchar.c to make it aware of `K_EVENT`, this commit fixes the problem with a different approach: Model Nvim as a pushdown automaton(https://en.wikipedia.org/wiki/Pushdown_automaton). This design has many advantages which include: - Decoupling the event loop from the states reponsible for handling events. - Better control of state transition with less dependency on global variable hacks(eg: 'restart_edit' global variable). - Easier removal of global variables and function splitting. That is because many variables are for state-specific information, and probably ended up being global to simplify communication between functions, which we fix by storing state-specific information in specialized structures. The final goal is to let Nvim have a single top-level event loop represented by the following pseudo-code: ``` while not quitting let event = read_event current_state(event) update_screen() ``` This closely mirrors the state machine description above and makes it easier to understand, extend and debug the program. Note that while the pseudo code suggests an explicit stack of states that doesn't rely on return addresses(as suggested by the principles of automata-based programming: https://en.wikipedia.org/wiki/Automata-based_programming), for now we'll use the call stack as a structure to manage state transitioning as it would be very difficult to refactor Nvim to use an explicit stack of states, and the benefits would be small. While this change may seem like an endless amount of work, it is possible to do it incrementally as was shown in the previous commits. The general procedure is: 1- Find a blocking `vgetc()`(or derivatives) call. This call represents an implicit state of the program. 2- Split the code before and after the `vgetc()` call into functions that match the signature of `state_check_callback` and `state_execute_callback. Only `state_execute_callback` is required. 3- Create a `VimState` "subclass" and a initializer function that sets the function pointers and performs any other required initialization steps. If the state has no local variables, just use `VimState` without subclassing. 4- Instead of calling the original function containing the `vgetc()`, initialize a stack-allocated `VimState` subclass, then call `state_enter` to begin processing events in the state. 5- The check/execute callbacks can return 1 to continue normally, 0 to break the loop or -1 to skip to the next iteration. These callbacks contain code that execute before and after the old `vgetc()` call. The functions created in step 2 may contain other `vgetc()` calls. These represent implicit sub-states of the current state, but it is fine to remove them later in smaller steps since we didn't break compatibility with existing code.