Re: [dev] [sandy] Additional key tests

From: Silvan Jegen <s.jegen_AT_gmail.com>
Date: Fri, 1 Aug 2014 20:27:14 +0200

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

This archive was generated by hypermail 2.3.0 : Fri Aug 01 2014 - 20:36:06 CEST