dos_compilers/DX-FORTH v430/TED.F

452 lines
11 KiB
FortranFixed
Raw Permalink Normal View History

2024-07-09 18:07:02 +02:00
\ TED.F
\
\ TED - A Tiny Text Editor for DX-Forth
\
\ Based on the HT-68K editor by J.Bartel
\
\ The HELP screen is only compiled for the
\ turnkey version
\
\ ^E Up cursor ^R Prev page
\ ^X Down cursor ^C Next page
\ ^D Right cursor ^G Del next char
\ ^S Left cursor ^H Del prev char
\ ^L Restore line ^M New line
\ ^T Erase to EOL ^Y Delete line
\ ^U Exit editor ^Z Function
\ ^ZC Clear text ^ZH Help
\ ^ZR Read file ^ZW Write file
\
\ Revision
\ 2016-09-25 es updated for DX-Forth
\ 2015-06-03 es specify a filename
\ 2015-12-09 es join lines with ^G or DEL
\ 2017-01-25 es replace EXIT THEN with END
forth definitions decimal
0 \ true for turnkey
( *) dup [if] application [then]
cr .( loading TED Text Editor )
\ Running DX-Forth for CP/M or DOS ?
: CPM? ( -- f ) $111 @ $4683 = ;
[undefined] ZCOUNT [if]
: ZCOUNT ( a -- a u ) dup -1 0 scan drop over - ;
[then]
[undefined] ZPLACE [if]
: ZPLACE ( a -- a u ) 2dup + >r swap cmove 0 r> c! ;
[then]
[undefined] PACK [if]
: PACK ( a u a2 -- a2 ) dup >r place r> ;
[then]
[undefined] TOKEN [if]
: TOKEN ( "name" -- c-addr u ) bl word count ;
[then]
\ Video terminal specific
79 value XMAX \ #columns - 1
24 value YMAX \ #rows - 1
\ INSERT-LINE ( -- ) insert blank line at cursor;
\ remaining rows scroll down
\ DELETE-LINE ( -- ) delete line at cursor;
\ remaining rows scroll up
\ CLEAR-LINE ( -- ) blank from cursor to end of line
\ pointer operations
: 1+! ( a -- ) 1 swap +! ;
: 1-! ( a -- ) -1 swap +! ;
: C@+ ( a -- c ) dup @ c@ swap 1+! ;
: C!+ ( c a -- ) tuck @ c! 1+! ;
: -C@ ( a -- c ) dup 1-! @ c@ ;
: -C! ( c a -- ) dup 1-! @ c! ;
\ max line length
132 constant COLS
0 value YBOT \ edit bottom row
0 value BUF \ edit buffer addr
0 value BUFE \ edit buffer end + 1
0 value TBUF \ text buffer addr
0 value LINES \ line count
0 value MEM \ top of memory
0 value FNAM \ filename buffer addr
0 value FID \ file handle
variable COL \ current column#
variable LIN \ current line#
variable LADR \ current line addr
variable LTOP \ absolute line# at top of screen
variable LPOS \ current line# relative to top of screen
variable BPOS \ address of char in edit buffer
variable NXT \ next free addr in text (contains 0)
variable UPD \ edit buffer change flag
variable XF \ quit flag
: UKEY ( -- c ) key upcase ;
: LMAX ( -- n ) lines 1- 0 max ;
: GOXY ( x y -- ) 1+ at-xy ;
: CXY ( -- ) col @ XMAX min lpos @ goxy ;
: MSG ( -- ) 0 0 at-xy clear-line ;
: CHGD ( -- ) upd on ;
: CONT ( -- ) xf off
." Press a key to continue " key drop ;
: .FIL ( -- ) fnam count 20 min type ;
: .POS ( -- )
13 0 at-xy lin @ 1+ u.
22 0 at-xy col @ 1+ u. cxy ;
: .HD ( -- ) msg 10 0 at-xy
[ dup ] [if]
." Ln Cl ^ZH Help File "
[else]
." Ln Cl File "
[then]
.fil .pos ;
: .ERR ( a u -- ) msg .fil space space type cont .hd ;
: SURE? ( a u -- f )
msg type ." Are you sure? " ukey [char] Y = ;
: LINE ( -- a u ) ladr @ zcount ;
: .LINE ( -- ) line XMAX 1+ min type ;
: .RT ( -- ) \ display string right of cursor
bpos @ bufe over - XMAX 1+ bpos @ buf - - min type ;
: ROOM? ( -- f ) bufe 1- c@ bl = ;
: LINE@ ( -- lin adr ) lin @ ladr @ ;
: LINE! ( lin adr -- ) ladr ! lin ! ;
: GOTOP ( -- ) tbuf ladr ! lin off ;
: CURTOP ( -- )
gotop ltop off col off lpos off ;
\ clear text, filename, reset cursor
: -TXT ( -- ) tbuf dup 1- 3 erase ( nulls )
1+ nxt ! 1 to lines 0 fnam c! curtop ;
: SETUP ( -- )
[ cpm? ] [if]
$168 c@ 1- to XMAX
$169 c@ 1- dup to YMAX 2- to YBOT
[else]
get-window ( x1 y1 x2 y2 )
rot - dup to YMAX 2- to YBOT
swap - to XMAX
[then]
application here unused + to mem pad 80 +
dup to fnam 80 + dup to buf COLS + dup to bufe
2+ dup to tbuf mem u> abort" no space" -txt ;
: INSC ( c -- ) \ insert char in buf
bpos @ dup 1+ bufe over - 1+ cmove>
bpos c!+ ;
: LU ( -- ) \ go up one line in text
lin 1-!
ladr dup 1-! begin dup -c@ 0= until 1+! ;
: LD ( -- ) \ go down one line in text
lin 1+! ladr begin dup c@+ 0= until drop ;
: SETLIN ( n -- ) \ setup for line n
tbuf over 0 ?do zcount + 1+ loop
ladr ! lin ! ;
: LINES+ ( -- ) lines 1+ to lines ;
: LINES- ( -- ) lines 1- to lines ;
: ?MEM ( -- )
nxt @ mem u< not if s" no space" .err then ;
: REPL ( a u -- ) \ replace line in text
>r line r@ over - >r
over + dup r@ + nxt @ 1+ dup >r
2 pick - move 2r> + dup off nxt !
r> cmove ?mem ;
: BSTR ( -- a u ) \ string in buffer
buf bufe over - -trailing ;
: LEAV ( -- ) \ leave the line we are on
upd @ if bstr repl then upd off ;
: ENTER ( -- ) \ start changes on this line
line buf dup COLS blank swap cmove
buf col @ + bpos ! upd off ;
: .ALL ( -- ) \ update screen
leav enter
page line@
ltop @ dup setlin
lmax swap - YBOT min
1+ 0 ?do 0 i goxy .line ld loop
line! .hd cxy ;
: SLN ( ltop lin -- )
>r 0 max lmax min dup r> max lmax min
dup setlin over - lpos ! ltop ! .all ;
: PU ( -- ) \ ^R page up
lin @ if
leav ltop @ YBOT - lin @ YBOT - sln
then ;
: PD ( -- ) \ ^C page dn
lin @ lines < if
leav ltop @ YBOT + lin @ YBOT + sln
then ;
: SU ( -- ) \ scroll up, new line at bottom
0 0 goxy delete-line 0 YBOT dup lpos ! goxy ;
: SD ( -- ) \ scroll down, new line at top
0 0 goxy insert-line lpos off ;
-? : UP ( -- ) \ ^E line up
lin @ if
leav lu
lin @ ltop @ 1- = if
sd .line ltop 1-!
else
lpos 1-!
then
enter .pos
then ;
: DN ( -- ) \ ^X line dn
lin @ lines < if
leav ld
lin @ ltop @ YBOT 1+ + = if
su .line ltop 1+!
else
lpos 1+!
then
enter .pos
then ;
: RT ( -- ) \ ^D right
col @ XMAX < if
col 1+! bpos 1+! .pos
then ;
: LFT ( -- ) \ ^S left
col @ if
bpos 1-! col 1-! .pos
then ;
: TAB ( -- ) \ ^I tab
4 col @ over mod - 0 do rt loop ;
: NLN ( -- ) \ ^M new line
room? if
13 insc chgd leav
ladr begin dup c@+ 13 = until 0 over -c! 1+!
lines+ lin 1+!
clear-line col off enter
lpos @ YBOT = if
su ltop 1+!
else
lpos 1+! insert-line cxy
then
.all
then ;
: DEL ( -- ) \ ^G del next
bpos @ bstr + < if ( del char)
bpos @ dup 1+ swap bufe bl over c! over - 1+ cmove
.rt cxy chgd
else ( join line)
chgd leav line COLS over - >r
+ dup 1+ zcount r> min rot zplace .all
then ;
: BS ( -- ) \ ^H del prev
col @ if lft del then ;
: DLN ( -- ) \ ^Y del line
lin @ lines < if
ladr @
ld enter 13 ladr -c!
ladr !
chgd leav enter
lines- lin 1-!
delete-line
ltop @ YBOT + lines < if
line@
ltop @ YBOT + setlin 0 YBOT goxy .line
line!
then
.pos
then ;
: RST ( -- ) \ ^L restore line
0 lpos @ goxy clear-line .line cxy
enter ;
: DEOL ( -- ) \ ^T delete to EOL
bufe bpos @ - blank
clear-line cxy chgd ;
: CHAROK ( c -- )
dup bl 126 between room? and if
dup insc dup emit col 1+! .rt
.pos chgd
then drop ;
: CLR ( -- ) \ ^ZC
s" *** Clear text: " sure? if leav -txt then
.all ;
: GETN ( -- a u ) msg ." Filename: "
pad dup XMAX 10 - accept ;
: STNAM ( a u -- a u )
2dup fnam pack count upper 0 to fid ;
: CLOSF ( -- ) fid ?dup if close-file drop then ;
: CLN ( a u -- ) \ ctl chars to spaces
over + swap ?do i c@ bl max i c! loop ;
: (RD) ( a u -- )
stnam r/w open-file throw to fid
0 to lines tbuf dup off dup 1+ nxt !
( a) begin
dup COLS 2dup + mem u> throw
fid read-line throw ( a u' f )
while
2dup cln + 0 over c! ( null)
1+ dup nxt ! lines+
repeat 2drop nxt @ off ;
: RD ( a u -- )
s" F" +ext ( append .F extension if none )
leav ['] (rd) catch if
2drop s" load/size error" .err -txt
then closf curtop .all ;
: (WR) ( a u -- )
stnam r/w create-file throw to fid
tbuf begin ( a)
dup nxt @ u<
while
zcount 2dup fid write-line drop + 1+
repeat drop ;
: WR ( a u -- )
leav ['] (wr) catch if
2drop s" save error" .err
then closf .all ;
: ZRD ( -- ) \ ^ZR read file into text buffer
getn rd .hd ;
: ZWR ( -- ) \ ^ZW write text to file
getn wr .hd ;
: SAV ( -- )
fnam count dup 0= if 2drop getn then wr ;
dup [if]
: HLP ( -- ) \ ^ZH help
leav page 14 spaces ." Help Menu"
cr ." ^E Up cursor ^R Prev page"
cr ." ^X Down cursor ^C Next page"
cr ." ^D Right cursor ^G Del next char"
cr ." ^S Left cursor ^H Del prev char"
cr ." ^L Restore line ^M New line"
cr ." ^T Erase to EOL ^Y Delete line"
cr ." ^U Exit editor ^Z Function"
cr ." ^ZC Clear text ^ZH Help"
cr ." ^ZR Read file ^ZW Write file"
cr cr cont .all ;
[then]
: FN ( -- ) \ ^Z function
[ dup ] [if]
msg ." *** (R)ead, (W)rite, (C)lear, (H)elp ? " ukey
[char] H of hlp end \ ^ZH help
[else]
msg ." *** (R)ead, (W)rite, (C)lear ? " ukey
[then]
[char] C of clr end \ ^ZC clear
[char] R of zrd end \ ^ZR read
[char] W of zwr end \ ^ZW write
drop .hd ;
: DONE ( -- ) \ ^U Quit editor
msg ." *** Exit: (S)ave, (Q)uit ? " ukey
[char] Q of xf on end
[char] S of sav xf on end
drop .hd ;
: KMAP ( c1 -- c2 ) \ map in arrow keys etc
[ cpm? ] [if]
$14F c@ of 5 end $150 c@ of 24 end
$151 c@ of 4 end $152 c@ of 19 end
127 of 7 end
[else]
200 of 5 end 208 of 24 end
205 of 4 end 203 of 19 end
211 of 7 end
210 of 22 end 201 of 18 end
209 of 3 end 199 of 17 end
[then] ;
: CMD ( -- ) key kmap
3 of pd ( ^C) end 4 of rt ( ^D) end
5 of up ( ^E) end 7 of del ( ^G) end
8 of bs ( ^H) end 9 of tab ( ^I) end
12 of rst ( ^L) end 13 of nln ( ^M) end
18 of pu ( ^R) end 19 of lft ( ^S) end
20 of deol ( ^T) end 21 of done ( ^U) end
24 of dn ( ^X) end 25 of dln ( ^Y) end
26 of fn ( ^Z) end
charok ;
\ Load & edit textfile addr len. If len=0 don't load.
: (TED) ( line addr len -- )
setup page .hd
?dup if
rd ( line ) 1- dup 7 - swap sln
else 2drop then
enter xf off begin cmd xf @ until
0 YMAX at-xy cr cr ;
( *) [if]
\ Turnkey version
-? : TED ( -- ) 1 cmdtail (ted) ; turnkey ted ted bye
[else]
\ Resident version
-? : TED ( "filename[.F]" -- ) token dup if 1 -rot
else 2drop loadline @ lastfile then (ted) ;
\ aka TED EDIT
behead cpm? cmd
[then]
forth definitions application