VI Worsened, a lightweight and fun VI clone. Inspired by the 6-domino-cascade from the React world.
- gcc
- ncurses
# Fedora
sudo dnf install ncurses-devel
# Debian/Ubuntu
sudo apt-get install libncurses5-devgit clone https://github.com/lpan/viw
cd viw/
make build
./viw [filename]Using mingw compiler on Windows, you need to install mingw-w64-x86_64-ncurses
pacman -S mingw-w64-x86_64-ncurses
mingw32-make buildjCursor downkCursor uphCursor leftlCursor right0Cursor to the beginning of the line$Cursor to the end of the lineiInsert beforeIInsert at the beginning of the lineaInsert afterAInsert at the end of the lineoAppend line then insertOPrepend line then insertddDelete line under the cursorggGo to the first line of the fileGGo the last line of the fileuUndorRedo (Unstable)
:qquit:wsave:wqsave then quit
Feel free to contribute! :)
- initiate the state
- Read file to buffer.
- Set up interface with ncurses
- Listen to keyboard events.
- Each supported keybinding is mapped to a method that mutates the
buffer
- Run
update_state(st)andrender_update(st)
- Similar to
selectorsin redux,update_state(state_t *st)will update all the computed properties (such as cursor position, rows to be displayed on the screen, etc) according to the new mutatedbufferstate. render_update(state_t *st)will actually render everything on the screen according to the result fromupdate_state().
- Goto step 2
Viw's undo & redo functionality is based on the state machine replication principle
- Initialization:
- Deep clone the initial buffer.
- Initialize two stacks (
history stackandredo stack).
- Capture all state-mutating functions and their payloads and push it on to the
history stack. - When the user hits
undo:- Pop the
history stackand the push the result ontoredo stack. - Clone the initial buffer and apply all the commands saved in the
history stackon top of it.
- Pop the
- When the user hits
redo:- Pop the
redo stackand apply the command immediately onto the current buffer.
- Pop the
- Clear the
redo stackwhen a command gets pushed to thehistory stackby the user.
See https://github.com/lpan/viw/blob/master/src/controller.c#L152 for more details
Our main state object has two children states, namely buffer and screen. This seperation
makes it easier to perform unit tests against the buffer. It also facilitates the migration
to a different rendering library in the future.
- The parent state stores computed states that depend on the
bufferand/orscreen. Those states include cursor positions, aount of space reserved for line numbers, etc.
- The buffer is represented as a two dimensional doubly linked list. This allows conatant time line/char deletion and insertion. Go to buffer.h for more information.
- Buffer is only allowed to be modified by the methods declared in
buffer.h
- The screen is the state of the interface between viw and GNU ncurses. It stores information such as pointers to the ncurses windows, etc. You can learn more about it at screen.h.