some small work on edit.forth
FossilOrigin-Name: 1dbd50b3cfe48b522714712d040af801c2b6905fee761e1e24580f2bcc1506fc
This commit is contained in:
parent
c3c3e1fda2
commit
fcbfebb54e
1 changed files with 88 additions and 52 deletions
|
@ -2,25 +2,41 @@
|
||||||
|
|
||||||
# Hua: a text editor written in RETRO
|
# Hua: a text editor written in RETRO
|
||||||
|
|
||||||
Hua is a small, functional text editor written in RETRO, using the
|
Hua is a small, functional text editor written in RETRO, using
|
||||||
*RRE* interface. It is line oriented, visual, and tries to be very
|
the *RRE* interface. It is line oriented, visual, and tries to
|
||||||
simple to use.
|
be very simple to use.
|
||||||
|
|
||||||
First up, several variables and constants that are used through
|
## Starting
|
||||||
the rest of the code.
|
|
||||||
|
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.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
'SourceFile var
|
sys:argc n:zero? [ #0 unix:exit ] if
|
||||||
'CurrentLine var
|
|
||||||
'LineCount var
|
|
||||||
'ShowEOL var
|
|
||||||
'FID var
|
|
||||||
'CopiedLine d:create #1025 allot
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
The configuration here is for two items. The number of lines from the
|
If I get here, a filename was provided. So I start by creating
|
||||||
file to show on screen, and the name of the temporary file to use
|
a few variables and constants.
|
||||||
when editing.
|
|
||||||
|
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
|
#80 'COLS const
|
||||||
|
@ -28,11 +44,28 @@ when editing.
|
||||||
'/tmp/rre.edit 'TEMP-FILE s:const
|
'/tmp/rre.edit 'TEMP-FILE s:const
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Get the name of the file to edit. If no file is provided, exit.
|
Next are the variables that I use to track various bits of
|
||||||
|
state.
|
||||||
|
|
||||||
|
~~~
|
||||||
|
'SourceFile var
|
||||||
|
'CurrentLine var
|
||||||
|
'LineCount var
|
||||||
|
'ShowEOL var
|
||||||
|
'FID var
|
||||||
|
'CopiedLine d:create #1025 allot
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Get the name of the file to edit.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
sys:argc n:zero? [ #0 unix:exit ] if
|
|
||||||
#0 sys:argv s:keep !SourceFile
|
#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?
|
@SourceFile 'new s:eq?
|
||||||
[ #1 sys:argv s:keep !SourceFile
|
[ #1 sys:argv s:keep !SourceFile
|
||||||
@SourceFile file:A file:open file:close ] if
|
@SourceFile file:A file:open file:close ] if
|
||||||
|
@ -48,15 +81,15 @@ easier.
|
||||||
I now turn my attention to displaying the file. I am aiming for
|
I now turn my attention to displaying the file. I am aiming for
|
||||||
an interface like:
|
an interface like:
|
||||||
|
|
||||||
<filename> : <line-count>
|
<filename> : <line-count>
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
* 99:
|
* 99:
|
||||||
100: :n:square dup * ;
|
100: :n:square dup * ;
|
||||||
101:
|
101:
|
||||||
102: This is the current line
|
102: This is the current line
|
||||||
103:
|
103:
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
j: down | k: up | ... other helpful text ...
|
j: down | k: up | ... other helpful text ...
|
||||||
|
|
||||||
The * denotes the currently selected line.
|
The * denotes the currently selected line.
|
||||||
|
|
||||||
|
@ -71,11 +104,11 @@ advance to the currently selected line.
|
||||||
@CurrentLine MAX-LINES #2 / - #0 n:max [ @FID file:read-line drop ] times ;
|
@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
|
Now for words to format the output. This should all be pretty
|
||||||
intent.
|
clear in intent.
|
||||||
|
|
||||||
`clear-display` uses an ANSI/VT100 escape sequence. This might need to
|
`clear-display` uses an ANSI/VT100 escape sequence. This might
|
||||||
be adjusted for your chosen terminal.
|
need to be adjusted for your chosen terminal.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
:clear-display (-)
|
:clear-display (-)
|
||||||
|
@ -89,33 +122,35 @@ This just displays the separator bars.
|
||||||
COLS [ $- c:put ] times nl ;
|
COLS [ $- c:put ] times nl ;
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Next, a word to display the header. Currently just the name of the file
|
Next, a word to display the header. Currently just the name of
|
||||||
being edited and the line count.
|
the file being edited and the line count.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
:header (-)
|
:header (-)
|
||||||
count-lines @SourceFile '%s_:_%n_lines\n s:format s:put ;
|
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)
|
:pad (n-n)
|
||||||
dup #0 #9 n:between? [ '____ s:put ] if
|
dup #0 #9 n:between? [ '____ s:put ] if
|
||||||
dup #10 #99 n:between? [ '___ s:put ] if
|
dup #10 #99 n:between? [ '___ s:put ] if
|
||||||
dup #100 #999 n:between? [ '__ s:put ] if
|
dup #100 #999 n:between? [ '__ s:put ] if
|
||||||
dup #1000 #9999 n:between? [ '_ s:put ] if ;
|
dup #1000 #9999 n:between? [ '_ s:put ] if ;
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
A line has a form:
|
A line has a form:
|
||||||
|
|
||||||
<indicator><number>: <text><eol>
|
<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
|
EOL is optional. If `ShowEOL` is `TRUE`, it'll display a ~ at
|
||||||
of each line. This is useful when looking for trailing whitespace. The
|
the end of each line. This is useful when looking for trailing
|
||||||
indicator can be toggled via the ~ key.
|
whitespace. The indicator can be toggled via the ~ key.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
:mark-if-current (n-n)
|
:mark-if-current (n-n)
|
||||||
|
@ -138,20 +173,21 @@ indicator can be toggled via the ~ key.
|
||||||
---- @FID file:close ;
|
---- @FID file:close ;
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
With the code to display the file done, I can proceed on to words for
|
With the code to display the file done, I can proceed to the
|
||||||
handling editing.
|
words for handling editing.
|
||||||
|
|
||||||
I add a custom combinator, `process-lines` to iterate over the lines in
|
I add a custom combinator, `process-lines` to iterate over the
|
||||||
the file. This takes a quote, and runs it once for each line in the file.
|
lines in the file. This takes a quote, and runs it once for
|
||||||
The quote gets passed two values: a counter and a pointer to the current
|
each line in the file. The quote gets passed two values: a
|
||||||
line in the file. The quote should consume the pointer an increment the
|
counter and a pointer to the current line in the file. The
|
||||||
counter. This also sets up `FID` as a pointer to the temporary file where
|
quote should consume the pointer an increment the counter. This
|
||||||
changes can be written. The combinator will replace the original file
|
also sets up `FID` as a pointer to the temporary file where
|
||||||
after execution completes.
|
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
|
Additionally, I define a word named `current?` which returns
|
||||||
the specified line is the current one. This is just to aid in later
|
`TRUE` if the specified line is the current one. This is just
|
||||||
readability.
|
to aid in later readability.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
:process-lines (q-)
|
:process-lines (q-)
|
||||||
|
|
Loading…
Reference in a new issue