Edit Line Extensions
{ ============================================================================
EditLine.F Extensions
(C) Copyright 2004 LOGIX, All Rights Reserved.
Changes:
Created 11/03/2003 by Mike Ghan
Released to the Public Domain 1/20/2004 MAG
Enhancements:
1) Allow up/down arrow keys to invoke auto-complete if not at line start.
2) Save all lines 1 or more chars long into history buffer.
3) Ctl Shift Del = Delete to End of Line
4) Ctl Home = Show History
5) F3 = Append Last to EOL (ala DOS)
6) Auto-complete comparison is now case-insensitive.
7) Fixed a few zero length bugs (ie DO >> ?DO).
Future:
1) If new line exists in history, delete old entry
=========================================================================== }
PACKAGE ACCEPTOR
PRIVATE
VARIABLE RECALLED?
VARIABLE RECALLING?
\ Bug with zero lengths (Bug reported 5/7/01 MAG)
-? \ Broken COMPARE(NC)
: COMPARE(NC) ( c-addr1 len1 c-addr2 len2 -- n )
DUP 0= 3 PICK 0= AND
IF 4DROP 0 EXIT THEN
DUP 0= 3 PICK 0= OR
IF NIP - NIP EXIT THEN
COMPARE(NC) ;
[UNDEFINED] PTR+ [IF]
\ Increment Pointer
: PTR+ ( addr limit --- )
OVER @ 1+ TUCK U> AND SWAP ! ;
\ Decrement pointer
: PTR- ( addr limit --- )
1- OVER @ ?DUP
IF 1- NIP THEN SWAP ! ;
[THEN]
-?
: /COMPLETE ( a n # -- a n # )
THIRD PATTERN COUNT TUCK COMPARE(NC) PATTERN C@ 0= OR IF
THIRD OVER PATTERN PLACE -1 THELINE ! ( << changed )
THEN ;
-? \ Fixed 0 length bug
: A-REPLACE ( a n # a n -- a n # )
2>R A-ESCAPE 2R> BOUNDS ?DO ( <<< change to ?DO )
I C@ A-OVERSTRIKE
LOOP A-HOME A-END ;
: A-MATCH-LINE? ( a n # -- a n # flag ) \ True = Match
THELINE @ NTH-LINE PATTERN COUNT ROT MIN TUCK COMPARE(NC) 0= ( Match? ) ;
: A-LINE-REPLACE ( a n # -- a n # )
THELINE @ NTH-LINE A-REPLACE ;
-?
: A-COMPLETE ( a n # -- a n # )
/COMPLETE
#LBUF 0
?DO THELINE #LBUF PTR+
A-MATCH-LINE?
IF A-LINE-REPLACE UNLOOP EXIT THEN
LOOP ;
: -A-COMPLETE ( a n # -- a n # )
/COMPLETE THELINE @ 0 MAX THELINE !
#LBUF 0
?DO THELINE #LBUF PTR-
A-MATCH-LINE?
IF A-LINE-REPLACE UNLOOP EXIT THEN
LOOP ;
: A-UP-ARROW ( a n # -- a n # )
DUP
RECALLING? @ NOT AND
IF A-COMPLETE
RECALLED? OFF
EXIT
THEN ( else ) A-RECALL-UP RECALLED? ON ;
: A-DN-ARROW ( a n # -- a n # )
DUP
RECALLING? @ NOT AND
IF -A-COMPLETE
RECALLED? OFF
EXIT
THEN ( else ) A-RECALL-DOWN RECALLED? ON ;
-? \ Fixed 0 length bug, validate n
: HISTORY ( n -- )
#LBUF MIN
1- 0 MAX 0 SWAP ?DO
CR I NTH-LINE TYPE
-1 +LOOP CR ;
: A-SHOW-HIST ( a n # -- a n # ) A-ESCAPE 10 HISTORY ;
: REPATTERN ( a n # -- a n # )
THIRD OVER PATTERN PLACE
-1 THELINE ! ;
: A-DEL-EOL ( a n # -- a n # )
R-BUF THIRD OVER R@ PLACE R> COUNT A-REPLACE ;
: A-APPEND-LAST ( a n # -- a n # )
A-DEL-EOL
0 NTH-LINE THIRD /STRING 0 MAX BOUNDS
?DO I C@ A-OVERSTRIKE LOOP REPATTERN ;
\ Repattern relevant control operations
: A-BACKSPACE-X ( a n # -- a n # ) A-BACKSPACE REPATTERN ;
: A-LEFT-X ( a n # -- a n # ) A-LEFT REPATTERN ;
: A-RIGHT-X ( a n # -- a n # ) A-RIGHT REPATTERN ;
: A-END-X ( a n # -- a n # ) A-END REPATTERN ;
: A-LEFTWORD-X ( a n # -- a n # ) A-LEFTWORD REPATTERN ;
: A-RIGHTWORD-X ( a n # -- a n # ) A-RIGHTWORD REPATTERN ;
[+SWITCH CONTROL ( a n # echar -- a n # )
8 RUNS A-BACKSPACE-X
9 RUNS A-COMPLETE
$010025 RUNS A-LEFT-X
$010027 RUNS A-RIGHT-X
$010023 RUNS A-END-X
$030025 RUNS A-LEFTWORD-X
$030027 RUNS A-RIGHTWORD-X
$010026 RUNS A-UP-ARROW
$010028 RUNS A-DN-ARROW
$030024 RUNS A-SHOW-HIST \ Ctl Home
$07002E RUNS A-DEL-EOL \ Ctl Shift Del
$010072 RUNS A-APPEND-LAST \ F3 - Append Last to EOL (ala DOS)
SWITCH]
-?
: ESTROKE ( a n # echar -- a n # )
DUP 32 256 WITHIN IF CHARACTER REPATTERN ( new ) ELSE CONTROL THEN ;
: ~ACCEPT~ ( a n -- n )
-1 THELINE ! PATTERN OFF
2DUP BLANK 0 BEGIN ( a n # )
AKEY
RECALLED? @ RECALLING? ! RECALLED? OFF ( <<< new )
ESTROKE
RECALLED? @ RECALLING? ! ( <<< new )
DUP 0<
UNTIL DROP ;
-?
: E-ACCEPT ( a n -- n )
~ACCEPT~ TUCK 2DUP >HISTORY PUSHLINE ;
' E-ACCEPT IS ACCEPT
PUBLIC
: CONSOLE-ACCEPT ( a n -- n ) ~ACCEPT~ ;
PRIVATE
\ This is Very Ugly (and Dangerous)! We'll Patch Existing Code.
\ Next we'll configure to min line length from the history buffer.
\ Note: If this is ever merged with EditLine.F, PUSHLINE should be modified to
\ use a user adjustable (PUBLIC) variable or value.
1 ( Min Line Length to be Saved in Line History )
1- 0 MAX ' PUSHLINE >CODE 2+ DUP C@ $02 <>
[IF] CR .( Bad Patch, Expecting $02 ) /FORTH ABORT [THEN] C!
END-PACKAGE