I spent some time the other day thinking about zippers and structural editors and I wanted to share some of the ideas, because they were interesting, so this is going to be a thread about that
Post
if we knew that `Pair m n` pretty prints as "<" ++ pretty m ++ "," ++ pretty n ++ ">"
we could say, aha, the user pressed `<` so a good candidate for what to push to the context is `Pair _ ?` or `Pair ? _`
practically speaking, this would look something like so:
suppose you have the program
\p -> fst p
and we have an insert cursor that's "before" `fst p`, which i'll indicate with surrounding brackets:
\p -> [fst p]
we type < and we might get
\p -> <[fst p], ?>
probably the way we get the magic of knowing the pretty printing is we have concrete grammar and we treat this as related to Earley parsing, which has a similar kind of structure
except Earley parsing will just try things to output a parse tree, whereas this requires that we have some kind of partial/localized parsing, where part of the parse agenda is already determined because of the context
it might actually be more precisely seen as left-corner parsing rather than general Earley parsing, but maybe that's too left biased, and instead we need a more general non-directional chart parse or some other kind of thing, so that you could type `>` and get a similar effect
i think this general view of things makes it somewhat easy to see how to approach structured editing, and how we can have an Insert cursor for trees. where the Overtype cursor would simply replace the current thing in focus, Insert would push a context frame to the stack
which frame we pick would depend on the type in question
how we deal with multiplicity of options, how we deal with underspecification of the tree, these are all UI/UX issues rather than programming issues
I know that there's a long history of work on structured editors, most of which i haven't read. some more recent work by @neurocy and others on Hazel's editor metatheory is quite interesting. i don't know how it relates to what i've described tho
here are some relevant Hazel links tho:
Toward Semantic Foundations for Program Editors
https://arxiv.org/pdf/1703.08694
Hazelnut: A Bidirectionally Typed Structure Editor Calculus
https://www.youtube.com/watch?v=99SRVnRA9Ec&list=PLechWD1Ts4l9oBGin5tXE7wM6KsF1AtvS&index=2
i think my general vibe on the Hazel approach is that it's too type-theoretic. and while I love type theory, I also love parsers, and I feel like the root of these issues is parsing-related rather than type theory related, even if type theory plays a role
in particular, i think there's a bunch of work on good parsing-with-error-recovery that has been done and needs to be done, especially from the perspective of making these things into generic tools rather than one off custom theories for specific languages
i also think we need a stronger focus on grammars as concrete objects of programming, rather than grammars as latent things
Parsec/parser combinators are cool but there's no concrete grammar to manipulate
TreeSitter is a terrible tool
there's a missing component
also, unrelated to structure editors, there's also a strong value to zippers in general UIs
in particular, when you have any kind of nested UI elements, and you have to do some kind of focus-related UI actions, for instance in a TUI you might have a focused UI element,..
..the zipper approach is very useful for this, because it lets you maintain and internal state for the focusing that makes event handling quite nice