From 2d3b518e8db13b6cc534836d8a4125e9d49b7a25 Mon Sep 17 00:00:00 2001 From: Zach Potter Date: Sat, 2 Sep 2023 22:00:30 -0700 Subject: A more reactive terminal The terminal can now - spawn with specific commands - kill their children and clean up resources - have dynamic rows/cols - draw text on any region And I added some docs, with a simple editor program! --- virtual-programs/terminal.folk | 89 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 16 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/terminal.folk b/virtual-programs/terminal.folk index 4cbf6339..16741e9c 100644 --- a/virtual-programs/terminal.folk +++ b/virtual-programs/terminal.folk @@ -1,29 +1,86 @@ # Terminal # -# Wish $this is a terminal -# Claim $this has keyboard input +# Spawn terminals with any command (default "bash"): +# Wish $this is a terminal +# Wish $this is a terminal spawning "any command" +# +# Send keyboard events to the terminal: +# Claim $thing has keyboard input +# +# Optionally, draw the terminal on an arbitrary region: +# Claim $thing has terminal region $region +# +# +# Example program: Tie it all together with a simple vim editor... +# +# When $this points up at /target/ & /target/ has program /anything/ { +# Wish $this is a terminal spawning "vim ~/folk-printed-programs/$target.folk" +# When $this has region /r/ { +# Claim $this has terminal region [region move $r right 350px] +# } +# Claim $this has keyboard input +# } +# +# +# Note: Terminals are killed after ::termExpireMs of being unmatched. # source lib/terminal.tcl -When /anyone/ wishes /thing/ is a terminal { - # Create a new terminal instance for this $thing only once - When /nobody/ claims $thing has terminal instance /term/ { - Assert terminal claims $thing has terminal instance [Terminal::create] +set ::termExpireMs [expr {10*60*1000}] ;# 10 minutes +set ::termInstances [dict create] +set ::termTimeouts [dict create] + +proc ::matchTerminal {id cmd} { + set termKey "$id $cmd" + if {$termKey ni $::termInstances} { + dict set ::termInstances $termKey [Terminal::create 12 43 $cmd] } + if {$termKey in $::termTimeouts} { + after cancel [dict get $::termTimeouts $termKey] + dict unset ::termTimeouts $termKey + } + dict get $::termInstances $termKey +} - When terminal claims $thing has terminal instance /term/ { - When $thing has region /r/ & /node/ has step count /c/ { - set display [region move $r up 180px] - Wish region $display is labelled [Terminal::read $term] +proc ::unmatchTerminal {id cmd} { + set termKey "$id $cmd" + dict set ::termTimeouts $termKey [ + after $::termExpireMs "::destroyTerminal [list $termKey]" + ] +} + +proc ::destroyTerminal {termKey} { + Terminal::destroy [dict get $::termInstances $termKey] + dict unset ::termInstances $termKey + dict unset ::termTimeouts $termKey +} + +When /anyone/ wishes /thing/ is a terminal { + Wish $thing is a terminal spawning bash +} + +When /thing/ has terminal region /r/ & /r/ has keyboard input { + Claim $thing has keyboard input +} + +When /anyone/ wishes /thing/ is a terminal spawning /cmd/ { + set term [::matchTerminal $thing $cmd] + On unmatch { ::unmatchTerminal $thing $cmd } + + When $::thisProcess has step count /c/ { + set lambda { + Wish region $region is labelled [Terminal::read $term] } + When $thing has terminal region /region/ $lambda + When /nobody/ claims $thing has terminal region /x/ & $thing has region /region/ $lambda + } - When /anyone/ claims $thing has keyboard input & \ - /anyone/ claims key /key/ is /direction/ with modifiers /modifiers/ { - if {$direction != "up"} { - set ctrlPressed [expr {"ctrl" in $modifiers}] - Terminal::write $term $key $ctrlPressed - } + When /anyone/ claims $thing has keyboard input \ + & /anyone/ claims key /key/ is /direction/ with modifiers /modifiers/ { + if {$direction != "up"} { + set ctrlPressed [expr {"ctrl" in $modifiers}] + Terminal::write $term $key $ctrlPressed } } } -- cgit v1.2.3 From 2afdf58664d2aa2fd583115aa3d5ebb046ca6c0d Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Wed, 6 Sep 2023 00:45:43 -0400 Subject: terminal: lambda -> body --- virtual-programs/terminal.folk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/terminal.folk b/virtual-programs/terminal.folk index 16741e9c..3fb335b5 100644 --- a/virtual-programs/terminal.folk +++ b/virtual-programs/terminal.folk @@ -69,11 +69,11 @@ When /anyone/ wishes /thing/ is a terminal spawning /cmd/ { On unmatch { ::unmatchTerminal $thing $cmd } When $::thisProcess has step count /c/ { - set lambda { + set body { Wish region $region is labelled [Terminal::read $term] } - When $thing has terminal region /region/ $lambda - When /nobody/ claims $thing has terminal region /x/ & $thing has region /region/ $lambda + When $thing has terminal region /region/ $body + When /nobody/ claims $thing has terminal region /x/ & $thing has region /region/ $body } When /anyone/ claims $thing has keyboard input \ -- cgit v1.2.3