80 constant COMMANDLINE_SIZE create commandline COMMANDLINE_SIZE allot variable cmdcursor variable cmdready : (cursor@) ( -- index-u ) cmdcursor @ ; : (translate) ( index-u -- addr ) commandline + ; : (last-position) ( -- index-u ) COMMANDLINE_SIZE 1- ; : (tail) ( index-u -- length-u ) COMMANDLINE_SIZE swap - ; : (cursor-left) ( -- ) (cursor@) 1- 0 max cmdcursor ! ; : (cursor-right) ( -- ) (cursor@) 1+ COMMANDLINE_SIZE 1- min cmdcursor ! ; : (overwrite-char) ( c -- ) commandline (cursor@) + c! ; : (append-char) ( c -- ) (cursor@) (last-position) <> IF (cursor@) dup (translate) dup 1+ rot (tail) 1- move THEN (overwrite-char) ; : (backspace) ( -- ) (cursor@) 0> IF (cursor@) (translate) dup 1- (cursor@) (tail) move bl (last-position) (translate) c! (cursor-left) THEN ; : commandline-handlekey ( ekey-n -- ) ekey>char if ( c ) CASE 10 OF true cmdready ! ENDOF \ newline 13 OF true cmdready ! ENDOF \ carriage return 127 OF (backspace) ENDOF \ DEL (append-char) (cursor-right) EXIT ENDCASE else ekey>fkey if ( key-id ) case k-left of (cursor-left) endof k-right of (cursor-right) endof endcase else ( keyboard-event ) drop \ just ignore an unknown keyboard event type then then ; : commandline-getline ( -- c-addr u ) commandline COMMANDLINE_SIZE ; : (update-cursorpos) ( -- ) s\" \033[" type (cursor@) 1+ s>d <# #s #> type s" G" type ; : (carriage-return) ( -- ) 13 emit ; : commandline-redraw ( -- ) (carriage-return) commandline-getline type (update-cursorpos) ; : commandline-reset ( -- ) commandline COMMANDLINE_SIZE bl fill 0 cmdcursor ! false cmdready ! ; : commandline-key? ( -- flag ) key? ; : commandline-key ( -- ekey ) ekey ; : commandline-ready? ( -- flag ) cmdready @ ; commandline-reset