<commit_before>* Event Loop
The basic structure of the app is just this:

#+BEGIN_SRC pseudocode
while(true){
  in = consume_input();
  new_state = process_input(in,state); // process_input is a state machine
  render_output(new_state);
  state = new_state;
}
#+END_SRC

* Command Parsing
The UI is modal, so parsing contextual commands is the main feature.

Inputs are classified according to type:

#+BEGIN_SRC js
let input_table=/* Type: input_char */
{
  mult0:'123456789',
  multN:'0123456789',
  verb:'cdvy',
  modifier:'ai',
  text_object:'0^${}()[]<>`"\'bBeEwWG',
  motion:'hjkl',
  search_char:'fFtT',
  edit:'aAiIoOpPrxX',
  undo:'u',
  repeat:',.',
};
#+END_SRC

The following type-combinations make a valid command:

- =mult? verb mult? modifier? text_object= operates on a range defined by a text object
- =mult? verb mult? search_char char= operates on the range (starting point, =char=)
- =mult? verb mult? motion= operates on a range defined by (starting point, =motion=)
- =mult? text_object= moves the cursor
- =mult? motion= moves the cursor
- =mult? search_char char= moves the cursor
- =mult? edit= cut/paste =mult?= times
- =mult? edit char* ESC= edit the document chars =mult?= times
- =mult? undo= undo as many times as specified by =mult?=
- =mult? repeat= repeat as many times as specified by =mult?=

** State Machine
Another way to translate typed commands into functions is through a state machine.
The letter x is used to indicate disallowed states.

| State\Input | mult0          | multN          | verb                      | modifier     | text_object | motion      |
|-------------+----------------+----------------+---------------------------+--------------+-------------+-------------|
| initial     | multN          | multN          | to(mult0,verb)            | x            | goto        | goto        |
| mult0       | any            | any            | to(multN,verb)            | x            | goto        | goto        |
| multN       | x              | any            | to(verb,mult0)            | x            | goto        | goto        |
| verb        | to(multN,verb) | to(multN,verb) | doit(double_verb_if_same) | (obj\vertmo) | doit(range) | doit(range) |
| modifier    | x              | x              | x                         | x            | x           | x           |
| text_object | x              | x              | x                         | x            | x           | x           |
| motion      | x              | x              | x                         | x            | x           | x           |

- [[http://parlab.eecs.berkeley.edu/wiki/_media/patterns/finitestatemachine.pdf][Finite State Machine pattern (PDF)]]
- [[https://gamedevelopment.tutsplus.com/tutorials/finite-state-machines-theory-and-implementation--gamedev-11867][State Machines for Games, in AS3]]
- [[https://github.com/Olical/StateMachine][State Machine library in JavaScript]]

* Keyboard Input
Wim is keyboard-centric and has to handle both key /sequences/ and key /chords/.
This can get quite complex if you let it.

For example, say you create a keyboard shortcut =Ctrl a b= where 3 keys are held simultaneously.
But you might also want a sequence =a b= in which first a is pressed, then b.
A fast touch-typist may not fully release one key before pressing another, so Wim might register that both the =Ctrl a b= chord and the =a b= sequence have occurred.

Wim must do one of:
1. prioritize based on an implicit global rule (e.g. evaluate chords before sequences)
2. prioritize based on a user-defined setting
3. disallow conflicts (e.g. throw an exception if user tries to load a config with conflicts)
4. ask the user to resolve conflicts manually<commit_msg>how do you make a vertical bar in org mode again?<commit_after>* Event Loop
The basic structure of the app is just this:

#+BEGIN_SRC pseudocode
while(true){
  in = consume_input();
  new_state = process_input(in,state); // process_input is a state machine
  render_output(new_state);
  state = new_state;
}
#+END_SRC

* Command Parsing
The UI is modal, so parsing contextual commands is the main feature.

Inputs are classified according to type:

#+BEGIN_SRC js
let input_table=/* Type: input_char */
{
  mult0:'123456789',
  multN:'0123456789',
  verb:'cdvy',
  modifier:'ai',
  text_object:'0^${}()[]<>`"\'bBeEwWG',
  motion:'hjkl',
  search_char:'fFtT',
  edit:'aAiIoOpPrxX',
  undo:'u',
  repeat:',.',
};
#+END_SRC

The following type-combinations make a valid command:

- =mult? verb mult? modifier? text_object= operates on a range defined by a text object
- =mult? verb mult? search_char char= operates on the range (starting point, =char=)
- =mult? verb mult? motion= operates on a range defined by (starting point, =motion=)
- =mult? text_object= moves the cursor
- =mult? motion= moves the cursor
- =mult? search_char char= moves the cursor
- =mult? edit= cut/paste =mult?= times
- =mult? edit char* ESC= edit the document chars =mult?= times
- =mult? undo= undo as many times as specified by =mult?=
- =mult? repeat= repeat as many times as specified by =mult?=

** State Machine
Another way to translate typed commands into functions is through a state machine.
The letter x is used to indicate disallowed states.

| State\Input | mult0          | multN          | verb                      | modifier       | text_object | motion      |
|-------------+----------------+----------------+---------------------------+----------------+-------------+-------------|
| initial     | multN          | multN          | to(mult0,verb)            | x              | goto        | goto        |
| mult0       | any            | any            | to(multN,verb)            | x              | goto        | goto        |
| multN       | x              | any            | to(verb,mult0)            | x              | goto        | goto        |
| verb        | to(multN,verb) | to(multN,verb) | doit(double_verb_if_same) | (obj \vert mo) | doit(range) | doit(range) |
| modifier    | x              | x              | x                         | x              | x           | x           |
| text_object | x              | x              | x                         | x              | x           | x           |
| motion      | x              | x              | x                         | x              | x           | x           |

- [[http://parlab.eecs.berkeley.edu/wiki/_media/patterns/finitestatemachine.pdf][Finite State Machine pattern (PDF)]]
- [[https://gamedevelopment.tutsplus.com/tutorials/finite-state-machines-theory-and-implementation--gamedev-11867][State Machines for Games, in AS3]]
- [[https://github.com/Olical/StateMachine][State Machine library in JavaScript]]

* Keyboard Input
Wim is keyboard-centric and has to handle both key /sequences/ and key /chords/.
This can get quite complex if you let it.

For example, say you create a keyboard shortcut =Ctrl a b= where 3 keys are held simultaneously.
But you might also want a sequence =a b= in which first a is pressed, then b.
A fast touch-typist may not fully release one key before pressing another, so Wim might register that both the =Ctrl a b= chord and the =a b= sequence have occurred.

Wim must do one of:
1. prioritize based on an implicit global rule (e.g. evaluate chords before sequences)
2. prioritize based on a user-defined setting
3. disallow conflicts (e.g. throw an exception if user tries to load a config with conflicts)
4. ask the user to resolve conflicts manually
{'fraction_non_alphanumeric': 0.1283458244111349, 'fraction_numerical': 0.009635974304068522, 'mean_word_length': 2.0664751743947476, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 29, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '880504', 'n_tokens_mistral': 2190, 'n_tokens_neox': 2081, 'n_words': 801}