Commit Graph

4300 Commits

Author SHA1 Message Date
Felipe Morales
04810c2b39 tutor: fix typo 2015-10-26 19:23:59 +01:00
Justin M. Keyes
77e93a65fe Merge pull request #3502 from ZyX-I/fix-xdg
option: Fix typos that may lead to SEGV in some cases
2015-10-26 12:48:42 -04:00
Thiago de Arruda
29d64a901d Merge PR #3413 'Refactor Neovim to remove the side effects of K_EVENT' 2015-10-26 11:24:51 -03:00
Thiago de Arruda
1726c7d999 edit.c: Fix one clint warning 2015-10-26 11:06:07 -03:00
Thiago de Arruda
b4c82dba5c Start documenting code 2015-10-26 10:52:02 -03:00
Thiago de Arruda
ed985d06ef ex_getln: Extract command_line_handle_key from command_line_execute 2015-10-26 10:52:02 -03:00
Thiago de Arruda
c0c562f97f ex_getln: Convert cmdline_{not_,}changed labels into functions 2015-10-26 10:52:02 -03:00
Thiago de Arruda
0701e1bfa4 ex_getln: refactor command line mode to use the state_enter loop
Split `getcmdline()` into command_line_{enter,check,execute}`
2015-10-26 10:52:02 -03:00
Thiago de Arruda
52d4978b03 ex_getln: Extract local variables from getcmdline() and fix code style
Begin refactoring getcmdline() into a state that can be managed by the
`state_enter()`:

- Move local variables into a local CommandLineState structure
- Fix code style in the entire function.
2015-10-26 10:52:02 -03:00
Thiago de Arruda
344bd64f96 terminal: Refactor to use state_enter
- Create `TerminalState` structure containing data used in terminal mode
- Extract `terminal_execute` from `terminal_enter` and use it with
  `state_enter`.
2015-10-26 10:52:02 -03:00
Thiago de Arruda
8890852cb7 edit: Extract some functions from insert_execute
- `insert_handle_key`: Contains the big insert mode switch statement.
- `insert_do_complete`: Code that used to be in the `docomplete` label.
- `insert_do_cindent`: Code that used to be in the `force_cindent` label.

Also move some code after the switch statement into the beginning of
`insert_check`.
2015-10-26 10:52:02 -03:00
Thiago de Arruda
091e7d033c edit: Move most code from edit() to insert_{enter,check,execute}
Refactor insert mode to use `state_enter` as an event loop:

- Move o_lnum(static variable) outside function
- Move code before the insert mode loop into `insert_enter`
- Move code before `safe_vgetc()` call into `insert_check`
- Move code after `safe_vgetc()` call into `insert_execute`
- Remove doESCkey label and handle insert mode repeating in the `insert_enter`
  function
- Remove do_intr label(this is not the place for platform-specific interrupt
  charts)
2015-10-26 10:52:02 -03:00
Thiago de Arruda
f5b333f532 edit: Extract local variables from edit() and fix code style
Begin refactoring edit() into a state that can be managed by the `state_enter()`:

- Move local variables into a local InsertState structure
- Fix code style in the entire function.
2015-10-26 10:52:01 -03:00
Thiago de Arruda
f1bc3e4c0c normal: Extract some functions from normal_finish_command
- `normal_need_redraw_mode_message`
- `normal_redraw_mode_message`
2015-10-26 10:52:01 -03:00
Thiago de Arruda
4c6e417d2a normal: Extract normal_finish_command from normal_execute 2015-10-26 10:52:01 -03:00
Thiago de Arruda
5abd25f6fb normal: Extract normal_get_command_count from normal_execute 2015-10-26 10:52:01 -03:00
Thiago de Arruda
0f0fae58b9 normal: Extract some functions from normal_execute
- `normal_handle_special_visual_command`
- `normal_need_aditional_char`
- `normal_get_additional_char`
- `normal_invert_horizontal`
2015-10-26 10:52:01 -03:00
Thiago de Arruda
fa83b03fea normal: Split normal_check into multiple functions
Split most code in `normal_check` in:

- `normal_check_stuff_buffer`
- `normal_check_interrupt`
- `normal_check_cursor_moved`
- `normal_check_text_changed`
- `normal_check_folds`
- `normal_redraw`
2015-10-26 10:52:01 -03:00
Thiago de Arruda
8d93621c63 main: Start modeling Nvim as pushdown automaton
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.
2015-10-26 10:52:01 -03:00
Thiago de Arruda
350ffc63db main: Refactor normal_enter to call os_inchar directly
This makes it impossible for K_EVENT to interfere with mappings, but it also
disables processing of events while in the middle of a mapping (Though this will
be fixed later as this refactoring progresses).

`may_sync_undo` is now called when K_EVENT is received. This is necessary to
correctly update undo entry lists before executing some action.
2015-10-26 10:52:01 -03:00
Thiago de Arruda
32594a33a3 main: Call normal_execute from normal_enter
`normal_prepare` is now called by `normal_check` before returning 1(to
continue).

Also remove `input_{enable,disable}_events` calls from `normal_cmd`, which only
exists now as a compatibility function to run normal commands with keys inserted
into the typeahead buffer(We don't want to process events in these cases
anyway).
2015-10-26 10:52:01 -03:00
Thiago de Arruda
e5165bae11 input: Remove CURSORHOLD key
Refactor input.c, normal.c and edit.c to use the K_EVENT special key to trigger
the CURSORHOLD event. In normal and edit mode, K_EVENT is treated as
K_CURSORHOLD, which enables better handling of arbitrary actions in those
states(eg: In normal mode the previous operator counts will be restored).

Also fix a test in vim_spec.lua. The test had a wrong assumption: cmdheight is
only used to determine when the press enter screen will be shown, not to limit
how many lines or control pagination.
2015-10-26 10:52:01 -03:00
Thiago de Arruda
d8055f8eab normal: Fix code style in normal_prepare and normal_execute
This was done separately to make it easier to follow the changes in the previous
commit.
2015-10-26 10:52:01 -03:00
Thiago de Arruda
82bb8c887c normal: Extract most normal_cmd logic into two functions
The new functions are `normal_prepare` and `normal_execute` which contain code
executed before and after input is received in normal mode.
2015-10-26 10:52:01 -03:00
Thiago de Arruda
dae006a942 main: Extract normal_check from main_loop
The new function contains logic that must be executed after handling input in
normal mode and also before the first main loop iteration. Also rename
`main_loop` to `normal_enter` and move it to normal.c
2015-10-26 10:52:01 -03:00
Thiago de Arruda
e596234fc2 test: Add more TUI tests and increase timeout 2015-10-26 10:52:01 -03:00
Justin M. Keyes
424b00ea61 Merge pull request #3507 from fmoralesc/fix-tutorial-1
tutor: fix location for init.vim file
2015-10-26 09:49:29 -04:00
Felipe Morales
c3f95ade91 tutor: fix location for init.vim file 2015-10-26 14:47:11 +01:00
ZyX
be6b784766 option: Fix strange condition in add_dir function 2015-10-26 14:51:56 +03:00
ZyX
89a84baaf9 option: Fix typos that may lead to SEGV in some cases 2015-10-26 14:49:03 +03:00
Justin M. Keyes
0f9dea2a0e vim-patch:7.4.849
Problem:    Moving the cursor in Insert mode starts new undo sequence.
Solution:   Add CTRL-G U to keep the undo sequence for the following
            cursor movement command. (Christian Brabandt)

8b5f65a527

Closes #3492
2015-10-26 02:23:59 -04:00
Justin M. Keyes
1ca5646bb5 Merge pull request #3470 from ZyX-I/pr-3198
XDG base directory specification support
2015-10-25 22:38:23 -04:00
ZyX
42047acb4f documentation: Update documentation regarding init.vim location 2015-10-24 04:35:14 +03:00
ZyX
157af47202 os/unix_defs: Rename default system vimrc file to sysinit.vim
This way all standard Vim file paths have .vim extension. VIMRC_FILE constant 
used for &exrc option was not touched.
2015-10-24 04:35:14 +03:00
ZyX
2b437e7102 main: Check init.vim files also in other XDG directories 2015-10-24 04:35:13 +03:00
Justin M. Keyes
de4cb766ca Merge pull request #3490 from ZyX-I/fix-3472
Fix local marks saving/restoring with ShaDa
2015-10-23 10:11:59 -04:00
ZyX
95979afc47 oldtests: Also set . as default directories for old tests 2015-10-23 17:04:26 +03:00
ZyX
e5537a935f functests: Fix tests 2015-10-23 15:56:51 +03:00
ZyX
6b17d35ff1 functests: Use . for various folder defaults in tests 2015-10-23 15:56:51 +03:00
ZyX
ec1ca54d59 functests: Do not forget about -i argument
Target: make all tests run with chmod -x ~/.config/nvim ~/.local/share/nvim.
2015-10-23 15:56:51 +03:00
ZyX
ca6235c20f *: Fix linter errors 2015-10-23 15:56:50 +03:00
ZyX
a8e18d9b5a memline: Automatically create swap file directory for last directory 2015-10-23 15:56:50 +03:00
ZyX
fefcc01cc1 os/fs: Allow os_mkdir_recurse directory name to end with /// 2015-10-23 14:54:11 +03:00
ZyX
030c608b7d option: Use memcnt for counting commas 2015-10-23 14:54:11 +03:00
ZyX
198ba323b8 stdpaths: Remove outdated comment 2015-10-23 14:54:11 +03:00
ZyX
25bb9c9f7d option: Silence “may be used unitialized” errors 2015-10-23 14:54:11 +03:00
ZyX
181c377697 stdpaths: Add Windows-specific directories 2015-10-23 14:54:11 +03:00
ZyX
b7732cceca functests: Fix 078_swapfile_recover test 2015-10-23 14:54:11 +03:00
ZyX
d2e07c8307 stdpaths: Add missing include 2015-10-23 14:54:11 +03:00
ZyX
8642bad122 shada: Remove SHADA_FILE2 2015-10-23 14:54:11 +03:00