Skip to content
a structured interaction engine 🗜️ ⚗️
Racket HTML CSS Other
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
archive total directory structured reorganization. TEMPORARILY including cont… Jun 26, 2019
saves space skipping out of variadic lists seems to work. hopeful but distr… Jul 3, 2019
shared total directory structured reorganization. TEMPORARILY including cont… Jun 26, 2019
src tweaks? slides. Jul 13, 2019
tests total directory structured reorganization. TEMPORARILY including cont… Jun 26, 2019
.gitignore added option to display sorts for holes. added the ability to quit Jun 30, 2019 Update Aug 8, 2019

Fructure: A structured interaction engine in Racket


alt text

Updated July 2019 : Installation instructions & mini-guide below

CLICK HERE for a video demo from RacketCon 2019

Fructure at RacketCon 2019.My talk (from the livestream).Slides: Real version. Extended unedited version.

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

  • fig 2: refactoring by re/destructuring Screenshot

  • fig 3: menu closeup Screenshot

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

Installation Instructions

Basically, you need to install racket, a couple libraries, and a font if you don't want thing to look screwy.


  1. brew cask install racket
  2. brew tap caskroom/fonts && brew cask install font-iosevka
  3. raco pkg install memoize
  4. raco pkg install rackjure
  5. git clone

Linux, Windows: (under construction)


  1. cd fructure
  2. racket src/fructure.rkt

FAQ: Q: Is it suppose to be this slow? A: It's open source.

Fructure Primer

STEP 0: What to do if you're stuck / Speedrun instructions

  1. 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.
  2. Check the terminal for silent crashes (aka 'bonus' victory conditions)

STEP 1: mini tutorial

Fructure starts in NAV(igation) mode. The selector (red) encloses a hole (yellow).

NAV keybindings

  • ENTER toggles 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/DOWN move menu / selector: find and select an "if" expression)
  • ENTER performs selected transform, toggles NAV mode: transform the hole to the if

NAV keybindings (continued)

  • LEFT/RIGHT move 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).


Approximating standard text-entry

NAV keybindings

  • UP/DOWN selector to parent/first child

TRANSFORM keybindings

  • ESC switch to NAV mode without performing transformation
  • RIGHT step 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)
  • LEFT undo (back to state at last step, delimited by entering transform mode)
  • SPACE in current implementation the same as RIGHT, minus the redo part. eventually, it should be part of alphanumerics
  • alphanumerics + ( + ) filter menu by search buffer prefix match
  • BACKSPACE erase most recent character in search buffer
  • DELETE erase search buffer


Abstract copy/paste

NAV keybindings

  • TAB capture selection
  • ESC clear captures

TRANSFORM keybindings

  • SHIFT-LEFT/RIGHT un/fold transform display
  • SHIFT-UP/DOWN extend/contract displayed menu options


Simple settings scrubber

NAV keybindings

  • SPACE switch to COMMAND mode

TRANSFORM keybindings

  • SHIFT-SPACE switch to COMMAND mode

COMMAND keybindings

  • UP/DOWN select property
  • LEFT/RIGHT scrub property
  • alphanumerics/BACKSPACE/DELETE : filter/unfilter property
  • ESC return to NAV or TRANSFORM mode

BOITE DIABOLIQUE: housing the 19 forbidden keybindings

EXPERIMENTAL & FICTIONAL keybindings: lies at best, trouble at worst


  • F2 dump current structure to stdin
  • CTRL-F9-F12 save structure to disk
  • SHIFT-F9-F12 load structure from disk
  • SHIFT-LEFT/RIGHT selector to sibling
  • DOWN step into capture
  • alphanumerics (restrict selector traversal to search buffer hits aka find as you type) TRANSFORM
  • F2 dump current structure to stdin
  • RCTRL shortcut to select/insert parens


Structured insertion via walking the grammar:



Navigation mode


Copy/Paste via Metavariables



Screenshot Screenshot Screenshot Screenshot

You can’t perform that action at this time.