some small work on edit.forth

FossilOrigin-Name: 1dbd50b3cfe48b522714712d040af801c2b6905fee761e1e24580f2bcc1506fc
This commit is contained in:
crc 2019-02-02 04:45:38 +00:00
parent c3c3e1fda2
commit fcbfebb54e

View file

@ -2,12 +2,50 @@
# Hua: a text editor written in RETRO
Hua is a small, functional text editor written in RETRO, using the
*RRE* interface. It is line oriented, visual, and tries to be very
simple to use.
Hua is a small, functional text editor written in RETRO, using
the *RRE* interface. It is line oriented, visual, and tries to
be very simple to use.
First up, several variables and constants that are used through
the rest of the code.
## Starting
Hua is intended to run as a standalone tool. Use a line like:
edit.forth filename
To create a new file:
edit.forth new filename
## A Word of Warning
Hua saves changes as you edit the file. I advise using it along
with a version control system so you can revert changes if or
when needed.
## The Code
Since this runs as a standalone application I use a quick check
to exit if no arguments were passed.
~~~
sys:argc n:zero? [ #0 unix:exit ] if
~~~
If I get here, a filename was provided. So I start by creating
a few variables and constants.
The configuration here is for two items. The number of lines
from the file to show on screen, and the name of the temporary
file to use when editing.
~~~
#80 'COLS const
#16 'MAX-LINES const
'/tmp/rre.edit 'TEMP-FILE s:const
~~~
Next are the variables that I use to track various bits of
state.
~~~
'SourceFile var
@ -18,21 +56,16 @@ the rest of the code.
'CopiedLine d:create #1025 allot
~~~
The configuration here is for two items. The number of lines from the
file to show on screen, and the name of the temporary file to use
when editing.
Get the name of the file to edit.
~~~
#80 'COLS const
#16 'MAX-LINES const
'/tmp/rre.edit 'TEMP-FILE s:const
~~~
Get the name of the file to edit. If no file is provided, exit.
~~~
sys:argc n:zero? [ #0 unix:exit ] if
#0 sys:argv s:keep !SourceFile
~~~
To create a new file, Hua allows for the use of `new` followed
by the filename. I handle the file creation here.
~~~
@SourceFile 'new s:eq?
[ #1 sys:argv s:keep !SourceFile
@SourceFile file:A file:open file:close ] if
@ -71,11 +104,11 @@ advance to the currently selected line.
@CurrentLine MAX-LINES #2 / - #0 n:max [ @FID file:read-line drop ] times ;
~~~
Now for words to format the output. This should all be pretty clear in
intent.
Now for words to format the output. This should all be pretty
clear in intent.
`clear-display` uses an ANSI/VT100 escape sequence. This might need to
be adjusted for your chosen terminal.
`clear-display` uses an ANSI/VT100 escape sequence. This might
need to be adjusted for your chosen terminal.
~~~
:clear-display (-)
@ -89,15 +122,16 @@ This just displays the separator bars.
COLS [ $- c:put ] times nl ;
~~~
Next, a word to display the header. Currently just the name of the file
being edited and the line count.
Next, a word to display the header. Currently just the name of
the file being edited and the line count.
~~~
:header (-)
count-lines @SourceFile '%s_:_%n_lines\n s:format s:put ;
~~~
The `pad` word is used to make sure line numbers are all the same width.
The `pad` word is used to make sure line numbers are all the
same width.
~~~
:pad (n-n)
@ -111,11 +145,12 @@ A line has a form:
<indicator><number>: <text><eol>
The indicator is an asterisk, and visually marks the current line.
The indicator is an asterisk, and visually marks the current
line.
EOL is optional. If `ShowEOL` is `TRUE`, it'll display a ~ at the end
of each line. This is useful when looking for trailing whitespace. The
indicator can be toggled via the ~ key.
EOL is optional. If `ShowEOL` is `TRUE`, it'll display a ~ at
the end of each line. This is useful when looking for trailing
whitespace. The indicator can be toggled via the ~ key.
~~~
:mark-if-current (n-n)
@ -138,20 +173,21 @@ indicator can be toggled via the ~ key.
---- @FID file:close ;
~~~
With the code to display the file done, I can proceed on to words for
handling editing.
With the code to display the file done, I can proceed to the
words for handling editing.
I add a custom combinator, `process-lines` to iterate over the lines in
the file. This takes a quote, and runs it once for each line in the file.
The quote gets passed two values: a counter and a pointer to the current
line in the file. The quote should consume the pointer an increment the
counter. This also sets up `FID` as a pointer to the temporary file where
changes can be written. The combinator will replace the original file
after execution completes.
I add a custom combinator, `process-lines` to iterate over the
lines in the file. This takes a quote, and runs it once for
each line in the file. The quote gets passed two values: a
counter and a pointer to the current line in the file. The
quote should consume the pointer an increment the counter. This
also sets up `FID` as a pointer to the temporary file where
changes can be written. The combinator will replace the
original file after execution completes.
Additionally, I define a word named `current?` which returns `TRUE` if
the specified line is the current one. This is just to aid in later
readability.
Additionally, I define a word named `current?` which returns
`TRUE` if the specified line is the current one. This is just
to aid in later readability.
~~~
:process-lines (q-)