|
Wil Baden 1998-12-15
TEXT
LINE:is used to define a line filter.||and||separate the three components of a line filter.LINE;finishes the definition.
The most powerful editor that I have ever used comes from a one-line definition given me by Ward McFarland.
\ CLIPBOARD gives the address and length of the
\ text in the program clipboard.
: CLIPBOARD ( -- _str len_ )
SE.SCRAP DUP @ SWAP _GetHandleSize ;
It has made a fundamental change in text and data management.
Now the principal way to handle text and data is select it, copy it to the clipboard, and submit a function name that you have defined.
The editor is written in Forth, and is directly integrated
with Forth. The return key starts a new line. But there also
is a submit key that interprets the line you are on or the
text you have selected. Any output from the interpretation
appears following the line or selection. Error messages are
formatted as comments so the text can be changed and
immediately submitted again without having to remove the
error messages right away. .S, .., and others also output
in the form of a comment. (.. is a destructive stack dump.)
In PowerMacForth the submit key is shift-return or the enter key. The enter key is distinct from the return key on the Macintosh.
A programming editor that does not have a submit stroke is deficient. With a submit stroke there is no bouncing between Forth and the editor. Almost all work is done in the editor.
"Select and submit" is the operation of selecting text and then doing the submit stroke.
CLIPBOARD makes it easy to program functions that work on
text and data.
The format in the clipboard is lines separated by the
#EOL-CHAR character. The #EOL-CHAR character is <return> on
the Macintosh, and <linefeed> in Unix. As usual on the PC it
is messier.
You can walk through the clipboard line by line using
SPLIT-NEXT-LINE.
\ SPLIT-NEXT-LINE splits the next line from the
\ rest of the clipboard.
: SPLIT-NEXT-LINE ( str len -- str2 len2 str1 len1 )
2DUP #EOL-CHAR SCAN DUP >R 1 /STRING 2SWAP R> - ;
Most functions on the clipboard work a line at a time.
CLIPBOARD BEGIN DUP 0> WHILE ( str len)
SPLIT-NEXT-LINE ( str2 len2 str1 len1)
(Do a line.) ( str2 len2)
REPEAT 2DROP ( )
This logic has been encapsulated with defining word LINE:.
The definition is ended with LINE;.
LINE: function-name (Do a line.) LINE;
Simple functions have simple definitions.
\ C copies "\ " before non-empty lines.
LINE: C
TRIM DUP IF ." \ " THEN
TYPE CR
LINE;
The defined word will initialize four variables: TEMP,
OUT, FLAG and COMMENTARY. You can use these variables
for whatever you want.
I use FLAG for mode setting. Many defined functions use
OUT to count lines or columns. When OUT has 0 it is the
beginning of a new paragraph.
LINE: uses :NONAME three times to prepare execution
tokens for special initiation, line processing, and
termination.
When special initiation or termination is needed, the line
processing must be bracketed by || and ||. Without
|| only line processing is done.
Words defined by LINE: start execution by backing over
themselves. This is so the name does not appear in the
output.
No stack-effect comment is given with LINE: definitions
because it is invariant.
When executing, at the beginning of line processing the stack will be str2 len2 str1 len1. At the end of line processing the stack should be str2 len2. str2 len2 is the rest of the clipboard.
With this format when processing a line, you can look at the next line.
CLIPBOARD can be used for other than editing. It becomes
the main source of data input. The usual mode of input is in
the editor. Text is selected and copied in the editor, and
then displayed by submitting a line filter command where you
want the result.
"Select, copy, and submit" and "select, cut, and submit" are the usual operations.
Line filters are often defined for a particular task, used once, and abandoned.
Using CLIPBOARD is helped by an library of scanning and
parsing definitions. Their use can be seen in the examples.
CLIPBOARD ( -- str len )
CB ( -- str len )
CLIPBOARD. For interactive use.
BACKSPACES ( n -- )
TEMP OUT FLAG COMMENTARY ( -- addr )
CONTINUING ( -- addr )
TEMP. This is so the
number in TEMP can be continued.
CONTINUED
CONTINUING on.
ALSO EDITOR
: CLIPBOARD ( -- str len )
SE.SCRAP DUP @ SWAP _GETHANDLESIZE ;
PREVIOUS
: CB ( -- str len ) clipboard ;
\ 8 CONSTANT #BACKSPACE-CHAR
: BACKSPACES ( n -- ) #BACKSPACE-CHAR EMITS ;
VARIABLE FLAG
VARIABLE COMMENTARY
VARIABLE CONTINUING
: CONTINUED ( -- ) CONTINUING ON ;
EXDEPTH ( -- addr )
DEPTH.
SAVE-DEPTH ( -- )
DEPTH.
CHECK-DEPTH ( -- )
DEPTH changed.
VARIABLE EXDEPTH
: SAVE-DEPTH ( -- )
DEPTH EXDEPTH ! ;
: CHECK-DEPTH ( ... -- same )
DEPTH EXDEPTH @ < ABORT" Stack shrinking."
DEPTH EXDEPTH @ > ABORT" Stack growing."
;
#EOL-CHAR ( -- n )
SPLIT-NEXT-LINE ( str len -- str2 len2 str1 len1 )
LINE-FILTER ( xt -- xt' )
CLIPBOARD. Used in DO-LINE-FILTER:.
DO-LINE-FILTER: ( "name" -- addr )
LINE:.
\ PowerMacForth to turn off line spacing after submit.
ALSO EDITOR 0 TO +CR PREVIOUS
\ 13 VALUE #EOL-CHAR \ 10 for Unix.
: BEGIN?
S" SAVE-DEPTH BEGIN CHECK-DEPTH DUP 0> WHILE " EVALUATE
; IMMEDIATE
\ : SPLIT-NEXT-LINE ( str len -- str2 len2 str1 len1 )
\ 2DUP #EOL-CHAR SCAN DUP >R 1 /STRING 2SWAP R> - ;
: SPLIT-LINES
S" BEGIN? SPLIT-NEXT-LINE " EVALUATE
; IMMEDIATE
: STOP? ( -- flag )
KEY? 0= IF FALSE EXIT THEN
KEY BL = IF KEY DROP FALSE EXIT THEN
TRUE ;
: ?REPEAT S" STOP? UNTIL THEN " EVALUATE ; IMMEDIATE
: LINE-FILTER ( xt -- xt' )
>R ( )( R: xt)
CLIPBOARD ( str len)
SPLIT-LINES ( str2 len2 str1 len1)
R@ @ EXECUTE ( str2 len2)
?REPEAT 2DROP
R> ;
: LINE-FILTER-INIT ( -- )
FLAG OFF OUT OFF COMMENTARY OFF
CONTINUING DUP @ TEMP ! OFF ;
: DO-LINE-FILTER: ( "name" -- addr )
>IN @ CREATE
>IN ! BL WORD C@ , HERE 0 , 0 , 0 ,
DOES> ( addr)
LINE-FILTER-INIT
\ Backover the name.
DUP @ BACKSPACES CELL+
\ Execute any initialization.
DUP CELL+ @ IF DUP CELL+ SWAP @ EXECUTE THEN
\ Execute the line filter.
LINE-FILTER
\ Execute termination.
CELL+ @ ?DUP IF EXECUTE THEN ;
LINE: ( "name" -- )
||
LINE;
: LINE: ( "name" -- ) DO-LINE-FILTER: ( addr) :NONAME ; : || POSTPONE ; OVER ! CELL+ :NONAME ; IMMEDIATE : LINE; POSTPONE ; SWAP ! ; IMMEDIATE