Hi
On Thu, Jul 24, 2014 at 03:22:34AM +0300, Dimitris Zervas wrote:
> [...]
> What do you think?
I spent some time thinking about the (finite) state machine idea for
sandy which I think would help simplify the key definitions a lot.
I came up with the following (non-exhaustive) function call graph.
http://sillymon.ch/data/funcfsm.png
(source:
http://sillymon.ch/data/funcfsm.dot )
Please note the following:
* To simplify the states I assume that a count ([0-9]+) can only occur
before the movement command (jklhw etc.) and not before the operator
(ydc). That means that "d3w" is valid but "3dw" isn't.
* The fsm_* functions would need to read input to decide on the
transitions (i. e. functions to call; to extract the count argument for
move(), fsm_move would have to read in a loop). I think maybe passing
a function pointer to these functions would make sense. The passed
function pointer would then determine whether the next input is read
from stdin or a buffer (useful for macros?) or from wherever.
* The operator-fsm_* functions do not much more than call fsm_move
which will return to- and from-coordinates that are then passed to the
functions doing the actual work (delete and yank). The order in which the
fsm_* functions call the other functions is not specified in the graph (but
should be fairly obvious).
* The screen/cursor would have to be updated after the FSM returns to the start
state.
* If move is called from the start node directly, the count parameter
is set to 1.
* There are probably some other things that I forgot to take into
consideration. We can figure out the details if we decide on this or a
similar approach.
Using this FSM the keys could be simplified. It should be possible to do
something like (untested and in C-like pseudocode).
enum key {
INPUT_MODE = 0
VISUAL_MODE
OBJECT_SENTENCE
OP_DELETE
...
};
and an array of chars with the "key binding" at the appropriate index
char chardefs[...] = {
'i', # INPUT_MODE: switch to input mode
'v', # VISUAL_MODE: ...
's', # OBJECT_SENTENCE: ...
'd', # OP_DELETE: ...
...
};
when reading input in the state functions we could then just do something
like.
while (ch = getch()) {
switch (ch) {
case chardefs[INPUT_MODE]:
fsm_input_mode()
return
case chardefs[VISUAL_MODE]:
...
}
}
There are still a few open questions like the handling of aliases (like "D" for
"d$") for example but I think they should be solvable if I have not
missed anything important.
I have not written one line of code yet because I am not sure this is
the best approach. Do you see issues with this proposal or do you have
a better idea/implementation in mind?
Cheers,
Silvan
Received on Fri Aug 01 2014 - 20:27:14 CEST