Welcome to Konilo ,dPYb, ,dPYb, IP'`Yb IP'`Yb I8 8I gg I8 8I I8 8bgg, "" I8 8' I8 dP" "8 ,ggggg, ,ggg,,ggg, gg I8 dP ,ggggg, I8d8bggP" dP" "Y8 ,8" "8P" "8, 88 I8dP dP" "Y8 I8P' "Yb, i8' ,8I d8 8I 8I 88 I8P i8' ,8I ,d8 `Yb,,d8, ,d8P8P 8I Yb,_,88,_,d8b,_ ,d8, ,d8' 88P Y8P"Y8888P" 8I `Y88P""Y88P'"Y88P"Y8888P" `manual` for the users guide `blocks` for help using the block editor `describe name` for help on a specific word `catalogue` to explore the blocks (startup) (configure_blocks,_load_extensions) . You should setup the numbers of blocks in your system. #192 !Blocks . Load desired extensions. As Konilo uses a single shared . buffer for blocks, I wrap these in a quote, and make `call` . the last item in this block. This ensures proper behavior. [ @Blocks [ #128 !Blocks '(std) needs '(termina) needs '(tools:describe) needs '(tools:blocks) needs '(tools:manual) needs '(tools:catalogue) needs '(tuhi) needs '(nonix) needs ] dip !Blocks ] call(startup) (local-configuration) . If you load things like (termina) or (graphica), you may want . to set various variables relating to the local environment. Do. this here. #75 !ti:width #20 !ti:height [ (n-) set load tuhi ] !Editor . On startup, display the welcome message in block 0. [ #0 set load list* nl ] call (std) (constants) . Constants for numeric range limits. :n:MIN #-2,147,483,647 ; :n:MAX #2,147,483,646 ; . Constants for flags. :TRUE #-1 ; :FALSE #0 ; . Constants for memory layout :sys:BUFFERS #60,000 ; :sys:EOM #65,535 ; (std) (s:) (constants) :s:DIGITS '0123456789ABCDEF ; :s:VOWELS 'aeiouAEIOU ; :s:ASCII-UPPERCASE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ; :s:ASCII-LOWERCASE 'abcdefghijklmnopqrstuvwxyz ; :s:ASCII-LETTERS 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ; 's:WHITESPACE d:create #4 comma #9 comma #10 comma #13 comma #32 comma :s:PUNCTUATION '_!"#$%&'()*+,-./:;<=>?@[\]^`{|}~ ; :s:CONSONANTS 'bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ ; (std) (c:) (classification) :c:consonant? (c-f) s:CONSONANTS swap s:contains? ; :c:vowel? (c-f) s:VOWELS swap s:contains? ; :c:letter? (c-f) s:ASCII-LETTERS swap s:contains? ; :c:digit? (c-f) s:DIGITS swap s:contains? ; :c:whitespace? (c-f) s:WHITESPACE swap s:contains? ; :c:visible? (c-f) #32 #126 n:between? ; :c:-consonant? (c-f) c:consonant? not ; :c:-vowel? (c-f) c:vowel? not ; :c:-letter? (c-f) c:letter? not ; :c:-digit? (c-f) c:digit? not ; :c:-whitespace? (c-f) c:whitespace? not ; :c:-uppercase? (c-f) c:uppercase? not ; :c:-lowercase? (c-f) c:lowercase? not ; :c:-visible? (c-f) c:visible? not ; (std) (c:) (conversions) :c:toggle-case dup c:lowercase? &c:to-upper &c:to-lower choose ; (std) (n:) (even,odd,sign,square,sqrt) :n:odd? (n-f) #1 and #1 eq? ; :n:even? (n-f) n:odd? not ; :n:negative? (n-f) #0 lt? ; :n:positive? (n-f) #0 gt? ; :n:strictly-positive? (n-f) #1 gteq? ; :n:square (n-n) dup n:mul ; :~guess dup-pair n:div over n:sub #2 n:div ; :n:sqrt (n-n) #1 [ ~guess &n:add sip ] while nip ; :n:sign (n-n) n:negative? [ #-1 ] [ #1 ] choose ; (std) (v:) :v:preserve (aq-) swap dup fetch [ &call dip ] dip swap store ; :v:inc-by (an-) [ fetch n:add ] sip store ; :v:dec-by (an-) [ fetch swap n:sub ] sip store ; :v:on (a-) #-1 swap store ; :v:off (a-) #0 swap store ; :v:update (aq-) swap [ fetch swap call ] sip store ; :v:limit (alu-) [ [ dup fetch ] dip ] dip n:limit swap store ; (std) (buffer:) {{ 'Start var 'Ptr var :at @Start @Ptr ; :update @Ptr @Start store ; ---reveal--- :buffer:size (-n) at nip ; :buffer:end (-a) at n:inc n:add ; :buffer:start (-a) @Start ; :buffer:empty (-) #0 !Ptr update ; :buffer:add (na-) at a:store &Ptr v:inc update ; :buffer:get (a-) &Ptr v:dec at a:fetch update ; :buffer:set (a-) !Start #0 !Ptr update ; }} (std) (s:) (begins-with,ends-with) :~prepare dup s:length &swap dip ; :s:begins-with? (ss-f) ~prepare s:left &s:hash bi@ eq? ; :s:ends-with? (ss-f) ~prepare s:right &s:hash bi@ eq? ; (std) (s:) (contains/s?) '~tar var '~src var '~tar.l var '~src.l var :s:contains/s? (ss-f) [ s:keep [ s:length !~tar.l ] [ !~tar ] bi s:keep [ s:length !~src.l ] [ !~src ] bi #0 @~src.l @~tar.l n:sub n:inc [ @~src I @~tar.l s:middle @~tar s:eq? or ] indexed-times ] gc ; (std) (s:) (index/s) {{ 'tar var 'src var 'tar.l var 'src.l var ---reveal--- :s:index/s (ss-n) [ s:keep [ s:length !tar.l ] [ !tar ] bi s:keep [ s:length !src.l ] [ !src ] bi #65535 @src.l @tar.l n:sub n:inc [ @src I @tar.l s:middle @tar s:eq? [ I n:min ] if ] indexed-times ] gc ; }} (std) (bit:) (bit-access) :bit:get (vi-b) [ #1 swap shift-left and ] sip shift-right ; :bit:set (vi-v) #1 swap shift-left or ; :bit:clear (vi-v) #1 swap shift-left not and ; (std) (b:) (byte-addressing) 'Byte var :byte-mask (xn-b) #255 swap #8 n:mul dup [ shift-left and ] dip shift-right ; [ drop @Byte ] [ [ drop @Byte ] dip ] [ [ [ drop @Byte ] dip ] dip ] [ [ [ [ drop @Byte ] dip ] dip ] dip ] 'replacements d:create comma comma comma comma :replace &replacements n:add fetch call ; (std) (b:) (byte-addressing) :b:to-byte-address (a-a) #4 n:mul ; :b:unpack (c-bbbb) dup #255 and swap dup #8 shift-right #255 and swap dup #16 shift-right #255 and swap #24 shift-right #255 and ; :b:pack (bbbb-c) #24 shift-left swap #16 shift-left n:add swap #8 shift-left n:add swap n:add ; (std) (b:) (byte-addressing) :b:fetch (a-b) #4 n:divmod swap #4 n:divmod rot n:add fetch swap byte-mask ; :b:store (ba-) swap !Byte #4 n:divmod swap [ dup fetch b:unpack ] dip replace b:pack swap store ; (std) (pali) (assembler) 'Instructions d:create #30 comma #5861473 comma #5863578 comma #5863326 comma #5863323 comma #5863823 comma #5863722 comma #5863716 comma #5863524 comma #5863273 comma #5863275 comma #5863282 comma #5863772 comma #5863355 comma #5863640 comma #5863589 comma #5863424 comma #5863376 comma #5863820 comma #5863210 comma #5863821 comma #5863623 comma #5863314 comma #5863220 comma #5863686 comma #5863980 comma #5863812 comma #5863818 comma #5863288 comma #5863297 comma #5863485 comma :inst s:hash &Instructions swap a:index ; (std) (pali) (reserved) (std) (pali) (assembler) :~split (s-nnnn) dup #2 s:left inst swap dup #2 #2 s:middle inst swap dup #4 #2 s:middle inst swap #2 s:right inst ; :assemble:opcode (s-n) ~split b:pack ; :i (s-) assemble:opcode comma ; &comma \d (n-) &comma \r (n-) :s (s-) dup s:length comma &comma s:for-each ; (std) (reorder,_roll,_unroll) (restructuring-the-stack) {{ 'values d:create #27 allot :from s:length dup [ [ &values n:add store ] sip n:dec ] times drop ; :to [ n:inc ] [ s:length ] bi [ fetch-next $a n:sub n:inc &values n:add fetch swap ] times drop ; ---reveal--- :reorder (...ss-?) &from dip to ; }} :roll (abc-cab) swap &swap dip ; :unroll (cba-abc) roll roll ; (std) (reset) (quickly-empty-the-stack) :reset (...-) depth/data dup n:negative? [ n:abs [ #0 ] ] [ &drop ] choose times ; (std) (.s) (display-stack) {{ 'Data d:create #33 allot :gather depth/data dup &Data store-next swap [ store-next ] times drop ; :display &Data a:reverse [ n:put sp ] a:for-each nl ; :restore &Data a:reverse [ ] a:for-each ; ---reveal--- :.s (-) gather display restore ; }} (std) (debug/dump) {{ :digits (-s) '0123456789ABCDEF ; :to-digit (n-c) digits swap s:fetch ; :h. (n-) #16 n:divmod swap [ to-digit c:put ] bi@ sp ; :order 'abcd 'dcba reorder ; :bytes (n-n) dup b:unpack order #4 &h. times ; :display (nn-n) bytes sp n:put nl ; ---reveal--- :dump (an-) [ dup n:put tab fetch-next display ] times drop ; }} (std) (random-number-generator) (xorshift) #1 'seed var-n :n:random (-n) @seed dup #13 shift-left xor dup #17 shift-right xor dup #5 shift-left xor dup !seed ; :n:random-mod (n-n) n:random n:abs swap n:mod ; . Note: this works well for small projects, but lacks some . range due to ilo's lack of unsigned numbers. (std) (block-tools) :block:empty? (n-f) @Block [ set load block:buffer n:dec s:hash #-967633659 eq? ] dip !Block load ; :block:for-each (q-) @Blocks [ [ I set load block:buffer swap call ] sip ] indexed-times drop ; (std) (block-tools) {{ :prep (-ns) @Block swap s:keep #0 set ; :get (-s) load next block:buffer n:dec ; :match? (ss-sf) over s:begins-with? ; :last? (-f) @Block @Blocks n:dec eq? ; :select (ns-n) drop last? [ drop @Block ] -if ; ---reveal--- :block:first-matching (s-n) [ prep [ get match? last? or ] until select ] gc ; }} (std) (editor-ext) 'Line d:create #64 allot :e:copy (n-) e:to-line &Line #64 copy ; :e:paste (n-) e:to-line &Line swap #64 copy ; :e:cut (n-) dup e:copy #32 swap e:to-line #64 fill ; {{ :get '_ s:temp #64 over store [ n:inc #64 copy ] sip ; :update n:inc swap #64 copy ; :at e:to-line dup get ; ---reveal--- :e:indent at #62 s:left '__ s:prepend update ; :e:unindent at #62 s:right '__ s:append update ; }} (std) (editor-ext) :e:for-each-line (q-) #16 [ block:buffer n:dec I #64 n:mul #64 s:middle swap &call sip ] indexed-times drop ; :n (-) next list ; :p (-) prev list ; &list \l (std) (fixed-point) #100 'f:scale var-n (ff-f) &n:add \f:add (ff-f) &n:sub \f:sub (ff-f) :f:mul n:mul @f:scale n:div ; (ff-f) :f:div [ @f:scale n:mul ] dip n:div ; (----) :~pad @f:scale n:to-s s:length n:dec over n:to-s s:length n:sub [ $0 c:put ] times ; (f-) :f:put @f:scale n:divmod n:put $. c:put ~pad n:put ; (std) (invoke,_*) :invoke (ss-) dup d:exists? &nip [ swap needs ] choose d:lookup d:address fetch call ; :~title ("-n) s:get/token '(LOAD: s:prepend ') s:append ; :* ("-) ~title block:first-matching set load &[ call run &] call call ; . `invoke` takes a block set and a word to run, if the word is . found, it will load the block set, then run the word . `*` takes the name of a LOAD: block. This will have a title of. `(LOAD:name)` and will contain a list of words that load the . dependencies and active block set. (tools:blocks) (block-editor-reference) . `blocks` starts the editor on a set of tutorial/reference . blocks. :blocks (-) #1016 edit ; (tools:manual-viewer) #8,192 'man:start var-n #8,303 'man:end var-n #0 'man:cur var-n #0 'man:done var-n :man:page (-) @man:start @man:cur n:add set load list* ; :man:length (-n) @man:end @man:start n:sub ; :man:hints '(1)_prev__(2)_next__(0)_exit s:put tab c:get ; :man:display (-) @Block man:page !Block load man:hints ; :man:limit (-) @man:cur #0 man:length n:limit !man:cur ; :man:0 (n-n) dup $0 eq? [ #-1 !man:done ] if ; :man:1 (n-n) dup $1 eq? [ &man:cur v:dec ] if ; :man:2 (n-) $2 eq? [ &man:cur v:inc ] if man:limit ; :man:prepare (-) #0 !man:done ; :manual (-) man:prepare [ man:display man:0 man:1 man:2 @man:done ] until ; (listener) {{ 'Done var :bye? dup 'bye s:eq? ; :exit (n-) drop #-1 !Done ; ---reveal--- :listener (-) 'Hi!_Enter_`bye`_when_done. s:put nl #0 !Done [ s:get/token bye? &exit &interpret choose @Done ] until ; }} . This implements a tiny nested Forth listener for Konilo. It's . basically intended to allow some interactive use for sessions . started under the kowae launcher. Termina : A Vocabulary for Terminal Applications =============== There are two parts to Termina. The first is a set of words for interacting with a DEC compatible terminal. The second builds onthese to provide a scaffold for building textual, keyboard centric programs. (termina) (terminal-config) #74 'ti:width var-n #21 'ti:height var-n (termina) (support;_cursor_movement;_clear_screen) :vt:esc (-) #27 c:put ; :vt:csi (-) vt:esc $[ c:put ; :vt:home (-) vt:csi $H c:put ; :vt:row,col (nn-) vt:csi swap n:put $; c:put n:put $H c:put ; :vt:up (-) vt:csi n:put $A c:put ; :vt:down (-) vt:csi n:put $B c:put ; :vt:right (-) vt:csi n:put $C c:put ; :vt:left (-) vt:csi n:put $D c:put ; :vt:clear (-) vt:csi '2J s:put ; :vt:reset vt:csi '0m s:put ; (termina) (colors) :vt:set/color (n-) vt:csi n:put $m c:put ; (foreground_________background_____) :fg:black #30 vt:set/color ; :bg:black #40 vt:set/color ; :fg:red #31 vt:set/color ; :bg:red #41 vt:set/color ; :fg:green #32 vt:set/color ; :bg:green #42 vt:set/color ; :fg:yellow #33 vt:set/color ; :bg:yellow #43 vt:set/color ; :fg:blue #34 vt:set/color ; :bg:blue #44 vt:set/color ; :fg:magenta #35 vt:set/color ; :bg:magenta #45 vt:set/color ; :fg:cyan #36 vt:set/color ; :bg:cyan #46 vt:set/color ; :fg:white #37 vt:set/color ; :bg:white #47 vt:set/color ; (termina) (key-to-action-mapping) 'ti:Actions d:create #128 comma #128 allot :ti:set-action (qc-) &ti:Actions swap a:store ; :ti:reset-actions (-) #128 [ #0 I ti:set-action ] indexed-times ; :ti:get-action (c-q) &ti:Actions swap a:fetch ; :ti:perform-action (c-) ti:get-action dup n:-zero? &call &drop choose ; :ti:input (-) c:get ti:perform-action ; (termina) (keyboard-hints) {{ 'ti:Hints d:create #130 allot :empty (-s) '____________ ; :constrain (s-s) dup s:length #12 gt? [ #12 s:left ] if ; :pad (s-s) #32 empty n:inc #12 fill empty &n:inc bi@ over n:dec fetch copy empty ; :start (n-a) #13 n:mul &ti:Hints n:add ; :display (-) I n:inc dup #10 eq? [ drop #0 ] if dup n:put sp start s:put sp ; :clean (-) '_ s:temp constrain pad I start #13 copy ; ---reveal--- :ti:add-hint (sn-) #13 n:mul &ti:Hints n:add [ constrain pad ] dip #13 copy ; :ti:reset-hints (-) #10 &clean indexed-times ; :ti:hints #10 [ display I #4 eq? &nl if ] indexed-times ; }} (termina) (display) :ti:display/none ; &ti:display/none 'ti:Display var-n :ti:set-display (a-) !ti:Display ; :ti:reset-display (-) &ti:display/none ti:set-display ; :ti:display (-) vt:home @ti:Display call @ti:height #3 n:sub #0 vt:row,col @ti:width [ $- c:put ] times nl ti:hints nl ; (termina) (nested-applications-support) 'ti:ptrs d:create #0 comma #5 allot :ti:add-program (a-) &ti:ptrs v:inc &ti:ptrs @ti:ptrs a:store ; :ti:current (-a) &ti:ptrs @ti:ptrs a:fetch ; :ti:more? (-f) @ti:ptrs n:-zero? ; :ti:remove &ti:ptrs v:dec ; :ti:load (-) ti:current call !ti:Display ti:reset-hints call ti:reset-actions call ; (termina) (application-loop) 'ti:Done var :ti:done #-1 !ti:Done vt:reset nl ; :ti:done? @ti:Done ; :ti:application/run (-) [ #0 !ti:Done ti:display ti:input ti:done? ] until ti:remove ti:more? [ ti:load #0 !ti:Done ] if ; :ti:application (q-) ti:add-program ti:load ti:application/run ; (termina) (ti:help) {{ 'ti:Help var 'ti:Help/Prior var :ti:help/actions &ti:done $0 ti:set-action ; :ti:help/hints 'Quit #0 ti:add-hint ; :ti:help/display vt:clear vt:home @ti:Help set load list* ; ---reveal--- :ti:help (n-) @Block !ti:Help/Prior !ti:Help [ &ti:help/actions &ti:help/hints &ti:help/display ] ti:application @ti:Help/Prior set load ; }} (tools:catalogue) (variables,_actions) #0 'Page var-n &edit 'Editor var-n :constrain @Page #0 @Blocks #16 n:div n:dec n:limit !Page ; :action (n-) ti:done @Page #16 n:mul n:add @Editor call ; :catalogue:rename c:get $a n:sub @Page #16 n:mul n:add set load 0 save ; (tools:catalogue) (actions,_continued) :catalogue:list c:get $a n:sub @Page #16 n:mul n:add set load vt:clear vt:home list# sys:info nl 'Press_x_when_done s:put nl [ c:get $x eq? ] until ; :catalogue:jump n:get #16 n:div !Page constrain ; :catalogue:leap [ s:get/token s:keep #0 set load [ block:buffer n:dec over s:begins-with? next @Block @Blocks n:dec eq? or ] until drop prev ] gc @Block #16 n:div !Page constrain ; (tools:catalogue) (key-bindings) :catalogue:actions/a-i [ #0 action ] $a ti:set-action [ #1 action ] $b ti:set-action [ #2 action ] $c ti:set-action [ #3 action ] $d ti:set-action [ #4 action ] $e ti:set-action [ #5 action ] $f ti:set-action [ #6 action ] $g ti:set-action [ #7 action ] $h ti:set-action [ #8 action ] $i ti:set-action ; (tools:catalogue) (key-bindings) :catalogue:actions/j-p [ #9 action ] $j ti:set-action [ #10 action ] $k ti:set-action [ #11 action ] $l ti:set-action [ #12 action ] $m ti:set-action [ #13 action ] $n ti:set-action [ #14 action ] $o ti:set-action [ #15 action ] $p ti:set-action ; (tools:catalogue) (key-bindings) :catalogue:actions [ &Page v:dec constrain ] $1 ti:set-action [ &Page v:inc constrain ] $2 ti:set-action [ ti:done ] $0 ti:set-action catalogue:actions/a-i catalogue:actions/j-p [ catalogue:rename ] $8 ti:set-action [ catalogue:list ] $3 ti:set-action [ catalogue:jump ] $4 ti:set-action [ catalogue:leap ] $9 ti:set-action ; (tools:catalogue) (hints) :catalogue:hints 'Previous #1 ti:add-hint 'Next #2 ti:add-hint 'Display #3 ti:add-hint 'Rename #8 ti:add-hint 'Quit #0 ti:add-hint 'Jump #4 ti:add-hint 'Leap #9 ti:add-hint ; (tools:catalogue) (display) {{ :key I $a n:add c:put '_|_ s:put ; :entry (-n) @Page #16 n:mul I n:add ; :title (-) entry set load block:buffer n:dec #64 over store s:put ; ---reveal--- :catalogue:display vt:clear vt:home #16 [ key title '_|_ s:put entry n:put nl ] indexed-times ; }} (tools:catalogue) (top-level) :catalogue (-) [ &catalogue:actions &catalogue:hints &catalogue:display ] ti:application ; &catalogue \catalog tools:describe This adds a word, `describe`, that scans the blocks for glossarydata. It takes a word name from the input stream, and looks for a block with a title of `Glossary: wordname` In example, to display the glossary data for `s:put`, you would run: describe s:put The output strips blank lines. Note that as this requires one block per word it is not a space efficient tool. You will need around 250 blocks to cover the core language, and many more to cover everything. (tools:describe) (glossary-lookups) {{ :empty? (-f) #-1 I #2 n:add e:to-line #64 [ fetch-next #32 eq? swap &and dip ] times drop ; ---reveal--- :describe:line (-) empty? [ I #2 n:add e:line ] -if ; :describe:word (s-) @Block swap [ 'Glossary:_ s:prepend '_ s:append s:keep @Blocks [ I set load block:buffer n:dec over dup s:length &swap dip s:left &s:hash bi@ eq? [ nl #13 &describe:line indexed-times nl ] if ] indexed-times drop ] gc !Block load ; :describe ('-) s:get/token s:temp describe:word ; }} (tools:manual) (display) #3,792 'manual:start var-n #3,891 'manual:end var-n 'manual:page var :manual:display @Block vt:clear vt:home @manual:page @manual:start n:add !Block load list* !Block ; :manual:constrain-page @manual:page #0 @manual:end @manual:start n:sub n:dec n:limit !manual:page ; (tools:manual) (hints) :manual:hints 'Prior #1 ti:add-hint 'Next #2 ti:add-hint 'Quit #0 ti:add-hint ; (tools:manual) (key-bindings) :manual:prev &manual:page v:dec manual:constrain-page ; :manual:next &manual:page v:inc manual:constrain-page ; :manual:actions &manual:prev $1 ti:set-action &manual:next $2 ti:set-action &ti:done $0 ti:set-action ; (tools:manual) (top-level) :manual [ &manual:actions &manual:hints &manual:display ] ti:application ; tuhi - a terminal block editor This is designed to be similar in spirit to the basic editor in Konilo, but makes use of the (termina) words to present a hotkeydriven interface for editing. Tuhi has two display modes: - plain text shown as a single color - source code shown with syntax highlighting Syntax mode will be used if the block starts with a "(" and `tuhi:cfg/syntax` is set to true (non-zero). In other cases the plain text mode is used. (tuhi) (configuration) &fg:cyan 'tuhi:cfg/colors,line# var-n &bg:black 'tuhi:cfg/colors,bg var-n &fg:green 'tuhi:cfg/colors,fg var-n #-1 'tuhi:cfg/syntax var-n #0 'tuhi:cfg/status var-n (tuhi) (list:syntax) (default-colors) :~colon bg:black fg:red ; (: :~immed bg:black fg:green ; (word:_[_]_; :~number bg:black fg:cyan ; (# :~char bg:black fg:yellow ; ($ :~string bg:black fg:white ; (' :~pointer bg:black fg:magenta ; (& :~comment bg:blue fg:white ; (( :~var bg:black fg:magenta ; (@_or_! :~normal bg:black fg:green ; '~SigilColors d:create #8 comma &~colon comma &~number comma &~char comma &~string comma &~pointer comma &~comment comma &~var comma &~var comma (tuhi) (list:syntax) (helpers) ':#$'&(@! s:keep \~Sigils :~sigil? (c-cf) &~Sigils over s:contains? ; :~color-sigil (c-c) &~Sigils over s:index/c &~SigilColors swap a:fetch call ; :~space? (c-cf) dup #32 eq? ; '~last var (tuhi) (list:syntax) (display) :~prepare (n-an) #64 n:mul block:buffer n:add #64 #32 !~last ; :e:line/syntax (n-) ~prepare [ fetch-next ~sigil? [ @~last #32 eq? [ ~color-sigil ] if ] if ~space? [ @~last #32 -eq? [ ~normal ] if ] if dup !~last c:put ] times vt:reset $| c:put nl drop ; :~line# I dup #10 lt? &sp if n:put sp ; :list:syntax (-) #16 [ ~line# I e:line/syntax ] indexed-times ; (tuhi) (display) {{ :status @tuhi:cfg/status &sys:info if ; :colorize call ; :line# @tuhi:cfg/colors,line# colorize I $a n:add c:put ; :sep vt:reset '_|_ s:put ; :text @tuhi:cfg/syntax block:buffer fetch $( eq? and [ I e:line/syntax ] [ @tuhi:cfg/colors,bg @tuhi:cfg/colors,fg &colorize bi@ I e:to-line #64 [ fetch-next c:put ] times drop vt:reset $| c:put nl ] choose ; :reset @tuhi:cfg/syntax [ bg:black fg:white ] if ; ---reveal--- :tuhi:display (-) vt:clear vt:home #16 [ line# sep text reset ] indexed-times status ; }} (tuhi) (key-actions) (lines) :tuhi:a #1 #5 vt:row,col 0 ; :tuhi:b #2 #5 vt:row,col 1 ; :tuhi:c #3 #5 vt:row,col 2 ; :tuhi:d #4 #5 vt:row,col 3 ; :tuhi:e #5 #5 vt:row,col 4 ; :tuhi:f #6 #5 vt:row,col 5 ; :tuhi:g #7 #5 vt:row,col 6 ; :tuhi:h #8 #5 vt:row,col 7 ; :tuhi:i #9 #5 vt:row,col 8 ; :tuhi:j #10 #5 vt:row,col 9 ; :tuhi:k #11 #5 vt:row,col 10 ; :tuhi:l #12 #5 vt:row,col 11 ; :tuhi:m #13 #5 vt:row,col 12 ; :tuhi:n #14 #5 vt:row,col 13 ; :tuhi:o #15 #5 vt:row,col 14 ; :tuhi:p #16 #5 vt:row,col 15 ; (jump/leap) :tuhi:4 s:get/line s:to-n !Block load ; :tuhi:9 s:get/line block:first-matching !Block load ; (tuhi) (key-actions) :tuhi:[ c:get $a n:sub e:unindent ; :tuhi:] c:get $a n:sub e:indent ; :tuhi:C c:get $a n:sub e:copy ; :tuhi:V c:get $a n:sub e:paste ; :tuhi:X c:get $a n:sub e:cut ; :tuhi:? #111 ti:help ; :tuhi:Q @tuhi:cfg/status not !tuhi:cfg/status ; :tuhi:N new ; (tuhi) (key-actions) (tuhi) (setup-key-actions-part-1) :tuhi:actions/1 (-) &prev $1 ti:set-action &next $2 ti:set-action &tuhi:4 $4 ti:set-action &run $5 ti:set-action &save $6 ti:set-action &load $7 ti:set-action &tuhi:9 $9 ti:set-action &ti:done $0 ti:set-action &tuhi:a $a ti:set-action &tuhi:b $b ti:set-action &tuhi:c $c ti:set-action &tuhi:d $d ti:set-action &tuhi:e $e ti:set-action &tuhi:f $f ti:set-action &tuhi:g $g ti:set-action &tuhi:h $h ti:set-action &tuhi:i $i ti:set-action &tuhi:j $j ti:set-action &tuhi:k $k ti:set-action &tuhi:l $l ti:set-action &tuhi:m $m ti:set-action &tuhi:n $n ti:set-action &tuhi:o $o ti:set-action &tuhi:p $p ti:set-action ; (tuhi) (setup-key-actions-part-2) :tuhi:actions/2 (-) &tuhi:[ $[ ti:set-action &tuhi:] $] ti:set-action &tuhi:C $C ti:set-action &tuhi:V $V ti:set-action &tuhi:X $X ti:set-action &tuhi:Q $Q ti:set-action &tuhi:? $? ti:set-action &tuhi:N $N ti:set-action ; :tuhi:actions (-) tuhi:actions/1 tuhi:actions/2 ; (tuhi) (hints) :tuhi:hints (-) 'Previous #1 ti:add-hint 'Next #2 ti:add-hint 'Jump #4 ti:add-hint 'Run #5 ti:add-hint 'Save #6 ti:add-hint 'Load #7 ti:add-hint 'Leap #9 ti:add-hint 'Quit #0 ti:add-hint ; (tuhi) (main-loop) :tuhi (-) [ &tuhi:actions &tuhi:hints &tuhi:display ] ti:application ; tuhi shortcuts ================================================= a - p line entry X cut C copy V paste [ un-indent line ] indent line Q toggle status line N erase block contents ? display this help screen nonix : a unix-inspired set of words for working with the blocks This provides: +--------+--------------+-------------------------------------+ | cp | src dest | copy block src to block dest | | mv | src dest | move block src to block dest | | rm | block | erase block | | cat | block | display contents of a block (text) | | locate | text | show blocks starting with text | | df | | show usage stats | | xcp | src dest num | copy num blocks from src to dest | | xmv | src dest num | move num blocks from src to dest | | xrm | start num | remove num blocks starting at start | +--------+--------------+-------------------------------------+ (nonix) (basic-commands) :cp n:get set load n:get set save ; :rm n:get set new save ; :mv n:get dup set load n:get set save set new save ; :cat n:get set load list* ; :locate s:get/token s:temp [ s:keep @Blocks [ I set load block:buffer n:dec over s:begins-with? [ I n:put tab #0 e:line ] if ] indexed-times drop ] gc ; :df:usage (-nn) #0 #0 @Blocks [ I block:empty? &n:inc [ &n:inc dip ] choose ] indexed-times ; :df (-) df:usage [ 'Used:___ s:put n:put nl ] [ 'Unused:_ s:put n:put nl ] bi* ; (nonix) (extended-commands) {{ :relocate over set load dup set save ; :erase over set new save ; :next &n:inc bi@ ; :args n:get n:get n:get ; ---reveal--- :xmv ("from,to,count") args [ relocate erase next ] times drop-pair ; :xcp ("from,to,count") args [ relocate next ] times drop-pair ; }} :clear (-) vt:clear vt:home ; (nonix) (extended-commands) :xrm ("start,count") n:get n:get swap set [ new save next ] times ;