forked from skx/z80-playground-cpm-fat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
EDLIN.SCR
1 lines (1 loc) · 18 KB
/
EDLIN.SCR
1
\ EDLIN - Information 970821es A simple line-oriented screen editor. It uses the same commands as the editor in 'Starting Forth' and is a slightly modified version of the editor that appeared in Forth Dimensions III/3. Note: Editing of screens with a line editor is rather tedious and is best avoided (see EDITOR.SCR for a full-screen editor). However it does have the advantage that it does not need to be installed and works with any video terminal. \ EDLIN - Load screen 970821es FORTH DEFINITIONS DECIMAL CR .( loading Line Editor ) 2 15 THRU CR .( loading Screen Utilities ) 16 LOAD \ EDLIN - EDITOR R# C/L DELIM 970821esSYSTEM VOCABULARY EDITOR EDITOR DEFINITIONS VARIABLE R# \ cursor position 64 CONSTANT C/L \ columns per line CHAR ^ CONSTANT DELIM \ delimiter used by editor \ EDLIN - TEXT MATCH 970821es\ Get string from input stream and save to pad : TEXT ( char -- ) HERE 65 BLANK WORD PAD 65 CMOVE ; \ String search : MATCH ( adr len sadr slen -- flag cursor-offs ) DUP >R 2 PICK >R SEARCH ROT DROP SWAP OVER IF 2R> ROT - + ELSE 2R> 2DROP THEN ; \ EDLIN - LINE #LOCATE #LEAD #LAG 970821es\ Start address of line : LINE ( ln -- adr ) SCR @ BLOCK SWAP C/L * + ; \ Cursor offset and line : #LOCATE ( -- offs ln ) R# @ C/L /MOD ; \ Line address and offset to cursor : #LEAD ( -- adr offs ) #LOCATE LINE SWAP ; \ Cursor address and count after cursor : #LAG ( -- adr count ) #LEAD DUP >R + C/L R> - ; \ EDLIN - -MOVE BUF-MOVE >LINE# FIND-BUF 970821es\ Move line from adr to new line : -MOVE ( adr ln -- ) LINE C/L CMOVE UPDATE ; \ Move pad text to buffer adr : BUF-MOVE ( adr -- ) PAD C@ IF ( not empty ) PAD SWAP C/L 1+ CMOVE ELSE DROP THEN ; \ Compute line from cursor position : >LINE# ( -- ln ) #LOCATE SWAP DROP ; \ Find buffer address : FIND-BUF ( -- adr ) PAD 80 + ; \ EDLIN - INSERT-BUF (HOLD) (KILL) (SPREAD) 970821es\ Insert buffer address : INSERT-BUF ( -- adr ) PAD 160 + ; \ Copy current line to insert buffer : (HOLD) ( ln -- ) LINE INSERT-BUF 1+ C/L DUP INSERT-BUF C! CMOVE ; \ Blank specified line : (KILL) ( ln -- ) LINE C/L BLANK UPDATE ; \ Spread screen starting at current line, line 15 is lost : (SPREAD) ( -- ) >LINE# DUP 1- 14 DO I LINE I 1+ -MOVE -1 +LOOP (KILL) ; \ EDLIN - (TOP) (R) SEEK-ERROR 1LINE 970821es\ Reset cursor position to top of screen : (TOP) ( -- ) 0 R# ! ; \ Replace current line with contents of search buffer : (R) ( -- ) >LINE# INSERT-BUF 1+ SWAP -MOVE ; \ Reset cursor position, display error message : SEEK-ERROR ( -- ) (TOP) FIND-BUF COUNT HERE PLACE 1 ABORT" not found" ; \ Scan current line for match with contents of find buffer : 1LINE ( -- flag ) #LAG FIND-BUF COUNT MATCH R# +! ; \ EDLIN - (SEEK) (DELETE) (F) 970821es\ Search rest of screen : (SEEK) ( -- ) BEGIN 1023 R# @ < IF SEEK-ERROR THEN 1LINE UNTIL ; \ Delete n characters backwards : (DELETE) ( n -- ) >R #LAG + R@ - #LAG R@ NEGATE R# +! #LEAD + SWAP CMOVE R> BLANK UPDATE ; \ Copy text to find buffer and search line : (F) ( -- ) DELIM TEXT FIND-BUF BUF-MOVE (SEEK) ; \ EDLIN - ? T X 970821es\ Display line and cursor position : ? ( -- ) CR SPACE #LEAD TYPE DELIM EMIT #LAG TYPE #LOCATE 2 .R SPACE DROP ; \ Type : T ( u -- ) C/L * R# ! ? ; \ Extract : X ( -- ) >LINE# DUP (HOLD) 15 DUP ROT DO I 1+ 15 MIN LINE I -MOVE LOOP (KILL) ; \ EDLIN - P U F E 970821es\ Put : P ( -- ) DELIM TEXT INSERT-BUF BUF-MOVE (R) ; \ Under : U ( -- ) C/L R# +! (SPREAD) P ; \ Find : F ( -- ) (F) ? ; \ Erase : E ( -- ) FIND-BUF C@ (DELETE) ? ; \ EDLIN - D TILL WIPE 970821es\ Delete : D ( -- ) (F) E ; \ Till : TILL ( -- ) #LEAD + DELIM TEXT FIND-BUF BUF-MOVE 1LINE 0= IF SEEK-ERROR THEN #LEAD + SWAP - (DELETE) ? ; \ Wipe : WIPE ( -- ) 16 0 DO I (KILL) LOOP ; \ EDLIN - S 970821es\ Search until block u-1 : S ( u -- ) DELIM TEXT FIND-BUF BUF-MOVE SCR @ DUP R# @ 2>R DO \ save current location I SCR ! (TOP) BEGIN 1LINE IF ? SCR @ 4 .R THEN 1023 R# @ < UNTIL KEY? IF \ any key to stop KEY DROP LEAVE THEN LOOP 2R> R# ! SCR ! ; \ EDLIN - I R 970821es\ Insert : I ( -- ) DELIM TEXT INSERT-BUF BUF-MOVE INSERT-BUF COUNT #LAG ROT OVER MIN >R R@ R# +! R@ - >R DUP HERE R@ CMOVE HERE #LEAD + R> CMOVE R> CMOVE UPDATE ? ; \ Replace : R ( -- ) E I ; \ EDLIN - M 970821es\ Move : M ( blk line -- ) SCR @ >R R# @ >R >LINE# (HOLD) SWAP SCR ! 1+ C/L * R# ! (SPREAD) (R) R> C/L + R# ! R> SCR ! ; \ EDLIN - (EDIT) EDIT WHERE 970821es\ Edit screen scr, placing cursor at offset : (EDIT) ( scr offs -- ) EDITOR SWAP CR LIST DUP R# ! C/L MOD CR T ; FORTH DEFINITIONS \ Edit screen u : EDIT ( u -- ) 0 [ EDITOR ] (EDIT) ; \ Edit screen where LOADing error occured : WHERE ( -- ) SCR 2@ SWAP [ EDITOR ] (EDIT) ; FORTH APPLICATION \ Utilities - L N B COPY 970806esFORTH DEFINITIONS DECIMAL SYSTEM \ Screen listing utilities : L ( -- ) SCR @ LIST ; \ list current screen : N ( -- ) 1 SCR +! ; \ next screen : B ( -- ) -1 SCR +! ; \ back screen \ Copy screen u1 to u2 : COPY ( u1 u2 -- ) SWAP BLOCK SWAP BUFFER 1024 CMOVE UPDATE SAVE-BUFFERS ; --> \ Utilities - COPIES 970806es\ Copy u3 screens from screen u1 to screen u2 : COPIES ( u1 u2 u3 -- ) SWAP 2 PICK - >R 1- OVER + CR ." Copy " OVER . ." thru " DUP . ." onto " OVER R@ + . ." thru " DUP R@ + . ." - continue? " Y/N 0= IF R> DROP ELSE R@ 0< IF 1+ SWAP 1 ELSE -1 THEN R> 2SWAP DO I 2DUP + OVER CR . ." -> " DUP . COPY KEY? IF KEY DROP LEAVE THEN OVER +LOOP THEN 2DROP ; APPLICATION