I like color in the editor for html since html tags are mostly not easy to pair up visually because they're not indented, vertically aligned, etc.. It makes it easier to find where you're ending the underlining, a particular font, where a commented-out section begins and ends, etc.. In 'normal' programming languages however [1], each one should be either directly across or directly above or below its mate(s). Unfortunately we see a ton of violations of this, forms like this where paired words are diagonal from each other
Code:
condition if bla bla bla
yada yada else bla bla then bla
instead of
Code:
condition
IF bla bla bla
yada yada
ELSE bla bla
THEN bla
The first version keeps to the misguided notion that Forth definitions should be kept to two lines or less; but the second version is
much easier to instantly factor visually, and I'd rather not have the color. In Forth, you can also make your own program flow control structures. A separate editor won't be aware of these, so it won't be highlighting them.
As for simple tools though, I had to work with screen files for a while around 1990, and I absolutely hated it. A good programmer's text editor is way better, and I have it set up so I can mark a block, as short or long as desired, even as little as a single character that's only part of a line, like . or @, and send it to the Forth system (as if printing the block) for execution, compilation, or assembly, as appropriate at the time, without suspending or backgrounding the editor, even though it's in a non-multitasking DOS system. No TSRs, nothing hiding under the hood. Dr Jefyll does a similar thing.
-----------------------
[1] or at least Forth, which is a 'natural language' language, meaning (as I understand it) that a BEGIN structure for example ends with UNTIL, or AGAIN, or WHILE...REPEAT instead of something like } or ; or ). When I wrote my
structure macros for assembly language, I patterned them partly after Forth's. (There wasn't much choice anyway, because assemblers' macro languages don't let you use punctuation marks as macro names.) The following example, showing how things are grouped by indentation and structure-ending words, is from my
page on simple multitasking. Hopefully the lines won't wrap on anyone's screen and make a disaster of it:
Code:
; For the RX_STATEs:
; When RX_STATE = 0, an $FF byte will be required to increment RX_STATE to 1. Other bytes do nothing. The $FF is discarded.
; When RX_STATE = 1, only a non-$FF byte will be put in READING_BUF and increment RX_STATE to 2. More leading $FF's do nothing.
; When RX_STATE = 2, any value received will be put in READING, READING_BUF will be transferred to READING+1, and RX_STATE will
; be returned to 0.
WATCH_ACIA:
LDA RX_STATE
CASE ACCUM
CASE_OF 0 ; In the case of RX_STATE being 0, an $FF is required to increment it to 1.
IF_BIT ACIA_STAT_REG, 3, IS_SET ; If a byte came in (indicated by bit 3 of the status register),
LDA ACIA_DATA_REG ; get it (this clears the flag in the status register too),
INA ; and see if it's $FF. (INA is 1 byte less than CMP #$FF, and I don't need A again.)
IF_EQ ; If it was $FF,
INC RX_STATE ; move on to watch for a valid (non-$FF) first byte.
END_IF ; The accumulator value gets discarded.
END_IF ; If no byte came in, just exit.
END_OF
CASE_OF 1 ; To get here, we've received the $FF marker and we're looking for a valid 1st byte.
IF_BIT ACIA_STAT_REG, 3, IS_SET ; If a byte came in,
LDA ACIA_DATA_REG ; get it,
IF_PLUS ; see if it's valid as a high byte, ie, that the high bit is clear, and if so,
STA READING_BUF ; store it as valid in the buffer area meant to prevent wrong readings between bytes,
INC RX_STATE ; and move on to watch for the 2nd byte which could be anything.
END_IF ; If it's not a valid high byte, just discard it, and leave RX_STATE as is.
END_IF ; If no byte came in, just exit.
END_OF
; In the case of RX_STATE being 2, we've gotten the high byte of READING,
CASE_OF 2 ; and we're waiting for the second byte which could be anything.
IF_BIT ACIA_STAT_REG, 3, IS_SET ; See if a byte came in. If one did,
COPY VIA_SR, TO, READING ; just transfer it
COPY READING_BUF, TO, READING+1 ; (including the high byte now, which we had saved to prevent glitches
STZ RX_STATE ; in the two-byte READING value), and go back to state 0.
END_IF ; If no byte came in, just exit.
END_OF
STZ RX_STATE ; If there's any chance for state to go invalid, just reset it and start over.
END_CASE
RTS
;---------------------------------------