diff --git a/femto b/femto index 9fcdd38..1cc18e5 100755 --- a/femto +++ b/femto @@ -5,7 +5,12 @@ # see femto.txt for documentation TTY=`stty -g` -uxnasm femto.tal femto.rom + +if [ "$1" = "-b" ]; then + shift + uxnasm femto.tal femto.rom +fi + if [ $? -eq 0 ]; then stty raw -echo uxncli femto.rom "$@" diff --git a/femto.tal b/femto.tal index ff80c3a..8aa2373 100644 --- a/femto.tal +++ b/femto.tal @@ -2,28 +2,9 @@ ( ) ( requires terminal to be in raw mode ) ( see femto launcher script for more details ) -( ) -( ANSI sequences used ) -( ) -( goto $row,$col ESC [ $row ; $col H ) -( go right by n ESC [ n C ) -( query cursor ESC [ 6 n ) -( erase line ESC [ 2 K ) -( erase all ESC [ 2 J ) -( ) -( set attrs ESC [ $at1 ; ... m ) -( reset ESC [ m ) -( 0 reset, 1 bright, 2 dim, ) -( 4 underscore, 5 blink, ) -( 7 reverse, 8 hidden ) -( ) -( fg (30-37), bg (40-47) ) -( black, red, green, yellow, ) -( blue, magenta, cyan, white ) ( TODO: ) ( - dollar ($) and caret (^) regex bug ) -( - optimize term drawing ) ( - get long line truncation/scrolling working ) ( - allow line numbers to be toggled off ) ( - help text ) @@ -35,7 +16,7 @@ |10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ] |a0 @File [ &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2 ] -( MAX file size is currently #d200, i.e. 53760 bytes ) +( MAX file size is currently #d000, i.e. 53248 bytes ) %dbg { #ff .System/debug DEO } %emit { .Console/write DEO } @@ -68,7 +49,6 @@ %emit-] { LIT2 '] 18 DEO } %emit-m { LIT2 'm 18 DEO } %emit-n { LIT2 'n 18 DEO } -%emit-u { LIT2 'u 18 DEO } %emit-~ { LIT2 '~ 18 DEO } %quit! { #01 .System/halt DEO BRK } @@ -115,6 +95,7 @@ ( tracks overall editor state between events ) @state [ + &in-help $1 ( are we showing help? ) &in-undo $1 ( are we currently in undo? ) &key $1 ( last key read ) &saw-esc $1 ( did we just see ESC? ) @@ -186,11 +167,11 @@ ( TODO: enable closing/opening files with editor already running ) @open-file ( filename* -> ) .File/name DEO2 - #d201 .File/length DEO2 + #d001 .File/length DEO2 ;data .File/read DEO2 .File/success DEI2 #0000 EQU2 .state/modified STZ - .File/success DEI2 #d201 LTH2 ,&ok JCN + .File/success DEI2 #d001 LTH2 ,&ok JCN ;messages/input-error ;print JSR2 ;filename ;print JSR2 nl quit! @@ -383,6 +364,16 @@ &done POP2 ;return JMP2 +@help + #01 .state/in-help STZ + ;term-erase-all JSR2 + #0000 #0000 ;term-move-cursor JSR2 + ;emit-color-bold JSR2 + ;help-text ;print JSR2 + ;emit-reset JSR2 + ;redraw-all JSR2 + BRK + ( center buffer view on the current line ) @center-view .term/rows LDZ2 INC2 #0002 DIV2 STH2k @@ -872,10 +863,6 @@ .state/key LDZ .state/saw-vt STZ ( ^[[1 through ^[[8 ) BRK -( ANSI control sequence to clear the current line ) -@clear-line ( -> ) - ansi emit-2 emit-K JMP2r - ( clear the message line ) ( ) ( this includes the code needed to move the cursor ) @@ -886,7 +873,7 @@ @clear-message-line .state/message LDZ #00 EQU ,&done JCN ;move-to-message-line JSR2 - ;clear-line JSR2 + ;term-erase-line JSR2 #00 .state/message STZ &done JMP2r @@ -1025,6 +1012,7 @@ ( - cancel the search restoring the cursor (C-g) ) @on-key-searching .state/key LDZ #07 EQU ( C-g ) ;cancel-search JCN2 + .state/key LDZ #08 EQU ( C-h ) ;help JCN2 .state/key LDZ #0d EQU ( \r ) ;finish-search JCN2 .state/key LDZ #12 EQU ( C-r ) ;jump-to-prev-match JCN2 .state/key LDZ #13 EQU ( C-s ) ;jump-to-next-match JCN2 @@ -1047,6 +1035,7 @@ ( this that for now i haven't done it. ) @on-key-prompt .state/key LDZ #07 EQU ( C-g ) ;cancel-prompt JCN2 + .state/key LDZ #08 EQU ( C-h ) ;help JCN2 .state/key LDZ #0d EQU ( \r ) ;finish-prompt JCN2 .state/key LDZ #7f EQU ( DEL ) ;backspace-prompt JCN2 .state/key LDZ #20 LTH ;ignore JCN2 ( ignore for now ) @@ -1071,6 +1060,7 @@ #00 .state/in-undo STZ .Console/read DEI .state/key STZ ;clear-message-line JSR2 + .state/in-help LDZ #00 .state/in-help STZ ;return JCN2 .searching/active LDZ ;on-key-searching JCN2 .prompt/active LDZ ;on-key-prompt JCN2 .state/saw-vt LDZ ;on-key-vt JCN2 @@ -1081,6 +1071,7 @@ .state/key LDZ #04 EQU ( C-d ) ;delete JCN2 .state/key LDZ #05 EQU ( C-e ) ;eol JCN2 .state/key LDZ #06 EQU ( C-f ) ;forward JCN2 + .state/key LDZ #08 EQU ( C-h ) ;help JCN2 .state/key LDZ #09 EQU ( \t ) ;insert-tab JCN2 .state/key LDZ #0c EQU ( C-l ) ;center-view JCN2 .state/key LDZ #0d EQU ( \r ) ;newline JCN2 @@ -1101,24 +1092,43 @@ @min2 ( x* y* -> min* ) LTH2k JMP SWP2 POP2 JMP2r +( ANSI terminal notes ) +( ) +( attrs [0-7] ) +( reset, bright, dim, underscore, ) +( blink, ???, reverse, hidden ) +( ) +( fg [30-37], bg [40-47] ) +( black, red, green, yellow, ) +( blue, magenta, cyan, white ) + ( ANSI control sequence to move the cursor to the given coord ) +( ESC [ $row ; $col H ) @term-move-cursor ( col* row* -> ) ansi INC2 ( row+1 ) ;emit-dec2 JSR2 emit-; INC2 ( col+1 ) ;emit-dec2 JSR2 emit-H JMP2r ( ANSI control sequence to move N positions right ) +( ESC [ $n C ) @term-move-right ( n* -> ) ansi ;emit-dec2 JSR2 emit-C JMP2r ( ANSI control sequence to get the cursor position ) +( ESC [ 6 n ) @term-get-cursor-position ( -> ) ansi emit-6 emit-n JMP2r ( ANSI control sequence to erase entire screen ) +( ESC [ 2 J ) @term-erase-all ( -> ) ansi emit-2 emit-J JMP2r +( ANSI control sequence to erase the current line ) +( ESC [ 2 K ) +@term-erase-line ( -> ) + ansi emit-2 emit-K JMP2r + ( method to add bits to the redraw register ) ( ) ( state/redraw uses 8 bits to represent which parts ) @@ -1189,10 +1199,9 @@ .cursor/row LDZ2 INC2 ;emit-dec2 JSR2 emit-) sp emit-[ LIT 's .config/insert-tabs LDZ ADD emit - emit-] sp emit-u emit-: - ;undo-stack/pos LDA2 ;undo-stack/data SUB2 #0003 DIV2 ;emit-dec2 JSR2 - - ;emit-reset JMP2 + emit-] sp + ;messages/help-msg ;print JSR2 + ;emit-reset JMP2 @draw-prompt ( -> ) ;clear-message-line JSR2 @@ -1210,7 +1219,7 @@ @draw-linenum ( n* -> ) ;emit-reset JSR2 ansi .config/color LDZ2 emit emit emit-m - ;emit-dec2-pad JSR2 + ;emit-dec2-pad JSR2 sp ansi emit-0 emit-m JMP2r @matches-at ( s* -> limit* ) @@ -1308,18 +1317,25 @@ &loop ORAk ,&next JCN POP2 POP2r JMP2r &next DEOkr INC2 ,&loop JMP +( ESC [ 1 m ) @emit-red ( -> ) ansi emit-3 emit-1 emit-m JMP2r +( ESC [ 0 m ) @emit-reset ( -> ) ansi emit-0 emit-m JMP2r +( ESC [ 1 m $ ESC [ 0 m ) @emit-red-dollar ( -> ) ;emit-red JSR2 emit-$ ;emit-reset JMP2 +( ESC [ 3 $x ; 7 m ) +( $x is 0-7 ) @emit-color-reverse ( -> ) ansi .config/color LDZ2 emit emit emit-; emit-7 emit-m JMP2r +( ESC [ 3 $x ; 1 m ) +( $x is 0-7 ) @emit-color-bold ( -> ) ansi .config/color LDZ2 emit emit emit-; emit-1 emit-m JMP2r @@ -1532,17 +1548,16 @@ ( emit a short as a decimal with leading spaces ) @emit-dec2-pad ( n* -> ) - #00 ,&zero STR - #2710 ,&parse JSR - #03e8 ,&parse JSR - #0064 ,&parse JSR - #000a ,&parse JSR - ,&emit JSR POP sp JMP2r - &parse DIV2k DUP ,&emit JSR MUL2 SUB2 JMP2r - &emit DUP [ LIT &zero $1 ] #0000 EQU2 ,&skip JCN - #01 ,&zero STR - #30 ADD #18 DEO JMP2r - &skip POP sp JMP2r + LITr 00 ( n [0] ) + &read ( n [k] ) + #000a DIV2k STH2k MUL2 SUB2 STH2r INCr ( n%10 n/10 [k+1] ) + STHkr #05 LTH ,&read JCN + POP2 ( top element was 0000 ) + &write0 ( n0 n1 ... nk [k+1] ) + DUP2 ORA ,emit-dec2/write JCN + POP2 sp LITr 01 SUBr + STHkr ,&write0 JCN + POPr JMP2r ( various string constants used as messages for the user ) @messages [ &null 00 @@ -1559,8 +1574,34 @@ &unknown-input "Unknown 20 "input: 20 00 &no-matches-found "No 20 "matches 20 "found: 20 00 &term-size-parse-error "Error 20 "parsing 20 "term 20 "size 00 + &help-msg "(help: 20 "C-h) 00 ] +@help-text + 09 "femto 20 "input 20 "reference 09 "(C 20 "is 20 "Ctrl, 20 "M 20 "is 20 "Meta/Alt ") 0d 0a + 0d 0a + 09 "quit 09 09 "C-x 09 09 "cancel 09 09 "C-g 0d 0a + 09 "save 09 09 "C-o 09 09 "undo 09 09 "C-u 0d 0a + 0d 0a + 09 "move 20 "up 09 09 "C-p 20 "(up) 09 "page 20 "up 09 09 "M-v 20 "(pg-up) 0d 0a + 09 "move 20 "down 09 "C-n 20 "(down) 09 "page 20 "down 09 "C-v 20 "(pg-dn) 0d 0a + 09 "move 20 "left 09 "C-b 20 "(left) 09 "line 20 "start 09 "C-a 20 "(home) 0d 0a + 09 "move 20 "right 09 "C-f 20 "(right) 09 "line 20 "end 09 "C-e 20 "(end) 0d 0a + 0d 0a + 09 "goto 20 "file 20 "start 09 "M-< 09 09 "left 20 "by 20 "word 09 "M-b 0d 0a + 09 "goto 20 "file 20 "end 09 "M-> 09 09 "right 20 "by 20 "word 09 "M-f 0d 0a + 09 "goto 20 "line 09 "M-g 09 09 "center 20 "cursor 09 "C-l 0d 0a + 0d 0a + 09 "search 09 09 "C-s 09 09 "toggle 20 "colors 09 "M-c 0d 0a + 09 "regex 20 "search 09 "M-s 09 09 "toggle 20 "tabs 09 "M-t 0d 0a + 09 "next 20 "match 09 "C-s 20 "(n) 0d 0a + 09 "prev 20 "match 09 "C-r 20 "(p) 0d 0a + 09 "end 20 "search 09 "enter 0d 0a + 09 "cancel 20 "search 09 "C-g 0d 0a + 0d 0a + 09 09 09 "press 20 "any 20 "key 20 "to 20 "continue... 0d 0a + 00 + ( perform the undo action ) @undo ( -> ) #01 .state/in-undo STZ @@ -1619,6 +1660,6 @@ ] ( actual file data to be edited ) -@data $d200 +@data $d000 ( end of femto.tal ) diff --git a/femto.txt b/femto.txt index a505796..e570ae2 100644 --- a/femto.txt +++ b/femto.txt @@ -16,7 +16,7 @@ development. although it seems to work fairly reliably it has bugs! please consider making backups (or using version control) -before femto this to modify important files. +before using femto to modify important files. ---- getting started ---- @@ -30,7 +30,6 @@ the femto launcher script makes many assumptions: - uxnasm and uxncli are both in the PATH - femto.tal is in the same directory as femto - - femto.rom should be (re)assembled every time - femot.rom should be written in the same directory once femto is not in active development a more robust @@ -42,7 +41,6 @@ packaging process can be explored. - doesn't support horizontal scrolling for long lines - no search & replace - no copy/paste - - few help messages - doesn't support function keys, mouse, etc. ---- status line ---- @@ -54,13 +52,15 @@ the femto status line contains a lot of information: 3. the number of bytes/lines (e.g. "[49 bytes, 8 lines]" 4. the x/y cursor position (e.g. "(1,8)" for col 1, row 8) 5. whether tabs ("[t]") or spaces ("[s]") are inserted by tab key - 6. how many items are in the undo stack (e.g. "u:13") + 6. how to run the help command (C-h) ---- special key bindings ---- C-g cancel (used with commands like save, search, etc.) - C-o save + C-h help C-x quit + C-o save + C-u undo C-b move back one character (or LEFT ARROW) C-f move forward one character (or RIGHT ARROW) @@ -98,6 +98,8 @@ the following commands: - n (or C-s): move forward to the next match, if any - p (or C-r): move backwards to the previous match, if any -basic regular expression syntax is mostly working, although there -are notable absences such as character classes (e.g. [] and [^]), +regex support is a work in progress, but basic regular expression syntax is +mostly working. + +there are notable absences such as character classes (e.g. [] and [^]), references to capture groups (e.g. \1), and repetitions (e.g. {n}). diff --git a/mksite.sh b/mksite.sh index edd0228..b04c259 100755 --- a/mksite.sh +++ b/mksite.sh @@ -1,6 +1,6 @@ #!/bin/sh -for NAME in about.txt math32.tal test-math32.tal test-math32.py primes32.tal regex.tal repl-regex.tal test-regex.tal grep.tal femto.tal femto.txt femto rainbow.tal drums.tal drums2.tal bfloat16.tal fix16.tal fixed.tal tal-mode1.png tal.nanorc; do +for NAME in about.txt math32.tal test-math32.tal test-math32.py primes32.tal regex.tal repl-regex.tal test-regex.tal grep.tal femto.tal femto.rom femto.txt femto rainbow.tal drums.tal drums2.tal bfloat16.tal fix16.tal fixed.tal tal-mode1.png tal.nanorc; do echo "-> $NAME" cp $NAME /var/www/plastic-idolatry.com/html/erik/nxu done