\ Full screen editor in forth-83. Based upon Henry 21Aug86 rsl vandys
\ Laxen's original. MODIFIED FOR ANY COMPUTER.
\ Ported to x86 eForth by Andy Valencia 11/2001
\ ----------------------------------------------------------------
\ Craig A. Lindley
\ Clockwork Software
\ 6 Sutherland Place
\ Manitou Springs, Co. 80829
\ ----------------------------------------------------------------
\ Reworked to have a vi-like command set and permit multiple
\ concurrent editing sessions. Andy Valencia 5/2003
\ Note that there *are* shadow screens with comments now.
only extensions \ true constant VIDEBUG? \ Debug variant?
[ifdef] VIDEBUG?
vocabulary vi2 also vi2 definitions Undebug [+debug]
[else]
vocabulary vi also vi definitions
[then]
\ To permit reentrancy across tasks, we use memory at "here"
\ to hold all editor state. This includes all local state like
\ cursor position and insertion state flags, and also the edited
\ buffer itself, since the one provided by "block" may be
\ reallocated when another task uses the block I/O subsystem.
\ Configuration for ANSI terminal vandys
7 constant BELL 9 constant TAB 8 constant TABcols
: beep BELL emit ;
\ Weird f83 stuff to emulate
: upc ( c -- c ) dup 96 > over 123 < and if 32 - then ;
: at ( y x -- ) swap at-xy ;
: edvar ( idx -- ) create cells , does> @ here + ;
0 edvar &mode 1 edvar &cur 2 edvar &badr
3 edvar &upd 4 edvar &arg 5 edvar &delta
6 edvar &findchar 7 edvar &cmdc 8 edvar &argvalid?
9 edvar &yank 10 edvar &srch>dir 11 edvar &findDir
12 edvar &srch>scr 13 edvar &scr
14 constant #edvars
create &id 12 allot &id 12 blank
variable 'insert variable 'overwrite variable 'command
SCRSIZ constant cps BLKROWS constant lps
BLKCOLS constant c/l
\ vandys
cps 1 - constant cps-1 cps 2 * constant cps*2
lps 1 - constant lps-1
27 constant ESC
80 constant BUFsize
84 constant BUFalloc
: textBuf pad BUFalloc + ;
: numBuf textBuf BUFalloc + ;
: searchBuf numBuf BUFalloc + ;
: prevsearchBuf searchBuf BUFalloc + ;
: blkBuf prevsearchBuf BUFalloc + ;
: yankBuf blkBuf BLKSIZ + ;
\ Next free location: yankBuf SCRSIZ +
\ vandys
: >line# c/l / ;
: line#> c/l * ;
: >bol ( n -- n ) >line# line#> ;
: >eol ( n -- n ) >bol c/l + 1- ;
: curpos ( -- n ) &cur @ ;
: +cur ( n -- ) &cur +! curpos 0 max cps-1 min &cur ! ;
: mvcur ( -- ) curpos c/l /mod at ;
: >bufadr ( n -- a ) &badr @ + ;
: bufpos ( -- a ) curpos >bufadr ;
\ vandys
: upd ( -- ) &upd on &delta inc ;
: ?prt ( c -- bool ) dup bl < swap 126 > or not ;
: mark &upd @ not if exit then
&id 0 >bufadr c/l + 11 - 11 cmove
blkBuf &scr @ block SCRSIZ 2* cmove update
&upd off &scr @ scr ! ;
: #tobol ( -- n ) curpos c/l mod ;
: #toeol ( -- n ) #tobol c/l swap - 1- ;
: bufmv ( asrc adest n -- ) rot >bufadr rot >bufadr rot
move upd ;
\ vandys
: position ( -- ) 0 lps-1 at c/l blot ;
: empty? ( n -- bool ) line#> >bufadr c/l -trailing nip 0= ;
: clrLine ( n -- ) >bufadr c/l blank upd ;
: exp ( -- ) curpos >bol dup dup c/l + cps over - bufmv clrLine ;
: shrink ( -- ) curpos >bol dup c/l + dup >r
swap cps r> - bufmv lps-1 line#> clrLine ;
\ vandys
: insertline ( -- ? ) lps-1 empty? not if beep false exit then
exp true ;
: deleteline shrink ;
: cempty? ( n -- ? ) >eol >bufadr c@ bl = ;
: inschar ( c -- ) curpos cempty? not if drop beep exit then
curpos dup 1+ #toeol bufmv bufpos c! upd ;
: delchar ( -- ) curpos dup 1+ swap #toeol bufmv
bl curpos >eol >bufadr c! upd ;
: deltoeol bufpos #toeol 1+ blank upd ;
: rarrow 1 +cur ;
: larrow -1 +cur ;
: uarrow c/l negate +cur ;
: darrow c/l +cur ;
\ vandys
: heading page
26 0 at ." *** Forth Full Screen Editor ***" ;
: inserting? &mode @ 'insert @ = ;
: breakline bufpos dup #toeol 1+ + #toeol 1+ move deltoeol ;
: curline ( -- u ) curpos >line# ;
: onlast? curline lps-1 = ;
: ret onlast? if beep exit then
inserting? if #toeol 1+ dup +cur insertline swap negate +cur
if breakline then then
curpos >line# 1+ line#> &cur ! ;
: quited 24 0 at-xy cr
." Edit session complete" sp0 @ sp! .ok quit ;
: exitupd mark save-buffers quited ;
: (>prev) ( a -- ) dup c@ 1+ prevsearchBuf swap move ;
: (<prev) ( a -- ) prevsearchBuf dup c@ 1+ >r swap r> move ;
: (padIn) ( a -- ) dup 1+ BUFsize 2dup blank expect
span @ ?dup if over c! (>prev) else (<prev) then ;
\ vandys
: scanfail r> drop 2drop drop 0 ;
: scan+= 2dup = if scanfail then
0 -rot do over i c@ = if leave then 1+ loop nip ;
: scan+<> 2dup = if scanfail then
0 -rot do over i c@ <> if leave then 1+ loop nip ;
: scan-= 2dup = if scanfail then
0 -rot do over i c@ = if leave then 1- -1 +loop nip ;
: scan-<> 2dup = if scanfail then
0 -rot do over i c@ <> if leave then 1- -1 +loop nip ;
: mvlwrd ( -- n ) bl 0 >bufadr bufpos scan-= >r
bl 0 >bufadr bufpos r@ + scan-<> r> + ;
: mvrwrd ( -- n ) bl cps-1 >bufadr bufpos scan+= >r
bl cps-1 >bufadr bufpos r@ + scan+<> r> + ;
\ vandys
: rword mvrwrd +cur ;
: lword mvlwrd +cur ;
: delchars ( n -- ) 0 do delchar loop ;
: dword mvrwrd bufpos #toeol 1+ -trailing
nip min delchars ;
: redraw &badr @ putpage ;
: clrscn 0 &cur ! bufpos cps blank upd ;
\ vandys
: getid &id 12 -trailing nip if exit then
cr ." Enter id: "
12 0 do 46 emit loop
12 0 do 8 emit loop
&id 12 expect ;
: init2 'command @ &mode ! 0 &cur ! redraw ;
: init &scr @ dup scr ! block blkBuf SCRSIZ 2* cmove
blkBuf &badr ! init2 ;
: rstedit discard &upd off init ;
: lstblk mark &scr @ dup 0> if 1- &scr ! init then ;
: nxtblk mark &scr inc init ;
\ vandys
\ A ForthOS block is 4k, and a screen is just shy of 2k. So
\ we use the first half of the block for the source, and the
\ second as a shadow.
: inShadow? ( -- bool ) &badr @ blkBuf <> ;
: edtshdw curpos inShadow? if blkBuf &badr !
else SCRSIZ &badr +! then init2 +cur ;
\ vandys
[ifdef] VIDEBUG? : kTAP ( c -- ) (locals).kTAP ; [then]
: (padTAP) dup ESC <> if kTAP exit then 1 throw ;
: (dopadIn) ( a -- a ) dup (padIn) ;
: padIn ( a -- <bool> ) 'tap @ swap ['] kTAP 'tap !
['] (dopadIn) catch 0= nip swap 'tap ! ;
\ vandys
: 1st 0 &cur ! ;
: middle lps-1 2/ line#> &cur ! ;
: lst lps-1 line#> &cur ! ;
: bol? ( -- ? ) #tobol 0= ;
: hldln curpos >bol >bufadr textBuf c/l cmove ;
: insln insertline not if exit then
textBuf curpos >bol c/l cmove ;
: begline curpos >bol &cur ! ;
: endline #toeol +cur bl bufpos dup c/l - swap scan-<>
1+ +cur ;
: startLine begline bufpos #toeol 1+ 0 do dup c@ bl <> if
i +cur unloop drop exit then 1+ loop drop ;
: rett onlast? not if #toeol 1+ +cur startLine then ;
: firstInsert startLine 'insert @ &mode ! ;
\ vandys
: status page
." Row:" curpos c/l / . ." Column: " #tobol . cr
." Screen #:" &scr ? &upd @ if ." (Modified)" else ." (Virgin)" then cr
." Line hold buffer contents:" cr
textBuf c/l -trailing type cr
cr ." Hit a key to continue: " key drop redraw ;
: joinLine
endline curpos dup #toeol 1+ >r ret startLine curpos swap
r> #toeol 1+ min dup >r bufmv r> delchars
curpos begline curpos swap - delchars curpos >line# empty? if
deleteline then
&cur ! ;
: replChar ( -- ) key bufpos c! upd ;
\ vandys
: backDchar -1 +cur delchar ;
: command dup 13 = if drop ret exit then
dup 8 = if drop backDchar exit then
drop 'command @ &mode ! bol? not if larrow then ;
: insertoff key dup ?prt
if bufpos c! upd 1 +cur
else command then ; ' insertoff 'overwrite !
: inserton key dup ?prt
if inschar 1 +cur
else command then ; ' inserton 'insert !
: dispatch ( c a -- ) swap >r begin @+ ?dup while
r@ = if r> drop @execute exit then
cell+ repeat r> 2drop beep ;
\ Delete, yank, with yank buffer vandys
: saveLines ( -- u ) &argvalid? @ if &arg @ lps curpos >line# -
( arg #lines ) min else 1 then
curpos >bol >bufadr over c/l * dup &yank ! yankBuf swap move ;
: cmd_deleteline ( -- ) saveLines 0 do deleteline loop ;
: deltoeos ( -- ) bufpos cps curpos - blank upd ;
create d_cmd char $ , ' deltoeol , char d , ' cmd_deleteline ,
char G , ' deltoeos , 0 , 0 ,
: cmd_Yank ( -- ) saveLines drop ;
: #insertlines ( -- u ) lps-1 begin
dup empty? over curline >= and while 1- repeat
lps-1 swap - ;
: cmd_Put ( -- ) &yank @ c/l / ?dup 0= if beep exit then
dup #insertlines > if drop beep exit then begline
0 do insertline 0= abort" insertline failed" loop
yankBuf bufpos &yank @ move upd ;
: cmd_put ( -- ) curpos rett cmd_Put &cur ! ;
\ vandys
: searchingCur? &srch>scr @ &scr @ = ;
: forward? &srch>dir @ 0> ;
: curBufArg ( -- ptr u ) blkBuf bufpos over - forward? if
cps*2 over - -rot + swap 1- swap 1+ swap then ;
: bufArg ( -- ptr u ) searchingCur? if curBufArg
else &srch>scr @ block cps*2 then ;
: scan ( a ptr u -- pos | -1 ) &srch>dir @ 0> if strpos else
strrpos then ;
: adjustResult ( u -- u ) searchingCur? forward? and if
bufpos 1+ blkBuf - + then ;
: found? ( -- pos T | F ) searchBuf bufArg scan dup -1 = if
drop false else adjustResult true then ;
\ vandys
: searchInit ( dir -- ) &srch>dir ! &scr @ &srch>scr ! ;
: scrJump ( n -- ) &scr @ over = if drop else
mark &scr ! init then ;
: jumpTo ( pos scr -- ) scrJump dup cps mod &cur ! cps >=
inShadow? <> if edtshdw then ;
: searchJump ( pos -- ) &srch>scr @ jumpTo ;
: showScreen ( -- ) page &srch>scr ? ;
: search ( dir -- ) searchInit begin
found? if searchJump exit then
&srch>dir @ &srch>scr +! showScreen
key? until key drop ;
: (search) ( dir c -- ) position emit searchBuf padIn
not if drop exit then search redraw ;
: searchAgain ( -- ) &srch>dir @ ?dup 0= if beep exit then
search redraw ;
\ vandys
: slash 1 [char] / (search) ;
: backslash -1 [char] ? (search) ;
create marks 26 2* cells allot
create marktick 2 cells allot
: setMark ( a -- ) &scr @ over !
curpos inShadow? if cps + then swap cell+ ! ;
: >mark ( c -- a | 0 ) dup [char] a >= over [char] z <= and if
[char] a - 2* cells marks + exit then
[char] ' = if marktick exit then 0 beep ;
: tick key >mark ?dup if dup @ 0= if drop exit then
2@ marktick setMark jumpTo then ;
: markPos key >mark ?dup if setMark then ;
\ vandys
: doDig ( -- )
&argvalid? @ 0= &cmdc @ [char] 0 = and if
begline exit then
&arg @ 10 * &cmdc @ [char] 0 - + &arg !
&argvalid? on ;
: isdigit? ( c -- ? ) [char] 0 [char] 9 1+ within ;
: doGo ( -- ) mark
&argvalid? @ if &scr @ fs.file>head &scr !
&arg @ begin dup BLKROWS >= while &scr inc BLKROWS - repeat
init 0 do darrow loop exit then
&scr @ fs.file>tail &scr ! init ;
: deleteBlock ( -- ) &scr @ fs.delblock init ;
\ vandys
: fixTab ( -- ) &cur @ cps 0 do i >bufadr c@ TAB = if
i &cur ! delchar i TABcols mod TABcols swap - 0 do
bl inschar loop then loop &cur ! ;
: (delFromTop) ( pos blkptr -- ) 2dup + over c/l +
( pos blkptr src dest ) cps 4 pick - move ( pos blkptr )
swap cps swap - c/l + tuck + swap cps swap - blank ;
: delFromTop ( blk pos -- ) swap block 2dup (delFromTop)
SCRSIZ + (delFromTop) update ;
: blankBottom ( -- ) bufpos cps curpos - 2dup blank
swap SCRSIZ + swap blank upd ;
: insertBlock ( -- ) mark begline curpos 0= if c/l +cur then
inShadow? if edtshdw then
&scr @ dup fs.insblock 1+ curpos delFromTop blankBottom ;
create Z_cmd char Z , ' exitupd , char N , ' nxtblk ,
char P , ' lstblk , char x , ' quited , char s , ' status ,
char S , ' edtshdw , 9 , ' fixTab , char i , ' insertBlock ,
char d , ' deleteBlock ,
0 , 0 ,
: saveKey key Z_cmd dispatch ;
\ vandys
: overwriteMode ['] insertoff &mode ! ;
: insertMode ['] inserton &mode ! ;
: openDown onlast? if beep exit then
#toeol 1+ +cur insertline drop insertMode ;
: openHere curpos >bol &cur ! insertline drop insertMode ;
\ : changeKey key ['] change_cmd dispatch ;
: delKey key d_cmd dispatch ;
: endWord rword lword ;
: backWord lword begin bol? if exit then bufpos c@ bl = if
1 +cur exit then -1 +cur again ;
\ vandys
: (findCount) ( -- n ) &findDir @ 0> if #toeol else #tobol then ;
: (findChar) ( c -- ) dup ESC = if drop exit then
&findchar c! curpos (findCount) 0 do ( u-pos )
&findDir @ + dup >bufadr c@ &findchar c@ = if
&cur ! unloop exit then
loop drop beep ;
: findChar ( -- ) 1 &findDir ! key (findChar) ;
: findCharb ( -- ) -1 &findDir ! key (findChar) ;
: findAgain ( -- ) &findchar c@ (findChar) ;
: appendMode ( -- ) 1 +cur insertMode ;
: tillChar ( -- ) findChar -1 +cur ;
: appendModef ( -- ) endline insertMode ;
\ vandys
: (setDigs) 10 0 do [char] 0 i + , ['] doDig , loop ;
create top_cmd char a , ' appendMode , char b , ' backWord ,
( char c , ' changeKey , ) char d , ' delKey , char e , ' endWord ,
char f , ' findChar , char h , ' larrow , char i , ' insertMode ,
char j , ' darrow , char k , ' uarrow , char l , ' rarrow ,
char m , ' markPos , char n , ' searchAgain , char o , ' openDown ,
char r , ' replChar ,
char p , ' cmd_put , char t , ' tillChar , char w , ' rword ,
char x , ' delchar , char A , ' appendModef , char F , ' findCharb ,
char G , ' doGo ,
char H , ' 1st , char I , ' firstInsert , char J , ' joinLine ,
char L , ' lst , char O , ' openHere , char P , ' cmd_Put ,
char M , ' middle , 13 , ' rett , char ; , ' findAgain ,
char X , ' backDchar , 32 , ' rarrow , char ^ , ' startLine ,
char Y , ' cmd_Yank , char Z , ' saveKey , char $ , ' endline ,
(setDigs) \ Fill in handler for 0..9
char ' , ' tick , char R , ' overwriteMode ,
char / , ' slash , char ? , ' backslash ,
0 , 0 ,
\ vandys
: keycmd key dup &cmdc ! top_cmd dispatch ; ' keycmd 'command !
[ifndef] VIDEBUG? also forth definitions [then]
: v decimal
here #edvars cells erase
depth 0= if scr @ then &scr !
heading cr cr ." Ready when you are" cr cr
getid init
begin [ifdef] VIDEBUG? 12321 [then]
&cmdc @ isdigit? 0= if &argvalid? off &arg off then
mvcur
&delta @ &mode @execute &delta @ <> if redraw then
[ifdef] VIDEBUG? 12321 - abort" vi stack" [then] again ;
[ifndef] VIDEBUG? only [then]
vandys
: beep TBD: tie this to some sort of sound service? Although it needs
to be a TTY abstraction to support RS-232 types of devices.
: upc Convert lower case to upper case
: at at-xy from the Forth standard, but (of course) args reversed
edvar's are variables whose storage lies at "here" and beyond,
with indices allocated as an argument. This permits multiple
instances of the editor, one per user task.
Number of words stored as per-process storage
This is the "user name" of the person editing. It is flagged as
empty, and gets filled in on initial editor invocation.
Vectors to our input modes; bound to routines as they are defined
chars per screen lines per screen
columns per line
Some x-1 variants
ASCII escape char
Size of each pad area
...size allocated (includes slop)
: textBuf Text save area
: numBuf Numeric input area
: searchBuf Text of search command
: prevsearchBuf Text of last search command, for searching again
: blkBuf Private copy of disk buffer for current screen
NOTE: blkBuf must be last, since it is not BUFsize bytes in size
: yankBuf Yank/put text hold buffer
: >line# Convert char position to line number
: line#> Convert line number to char position
: >bol Convert position to beginning of line
: >eol ...to last char position on line
: curpos Get cursor position
: +cur Advance cusor position and check bounds
: mvcur Move cursor to current position
: bufadr Convert offset to byte pointer into buffer
: bufpos Return byte pointer in buffer of current edit position
: upd Set update flag
: ?prt Tell if char on TOS is printable
: mark If buffer hasn't changed, just return
Tag modified block with our username in row 1
Move our private buffer copy back to the block, clear change flag
: #tobol Return # chars to beginning of line
: #toeol Return # chars to end of line
: bufmv Move chars in disk buffer. Convert from source and dest
offsets to positions in buffer, then do a bulk move. Flag buffer
modified.
\ vandys
: position Move to special input partof screen, and blank input line
: empty? Tell if the indicated line # is empty
: clrLine Clear line starting at given position
: exp Insert blank line at current position, shifting all down one.
: shrink Delete line at position specified by TOS.
Add blank line at bottom of screen.
vandys
: insertline Add line if there's room at bottom of screen
: deleteline Delete line at current position
: cempty? Tell if last char in line of position is a blank
: inschar Insert char at current position
: delchar Delete char at current position
: deltoeol Delete to end of line
: rarrow Cursor right
: larrow Cursor left
: uarrow Cursor up
: darrow Cursor down
vandys
: heading Display a small header
: inserting? Tell if we are in insert input mode
: breakline Insert line at current position, shifting text after
the cursor down to the new line.
: curline Return line # of current position
: onlast? Tell if we're on the last line of the screen
: ret Handle insertion of a CR. If in insert mode, insert a whole
blank line. Otherwise just move down to the next line.
: quited Quit editor without saving screens. Also resets stack.
: exitupd Save screens, then quit editor.
: (>prev) Save passed buffer to prevsearchBuf
: (<prev) Put prevsearchBuf onto passed buffer
: (padIn) Input a PAD buffer worth of typing; save new input. If there
is no input, use text from previous search.
: scanfail Factor out actions taken on scan failure, unstructured return
: scan+= ( c lim pos -- 0 | pos ) Scan forward for given char.
Return a non-zero position, or 0 on failure.
: scan+<> Scan forward until not equal to given char.
: scan-= Scan backward for given char.
: scan-<> Scan backward for not equal to given char.
: mvlwrd Move left a word, returns # chars to move
: mvrwrd Like mvlwrd, but moving right.
: rword Move cursor right one word
: lword ...left
: delchars Delete characters from current position
: dword Delete word at current position
: updscr Redisplay whole screen
: clrscn Clear whole screen
vandys
: getid Input user ID
Remembers it from the first time, and doesn't ask again.
: init2 Initialize data structures, but not block buffer portion
: init Initialize block buffer, then call init2 to set up rest of editor
: rstedit Restart edit of current block, discarding changes
: lstblk Move to block number one lower than our current one
: nxtblk Move to next block
: inShadow? Return whether we're currently editing the shadow screen
: edtshdw Move between source block and its shadow
If we're building interactively, kTAP has been hidden by hide-sys
: (padTAP) Handle control chars within accept. Escape aborts input,
otherwise we use the existing control character handling.
: (dopadIn) Like (padIn), but don't consume argument
: padIn Read a line from the user into the given buffer. Return whether
or not input was successful--escaping out is detected.
: openDown Open a line beneath our current line
: openHere Open a line here, pushing current line down
: 1st Go to first line
: middle Go to middle of screen
: lst Go to last line
: bol? Are we at beginning of line?
: hldln Copy current line into our hold buffer in pad1
: insln Insert line from pad1 if there's room (last line empty).
: rett Special CR never inserts a line
: begline Go to beginning of line
: endline Go to last char on this line
: startLine Go to first non-blank char on line
: status Display edit status
: joinLine Join chars from next line onto this one.
Move the chars, delete from old line
Snug remaining text against beginning of line
Remove line if all text was pulled up
Place cursor at point of joining
: backDchar Back up and delete char before cursor
: command Return to top-level command mode from insert mode
: insertoff Process a keystroke while in overwrite mode
: inserton Process keystroke while in insert mode
: dispatch Look through the command table and execute the matching
entry. Beep if no match is found.
: saveLines Massage argument (count # lines) against lines left on screen,
save over the appropriate number of lines and return this count.
: cmd_deleteline Interactive line deletion, with save of text
d_cmd... Dispatch for delete commands
: cmd_Yank Yank some lines
: #insertlines Tell how many lines can be inserted at the current position
: cmd_Put Insert lines from yank buffer at current position
: cmd_put Insert lines at point below this line
vandys
: searchingCur? Tell if we're searching on the current screen #
: curBufArg Provide pointer and count for searching in current screen
edit buffer.
: bufArg Provide buffer pointer and count. Use curBufArg for current
buffer, else get block through block I/O and access all cps*2 bytes.
: scan Scan forward or backwards through buffer for target string,
depending on search direction.
: adjustResult Adjust buffer pointer for the case of forward
searching on current screen--index is in terms of curent position
: found? Drive a search of the current search buffer screen.
: searchInit Store parameters in preparation for a search
: scrJump Move to potentially new screen; do init if new screen
: jumpTo Jump to given position on given screen
: searchJump Jump to found position on search success
: search Search for string; move to location if string found. Scan
continues until a keystroke or the search succeeds.
: showScreen As we advance screen #'s, show the counter
: (fwd) Advance position in a forward search
: (back) Advance position in a backward search
: /fwd Search forward
: /back Search backwards
vandys
: slash Do forward search of user-supplied string
: backslash Backward search
marks: Table of marked positions. Both screen # as well as byte
marktick: Record of previous position when jumping to a mark
:setMark Record position. Screen # in first word, byte position in
second. If on shadow, will have SCRSIZ added to it.
: >mark Convert character to a marker pointer. If it's a bad
character, beep and return 0.
: tick Get key, then jump to that mark.
: markPos Get key, then set mark to current location.
vandys
: doDig Process a typed digit, accumulating a numeric argument
Initial 0 means go to beginning of line, not numeric argument
Accumulate argument value
Tag that we have a valid argument
: isdigit? Tell if the given char is a numeric digit
: doGo Jump to a position. No argument, jump to end of file.
Otherwise it's a line number, thus jump to the given line on
a given screen.
: deleteBlock Delete current screen, restart with new contents
vandys
: fixTab Sweep through the current screen, converting tab chars
into their equivalent spaces
: (delFromTop) Move up text at point to top of screen
Block move from pos to EOS to top of screen (plus one line)
Now erase from end of moved text to bottom of screen
: delFromTop Move up text from point, on both source screen
and its shadow
: blankBottom Blank text from point to end of screen on both source
screen and its shadow
: insertBlock Insert new block in source, moving text from curpos
to end of screen onto top of the new screen, and blanking this off
of current screen
Z_cmd table for Z-<cmd> prefixes
: saveKey Dispatch all the Z-<cmd> prefix commands
vandys
: overwriteMode Start overwriting characters at cursor
: insertMode Start inserting characters at cursor position
: openDown Insert line below this one, go into insertion mode
: openHere Insert line before this one, go into insertion mode
\ : changeKey Handle all cX sequences
: delKey Handle all dX sequences
: endWord Move to end of current word
: backWord Move back to previous word
vandys
: (findCount) Return count of # char position we'll be looking at
: (findChar) Move to specified char, no-op on ESC
&findchar is char we're searching, walk through buffer
Move by increment/decrement in &findDir, end loop on match
Simply set buffer position
Forget buf pos and beep on failure to find char
: findChar Get char from user, then find it
: findAgain Find again, using last char searched
: appendMode Advance, then do insertion
: tillChar Move up until just before specified char
top_cmd: Top-level dispatch of "vi" type command chars.
vandys
: keycmd Read key and dispatch at top level of editor commands
Arrange for "v" to enter editor from forth vocabulary
: v Invoke editor, optionally with scr # on stack
Initialize state
Edit at previously accessed block of no argument specified
Startup message
Get user ID and initialize editor on current block
Main editor loop
Clear accumulated numberic argument after command
Update cursor position
Execute whatever mode is selected, repaint on screen change