-
Notifications
You must be signed in to change notification settings - Fork 115
Design
Vintageous implements Vim emulation on top of the Sublime Text API.
Vintageous keeps collecting user input via key bindings until it can build a runnable command. At that point, command data is passed as JSON to a command runner.
Collecting command data from the user and running collected command data are Vintageous' core tasks, but there are other support steps too (more on that later).
state.State
: Collects user input and evaluates its runnability.
At a very high level, this would be the life-cycle of a command, starting from a clean state:
- User presses
d
(to request Vim delete command). - [
State
captures the action name in its.action
property.] - User presses
2
(to request a count on the following motion). - [
State
captures the motion count in its.motion_count
property.] - [At this point, our command is still incomplete.]
- User presses
w
(to request a 'move by words' motion). - [
State
captures the motion name in its.motion
property.]
At this point, State
finally holds a runnable command: d2w
. It's
now time to run it, but before we see how that's done, here's a couple of
important notes about State
:
The interaction between the user and State
has been possible thanks to
the key bindings defined in ./Default.sublime-keymap. Contexts play a crucial
part here to provide commands with mode awareness (./vi/contexts.py).
Also, it's worth noting that the Sublime Text settings API is used to persist
the vast majority of State
's data. The settings abstraction for
Vintageous can be found in ./vi/settings.py.
After every key press, xactions.PressKey
runs State.eval()
.
In each call, if .eval()
finds State
needs further user input, it
does nothing. By contrast, if it finds a runnable command, it runs it.
Therefore, a more accurate description of the program's flow is conceptually as follows (in pseudocode):
[PressKey: d]
State.eval()
[PressKey: 2]
State.eval()
[PressKey: w]
State.eval()
Parsing State
's captured data is State.eval()
's job. It makes sure that
the requested command receives the current state as JSON-valid data.
Command implementations are in xactions.py
and xmotions.py
.
We've left out quite a few details, and Sublime Text imposes some rigid restrictions that Vintageous must work around. While the above should enable you to grasp the inner workings of Vintageous, it isn't the full story.
We have also not discussed how the command line works. Though similar in many
respects to the rest of Vintageous, it bypasses State
most of the time.