disconcision/fructure
{ "createdAt": "2017-01-28T04:47:12Z", "defaultBranch": "master", "description": "a structured interaction engine đď¸ âď¸", "fullName": "disconcision/fructure", "homepage": "https://fructure-editor.tumblr.com/", "language": "Racket", "name": "fructure", "pushedAt": "2024-01-27T07:54:38Z", "stargazersCount": 488, "topics": [], "updatedAt": "2025-11-14T15:43:22Z", "url": "https://github.com/disconcision/fructure"}Fructure: A structured interaction engine in Racket
Section titled âFructure: A structured interaction engine in Racketâ![Screenshot]!(screenshots/tumblr_pmdgbc2Kgc1y69izqo1_400.png)
Updated July 2019 : Installation instructions & mini-guide below
CLICK HERE for a video demo from RacketCon 2019
Section titled âCLICK HERE for a video demo from RacketCon 2019âFructure at RacketCon 2019.My talk (from the livestream).Slides: [Real version]!(screenshots/REAL-RacketCon-Fructure-Talk.pdf). [Extended unedited version]!(screenshots/FAKE-extended-unedited-racketcon-fructure-talk.pdf).
Fructure is a prototype structure editor, which can currently be used to write & edit small programs in a small subset of scheme/racket. This is a personal project where Iâm playing with ideas in editing, programming languages, and interaction design.
Note: now that this is getting some traffic I wanted to put up a disclaimer that some of the code is currently in a bit of a state: Iâve commented out some things and hacked up some others to smoothen the demo. My immediate plans are - after taking a post-racketcon break and aside from general cleanup - to unhackify the way transforms currently work, properly re-instate variadic parameters for binding forms, and do some profiling and address the current sluggishness.
-
fig 1: walking the grammar ![Screenshot]!(screenshots/walk-1.png)
-
fig 2: refactoring by re/destructuring ![Screenshot]!(screenshots/cond-if-1.png)
-
fig 3: menu closeup ![Screenshot]!(screenshots/menu-2.png)
I wrote a bit about my then-current direction in September 2018, just before beginning my current implementation attempt. Iâve completed most of what I talk about there, with varying levels of success: Fructure 1 of 2 Fructure 2 of 2. There will soon be some slightly more up-to-date notes via my racketcon slides. For more updates cyberfollow @twitter and @elsewhere. Hereâs an ongoing dev screenshot dump; check out the chronological overview:
fig 4: family history ![Screenshot]!(screenshots/2019-02-07-22_29_41-fructure-editor-Archive.png)
Installation Instructions
Section titled âInstallation InstructionsâBasically, you need to install racket, a couple libraries, and a font if you donât want thing to look screwy.
MacOS:
- brew install racket âcask
- brew tap homebrew/cask-fonts && brew install font-iosevka âcask
- raco pkg install memoize
- raco pkg install rackjure
- git clone https://github.com/disconcision/fructure.git
Linux, Windows: (under construction)
TO RUN:
- cd fructure
- racket src/fructure.rkt
FAQ: Q: Is it suppose to be this slow? A: Itâs open source.
Fructure Primer
Section titled âFructure PrimerâSTEP 0: What to do if youâre stuck / Speedrun instructions
Section titled âSTEP 0: What to do if youâre stuck / Speedrun instructionsâ- How to win: There are modes, but pressing ESC enough times should always get you to the base mode. From there, press SPACE to enter command mode. From here, PRESS âqâ then RIGHT-ARROW to quit.
- Check the terminal for silent crashes (aka âbonusâ victory conditions)
STEP 1: mini tutorial
Section titled âSTEP 1: mini tutorialâFructure starts in NAV(igation) mode. The selector (red) encloses a hole (yellow).
NAV keybindings
ENTERtoggles TRANSFORM mode
A transform (red) maps the source (the hole) to (->) the target (selection (outlined in red) in menu (also outlined in red))
TRANSFORM keybindings
UP/DOWNmove menu / selector: find and select an âifâ expression)ENTERperforms selected transform, toggles NAV mode: transform the hole to the if
NAV keybindings (continued)
LEFT/RIGHTmove selector in preorder tree traversal: go right thrice and left twice to cycle the selection, settling on the first child
These keys (almost) suffice to build/delete arbitrary syntax, though not terribly conveniently. Build a tiny program this way. I say almost because you canât (yet, owing to a bug) input new identifiers in this way. Doing so (currently) requires being in the menu and pressing RIGHT on a lambda or define (see next step).
STEP 2:
Section titled âSTEP 2:âApproximating standard text-entry
NAV keybindings
UP/DOWNselector to parent/first child
TRANSFORM keybindings
ESCswitch to NAV mode without performing transformationRIGHTstep into current transform: (essentially) perform selected transform, and then advance the selector/menu to the first created hole. (unless last action was an undo, in which case RIGHT is a redo)LEFTundo (back to state at last step, delimited by entering transform mode)SPACEin current implementation the same as RIGHT, minus the redo part. eventually, it should be part of alphanumericsalphanumerics+(+)filter menu by search buffer prefix matchBACKSPACEerase most recent character in search bufferDELETEerase search buffer
STEP 3:
Section titled âSTEP 3:âAbstract copy/paste
NAV keybindings
TABcapture selectionESCclear captures
TRANSFORM keybindings
SHIFT-LEFT/RIGHTun/fold transform displaySHIFT-UP/DOWNextend/contract displayed menu options
STEP 4:
Section titled âSTEP 4:âSimple settings scrubber
NAV keybindings
SPACEswitch to COMMAND mode
TRANSFORM keybindings
SHIFT-SPACEswitch to COMMAND mode
COMMAND keybindings
UP/DOWNselect propertyLEFT/RIGHTscrub property- alphanumerics/BACKSPACE/DELETE : filter/unfilter property
ESCreturn to NAV or TRANSFORM mode
BOITE DIABOLIQUE: housing the 19 forbidden keybindings
Section titled âBOITE DIABOLIQUE: housing the 19 forbidden keybindingsâEXPERIMENTAL & FICTIONAL keybindings: lies at best, trouble at worst
NAV
F2dump current structure to stdinCTRL-F9-F12save structure to diskSHIFT-F9-F12load structure from diskSHIFT-LEFT/RIGHTselector to siblingDOWNstep into capturealphanumerics(restrict selector traversal to search buffer hits aka find as you type) TRANSFORMF2dump current structure to stdinRCTRLshortcut to select/insert parens
Screenshots
Section titled âScreenshotsâStructured insertion via walking the grammar:
Section titled âStructured insertion via walking the grammar:â![Screenshot]!(screenshots/tumblr_pme22tqxTr1y69izqo1_1280.png)
![Screenshot]!(screenshots/fructure-rounded-modified.gif)
Navigation mode
Section titled âNavigation modeâ![Screenshot]!(screenshots/2019-02-07-22_19_43-fructure-editor.png)
Copy/Paste via Metavariables
Section titled âCopy/Paste via Metavariablesâ![Screenshot]!(screenshots/2019-02-07-22_19_53-fructure-editor.png)
âŚ
![Screenshot]!(screenshots/tumblr_pme1mh4Sdd1y69izqo1_640.png) ![Screenshot]!(screenshots/tumblr_pme1mabMT01y69izqo1_500.png) ![Screenshot]!(screenshots/tumblr_pmdg8nEd4h1y69izqo2_640.png) ![Screenshot]!(screenshots/tumblr_pme1hgBeA41y69izqo1_400.png)