| ID | 3cde3b32-85d7-4f9c-bd40-8ab7b3ce7ddb |
|---|---|
| DeertopiaVisibility | public |
Structural editing
Structural editing is the editing of code directly using syntax trees rather than strings of text.
TODO: this is an unorganised dump!
TODO: S-expressions
Inbox
Identifiers can easily include spaces }:3
Ki's file manager works by rendering the file tree to YAML, and providing normal, structural, tree navigation. Can tree editing really simplify UI this much?
Generalised yank/paste
Could you copy functions to registers? e.g., if you raised a expression:
;; Let the 'selected' expression be delimited by !* ... *!
(map !*(λ (x) (* x x))*!
'(0 1 2 3))
;; to
!*(λ (x) (* x x))*!
Suppose you could then "paste" the killed partial expression, like so: example
(λ (x) !*(* x x)*!)
;; to
(λ (x) (map !*(* x x)*!
'(0 1 2 3)))
Structural descriptions of languages
Could we create something analogous to a tree-sitter grammar? That is, a portable package format to describe
A grammar optimised for editing (as opposed to parsing).
Serialisation.
Actions available for each node type.
Default highlights and queries.
Buffer narrowing
Focus on just a few select nodes, either by exclusively displaying them, or dimming out the surroundings.
Motivation
unimplemented! (verse-block)
{:type "verse-block",
:affiliated {},
:contents-begin 1494,
:contents-end 2899,
:position
{:start {:line 56, :column 1, :offset 1480},
:end {:line 65, :column 1, :offset 2911}},
:children
([:b ("faye")]
": why isn't visual "
[:span.org-link
[:a {:href "/n/dbT4KZslR3-pLXGmQClErQ"} (("programming"))]]
" more of a thing :() why are we still at the point of prodding at a byte stream by hand to write code\n"
[:b ("faye")]
": we should be able to work directly in the AST....\n"
[:b ("madeleine")]
": 1. i really wish people were more open-minded about lispy syntaxes (syntaces?). it really frustrates, since i think the C/C++/java-style syntaxes that are so widely popular are reaaaally fucking ugly, complex, difficult to parse, and despite it all, considered \"normal\" due to their popularity.\n"
[:b ("madeleine")]
": 2. pure structural editing isn't a deeply-explored idea to me, so this opinion may change, but i currently believe that s-expressions give you 90% of the benefits at 10% of the cost of pure structural editing. a really nice compromise, in my opinion. }:3\n"
[:b ("madeleine")]
": 3. despite all of that praise, i'm actually not much of a lisp person. }:P i admire it from afar, but i'm seldom comfortable parting with my static types.\n"
[:b ("madeleine")]
": 3.5. (at the very least, i can say that lisps have better type systems than many other dynamic languages...)\n"
[:b ("faye")]
": i agree with your points! i really would like it if we invested more in structural editing :() i think the preoccupation with textual languages make a lot of people more concerned about the ergonomics of typing out a language rather than the expressiveness of it, which i find strange.\n")}
Silly problems with character-wise editing
Indentation/formatting arguments due to personal preferences.
Indentation/formatting arguments due to ease-of-diffing.
snakecase vs. camelCase vs. kebab-case.
Trivial syntax errors.
Debates over significant/insignificant whitespace.
Advantages of text-based traditions
can be embedded and shared anywhere.
can be written and read by any neanderthal with tools ranging from a single eye and a ink-soaked finger, to a fancy proprietary IDE.
maybe there is an argument to be had regarding whether or not the high-level input experience is consistent, but the low-level, character-wise input is consistent.
a single syntax means everyone...
unimplemented! (verse-block)
{:type "verse-block",
:affiliated {},
:contents-begin 3638,
:contents-end 3950,
:position
{:start {:line 81, :column 1, :offset 3624},
:end {:line 88, :column 1, :offset 3962}},
:children
([:b ("madeleine")]
": you know what..?\n"
[:b ("madeleine")]
": all of these but the third are irrelevant, at the scope of two hobbyists. who gives a fuck? }:PPP\n\n"
[:b ("faye")]
": haha . i'm feeling #3!\n"
[:b ("faye")]
": don't think there's anything preventing us from having both a nice text repr as well as a symbolic view for traditional languages\n")}
Interactive editing
unimplemented! (verse-block)
{:type "verse-block",
:affiliated {},
:contents-begin 4000,
:contents-end 4376,
:position
{:start {:line 91, :column 1, :offset 3986},
:end {:line 94, :column 1, :offset 4388}},
:children
([:b ("madeleine")]
": ooooh!! a tangentially related idea i've had in the back of my head for a while now: within this framework, some languages could allow interactive editing that takes advantage of language-specific semantics. the most obvious examples arise from statically-typed languages. "
[:s
("as far as i understand, idris and agda are the most mainstream pioneers in this space.")])}
In a similar vein, one could implement a which-key-like menu, listing the various syntactic constructs that make sense to appear at a given node.
Editing plaintext in a structural editor
Plaintext can be mapped to a tree in a variety of ways. I particularly like these models:
Lorem ipsum odor amet, consectetuer adipiscing elit. Sem cursus proin ullamcorper lobortis euismod facilisi. Fermentum neque nibh rhoncus netus efficitur habitasse nostra. Nostra blandit justo fames tempus quam convallis cursus. Purus etiam sociosqu elementum ad ligula. Elit adipiscing et porta libero urna commodo rutrum. Lacus ridiculus parturient in nostra mi pulvinar. Maecenas at fringilla sociosqu hac mollis diam elit platea. Dictumst montes scelerisque arcu convallis; rutrum rhoncus potenti. Curabitur ligula elit aliquet mollis class. Volutpat in velit viverra urna adipiscing interdum velit. Accumsan montes finibus tempus blandit ad. Curabitur faucibus porta venenatis eget dictumst. Torquent metus vulputate amet nullam himenaeos justo sed. Eleifend donec auctor aptent ullamcorper est vestibulum.
digraph G {
fontname="Helvetica,Arial,sans-serif"
subgraph cluster_document {
label = "document"
document [label="Lorem ipsum..."]
}
subgraph cluster_paragraphs {
label = "paragraphs"
para1 [label="Lorem ipsum ... rutrum."]
para2 [label="Lacus ridiculus ... vestibulum."]
}
document -> para1
document -> para2
subgraph cluster_sentences {
label = "sentences"
para1_sent1 [label="Lorem ipsum ... elit."]
para1_sent2 [label="Sem cursus ... facilisi."]
para2_sent1 [label="Lacus ridiculus ... pulvinar."]
para2_sent2 [label="Maecenas at ... platea."]
}
para1 -> {para1_sent1, para1_sent2}
para2 -> {para2_sent1, para2_sent2}
subgraph cluster_words {
label = "words"
para1_sent1_word1 [label="Lorem"]
para1_sent1_word2 [label="ipsum"]
para1_sent2_word1 [label="Sem"]
para1_sent2_word2 [label="cursus"]
para2_sent1_word1 [label="Lacus"]
para2_sent1_word2 [label="ridiculus"]
para2_sent2_word1 [label="Maecenas"]
para2_sent2_word2 [label="at"]
}
para1_sent1 -> {para1_sent1_word1, para1_sent1_word2}
para1_sent2 -> {para1_sent2_word1, para1_sent2_word2}
para2_sent1 -> {para2_sent1_word1, para2_sent1_word2}
para2_sent2 -> {para2_sent2_word1, para2_sent2_word2}
subgraph cluster_characters {
label = "characters"
para1_sent1_word1_char1 [label="L"]
para1_sent1_word1_char2 [label="o"]
lol [label="you get the idea. }:3"]
}
para1_sent1_word1 -> {para1_sent1_word1_char1, para1_sent1_word1_char2}
para1_sent1_word2 -> lol
}
file:structural-editing-assets/plaintext-1.png
Sentences could instead be lines, or both sentences and lines could be used. This would be interesting, as the document would now be a DAG rather than a tree.
Open questions
How is whitespace handled? Is whitespace handled?