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
