win-vind
win-vind copied to clipboard
Integrate noremap and map
As discussed in #104, #96, we should implement the easy-to-write macro syntax. The current map
and noremap
have different features. The map
is designed to propagate defined macros to other applications except for win-vind, whereas the noremap
effects in win-vind scope only.
However, the map
and noremap
in the original Vim are used for different purposes with win-vind. It is a factor to misunderstand for Vim users. At this time, this patch allows us to write the following style macros.
noremap j easy_click_left
" a -> move_cursor_down
noremap a j
" a -> easy_click_left
map a j
" only inside {} is actually entered.
noremap a j{This text is inserted}
However, this patch changes the core design and effects .vindrc syntax.
#55
I designed an abstract mapping flow.
In this flow, the main actor is MapSolver, which solve noremap and map recursively and uses it to match the current input. At first glance, the class design is very complex but the main purpose is the latter one. The former uses only at specific times such as :noremap
or :source
, so it behaves like a constructor.
MapSolver has CmdMatcher consisting of a list of CmdUnitMatcher. Each CmdUnitMatcher has a state to state the matching and the CmdMatcher has matching heads to denote the matching unit. They are alternative classes instead of KeyLogger or KeyLog classes.
When a keyset is inputted, it passes through InputGate and en-queues into Queue. The Queue periodically de-queues a CmdUnit to execute it. CmdUnit derives to three classes, ExternalCmdUnit, InternalCmdUnit, FunctionalCmdUnit. The ExternalCmdUnit, parsed from the syntax like {<s-h>}
, executes SendInput of Win32 and creates an internal command unit. The InternalCmdUnit creates only a command unit. The FunctionalCmdUnit, parsed from the syntax such as <easy_click_left>
, wraps the conventional BindedFunc to execute each predefined function.
The InternalCmdUnit and the ExternalCmdUnit create the basic CmdUnit to match with global maps. Therefore, the MapSolver also behaves as a function generator. Such MapSolver is passed to CmdUnit.execute() to solve further matching in functions like :wq
, :dw
, :y$
, or etc.
This design is very small and simple rather than conventional KeyLogger, KeyLog, LoggerParser something. In addition to decreasing the number of singletons used as global objects.
I'm implementing it now.
TODO
- [x] Implement new mapping parser
- [x] Add CmdUnit
- [x] Add a new class to solve and map (MapSolver).
- [x] Implement a class to count the prefix number.
- [x] Fix binded functions to fit new mapping system.
- [x] Add a interface into InputGate to register low-level hotkeys from MapSolver.
- [x] Careful running test
I eliminated conventional complex window_accel
, window_tweight
, and window_maxv
options and added simpler a window_velocity
option.
Most of the refactoring has now been completed, but command mode implementation remaining.
Since it is difficult to get prefixes in command mode for the system command {mode}map
, it is better to seprate each mode by inheriting the class.
I renamed the config cursor_tweight
to cursor_resolution
.
Removed cursor_maxv
, cmd_maxchar
, and cmd_maxhist
.