Open jhance opened 8 years ago
I made a PR on yi-language
that starts this off by making ExtHL
composable.
@jhance I think the most important thing to do is to define semantics for the compositions of modes. For example, what does it mean when two modes are composed and one wants to highlight a word red and the other wants to highlight it blue? Or if one mode binds a key to insert text and another binds that same key to delete some text?
I think the easiest semantics just always follow the semantics of the first mode (if there is a conflict), but that can cause unexpected behavior when a mode expects all its keybindings to actually be bound, what if a vim based mode would suddenly lose its escape key?
We can also define a composition of modes that only works if they don't conflict. For example, you wouldn't be able to compose a vim keybindings mode with an emacs keybdinding mode, because they have overlapping keybindings.
I think a better solution is to add a more nuanced way of composing modes where you can give priority to certain semantics. For example, you could say that errors are more important than warnings when highlighting text, so the highlighter should show an error if it overlaps with a warning.
I kind of tried to look at doing this like two years ago, and hopefully I'm smarter now than I was then.
My vision is this: We need some sort of minor-vs-major distinction so that we can ensure that only one "major" mode is active at a time. I think the best way to do this is to have separate types, but a boolean record might be better.
A
ModeStack
should probably be different than aMode
. In particular aModeStack
needs to compose most of the things insideMode
, but not all, for example the name of aModeStack
should be a list of the underyling modes (in precedence order).We need to define how certain parts of modes. Some parts should be major-mode only (think for example the modeline). We can convert a
MajorMode
into aModeStack
and then add a minor-mode into aModeStack
, changing the properties of the mode. ThenAnyModeStack
replacesAnyMode
.The type for minor modes can be littered with
Maybe
s and hence we can have like aemptyMinorMode :: T.Text -> MinorMode
which creates one with a bunch ofNothing
.(Names subject to change, its easiest to make the naming such that
AnyMode = forall syntax. ModeStack syntax
)Note: This will first require composability of
ExtHL
. We can't make these monoids, but we can make them something structurally similar (like a product-preserving map?)