Artifact ec6f056c2438ce460bb5d4d283574fc464532901
File editor.rx part of check-in [545ff85ff0] - editor: use whend combinator instead of "dup nn = [ drop .., ] drop .., ifTrue" by crc on 2011-11-25 17:06:02. [annotate]
( retro editor v11-2011.11.24 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
( Key Action )
( --- ------------------------------------------------- )
( k Move cursor up )
( h Move cursor left )
( j Move cursor down )
( l Move cursor right )
( [ Switch to previous block )
( ] Switch to next block )
( e Evaluate current block )
( E Evaluate all blocks )
( m Move cursor to start of next line )
( K Move cursor to top line of block )
( H Move cursor to start of current line )
( J Move cursor to last line of block )
( L Move cursor to end of current line )
( M Center cursor on current line )
( z Exit RxE )
( { Load "blocks" )
( } Save "blocks" )
( TAB Switch between edit and command mode )
( ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
chain: editor'
{{
2 elements buffer count
: restore ( - ) &getc :devector ok ;
: get ( -c ) @buffer @ ;
: next ( -c ) @count [ count -- get buffer ++ ] [ 32 restore ] if ;
: replace ( - ) &next &getc :is ;
: eval ( an- ) !count !buffer replace ;
7 elements #blocks offset blk line column mode active
: toBlock 1600 * @offset + ;
: thisBlock @blk toBlock ;
: toLine 80 * thisBlock + ;
( check boundaries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
: top ( - ) 0 !line ;
: bot ( - ) 19 !line ;
: beg ( - ) 0 !column ;
: end ( - ) 79 !column ;
: mid ( - ) 41 !column ;
: 1st ( - ) 0 !blk ;
: bounds ( - )
@column -1 = [ end line -- ] ifTrue
@column 80 = [ beg line ++ ] ifTrue
@line -1 = [ top blk -- ] ifTrue
@line 20 = [ bot blk ++ ] ifTrue
@blk -1 = [ 1st ] ifTrue
@blk @#blocks >= [ blk -- ] ifTrue ;
( display a block ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
: rows 20 [ dup 80 [ @ putc ] ^types'BUFFER each@ 80 + cr ] times ;
: mode? @mode [ "INS" ] [ "CMD" ] if ;
: .block @column @line @blk mode? "(%s) #%d - %d:%d " puts ;
: bar 80 [ '- putc ] times cr ;
: vb @blk toBlock rows drop bar .block ;
: (v) ( - ) clear vb ;
: pos ( -cl ) @column @line ;
: get ( cl-a ) toLine + ;
: va ( a-va ) dup @ swap ;
: c! ( a- ) '* swap ! ;
: show ( va- ) dup c! (v) ! ;
: display ( - ) bounds pos get va show ;
( input processing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
: advance? ( - ) line ++ @line 20 >= [ 0 !line blk ++ ] ifTrue 0 !column ;
: del ( - )
@column dup
[ dup 80 =
[ drop !column display 0 ]
[ 32 over @line get ! 1+ -1 ] if
] while ;
: remap ( c-c )
[ 9 = ] [ 27 ] whend
[ 13 = ] [ 0 ] whend
[ 10 = ] [ 0 advance? display ] whend ;
: input ( - )
repeat
display
@mode 0; drop
getc 0;
dup 27 <> 0; drop
dup 8 = [ drop column -- display ] [ pos get ! column ++ ] if
again ;
: rxe.in ( -c ) mode on remapping [ remapping off input ] preserve mode off ;
: match ( c- ) "$$_" dup [ 2 + ! ] dip find [ @d->xt do ] &drop if ;
: edit? ( c-c ) dup 27 = [ rxe.in drop ] ifTrue ;
( various support bits ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
: new ( - ) @offset 32 1600 @#blocks * fill ;
: e ( - ) thisBlock 1600 eval ;
: ea ( - ) @offset @#blocks 1600 * eval ;
: run ( - )
active on &remap &remapKeys :is clear
[ display getc edit? match @active ] while ;
---reveal---
: setBlocks ( n- ) !#blocks @memory 1600 @#blocks * - !offset new ;
: edit ( - )
@ch 22 >= @cw 80 >= and
&run [ "requires an 80x22 or greater display, sorry!\n" puts ] if ;
: $$k line -- ;
: $$h column -- ;
: $$j line ++ ;
: $$l column ++ ;
: $$m $$k beg ;
: $$K top ;
: $$H beg ;
: $$J bot ;
: $$L end ;
: $$M mid ;
: $$D del ;
: $$[ blk -- ;
: $$] blk ++ ;
: $${ @offset "blocks" ^files'slurp drop ;
: $$} @offset @#blocks 1600 * "blocks" ^files'spew drop ;
: $$e active off e ;
: $$E active off ea ;
: $$z active off ;
128 setBlocks
}}
;chain
global
with editor'
doc{
============
Retro Editor
============
--------
Overview
--------
The Retro Editor is a block editor for use with Retro.
For most users, files are a better choice. However there are
at least two cases where you may want or need to use them:
* keeping sources embeded in the image
* if you are using a VM that lacks file i/o
-------
Loading
-------
::
include editor.rx
-----------
Quick Guide
-----------
Starting
========
Once loaded, you'll need to start it using **edit**:
::
edit
The Interface
=============
You'll see a screen looking something like:
::
*
--------------------------------------------------------------------------------
(CMD) #0 - 0:0
The asterisk at the top is the cursor. The line at the
bottom marks the end of the current block. Below the line
is a status row, showing the current mode (CMD or INS), the
current block number, and the current row and column.
Exiting
=======
Press *z*. This should return you to the Retro listener.
Navigation
==========
Restart the editor with **edit**.
The following keys can be used to navigate through the
blocks.
+-----+--------------------------------------------+
| Key | Used for |
+=====+============================================+
| i | Move cursor up |
+-----+--------------------------------------------+
| j | Move cursor left |
+-----+--------------------------------------------+
| k | Move cursor down |
+-----+--------------------------------------------+
| l | Move cursor right |
+-----+--------------------------------------------+
| [ | Switch to previous block |
+-----+--------------------------------------------+
| ] | Switch to next block |
+-----+--------------------------------------------+
| m | Move cursor to start of next line |
+-----+--------------------------------------------+
| I | Move cursor to top line of block |
+-----+--------------------------------------------+
| J | Move cursor to start of current line |
+-----+--------------------------------------------+
| K | Move cursor to last line of block |
+-----+--------------------------------------------+
| L | Move cursor to end of current line |
+-----+--------------------------------------------+
| M | Center cursor on current line |
+-----+--------------------------------------------+
Entry Mode
==========
Use the *tab* key to switch to entry mode, and again to
switch back to command mode.
Evaluating Code
===============
When you're ready to process the code you've entered, use
the following keys to pass the code to the listener.
**Note:** *This will stop the editor from running. You will
have to restart it manually after evaluating code.*
+-----+--------------------------------------------+
| Key | Used for |
+=====+============================================+
| e | Evaluate current block |
+-----+--------------------------------------------+
| E | Evaluate all blocks |
+-----+--------------------------------------------+
Loading And Saving
==================
Blocks are stored in the image file. If you are using a VM
that supports the files' vocabulary, you can use the following
keys to import and export the blocks to regular files.
+-----+--------------------------------------------+
| Key | Used for |
+=====+============================================+
| { | Load the contents of "blocks" |
+-----+--------------------------------------------+
| } | Store all blocks into "blocks" |
+-----+--------------------------------------------+
-----------
Misc. Notes
-----------
Retro's blocks are 1600 cells in length each. They are displayed as
80 columns and 20 rows.
}doc