'''2004-06-16''' [SRIV] This is a minimal console text editor for Linux written in pure TCL. Usage: con-editor.tcl filename After the file loads, the screen is blank till you hit the down arrow key, I forget why I did that. To save the file, press Ctrl-Q, it will prompt you to Save Y/n . Ctrl-Y will delete the current line. I notice that the backspace key isn't working properly on my current computer, so I'll need to look into that. Update: backspace works at a true console, but misbehaves in an xterm. It also is fixed at 24x80, so the editor wont use more that that, like on a 50x132 framebuffer system. ---- [LV] Perhaps the backspace key would work if you added a \u0008 (^h) to the current \u0007f (^?) case? ([JH]: Yes, added in) ---- Edited by [JH] 2005-05-04 to support any size terminal and clean up the code for improved readability. Anyone wanting to interpret more escape codes should find it easier to work with. Screenshot: [http://www.sriv.net/images/con-editor.jpg] ---- #!/bin/sh # The next line is executed by /bin/sh, but not tcl \ exec tclsh "$0" ${1+"$@"} # con-editor.tcl a linux console based editor in pure tcl # 2004-06-16 Steve Redler IV # 2005-05-04 mods by Hobbs to work in any terminal size and clean up code set filename [lindex $argv 0] proc edittext {file2read visible} { global CLEAR buffer HOME CURSOROFF CURSORON IDX set COLUMN 1 set ROW 1 set lastrow "" set lastcol "" set firstcol2display "" set firstrow2display "" set line "" set bufferrow 0 set buffercol 0 set char "" puts -nonewline $CURSOROFF$HOME while {$char != "\u0011"} { set char [read $file2read 1] if {[eof $file2read]} {return done} switch -exact -- $char { \u0011 { # ^q - quit return done } \u0019 { # ^y - yank line if {$bufferrow < [llength $buffer]} { set buffer [lreplace $buffer $bufferrow $bufferrow] set lastcol "" } } \u000a { # ^j - insert last yank set currline [string range $line 0 [expr {$buffercol - 1}]] set buffer [lreplace $buffer $bufferrow $bufferrow $currline] if {!$visible} {set IDX(ROW) $bufferrow} incr bufferrow incr ROW set buffer [linsert $buffer $bufferrow \ [string range $line $buffercol end]] set lastcol "" set line [lindex $buffer $bufferrow] set buffercol 0 } \u001b { # ESC - handle escape sequences set next [read stdin 1] if {$next == "\["} { ; # \[ set next [read stdin 1] switch -exact -- $next { A { # Cursor Up (cuu1,up) if {$bufferrow > 0} {incr bufferrow -1} set line [lindex $buffer $bufferrow] incr ROW -1 } B { # Cursor Down if {$bufferrow < [expr {[llength $buffer] -1}]} { incr bufferrow 1 } set line [lindex $buffer $bufferrow] if {$bufferrow > [expr {$ROW -1}]} { incr ROW } } C { # Cursor Right (cuf1,nd) if {$buffercol < [string length $line]} { incr buffercol 1 } } D { # Cursor Left if {$buffercol > 0} {incr buffercol -1 } } 3 { # delete set next [read stdin 1] if {$buffercol > [string length $line]} { set buffercol [string length $line] } set prevchr $buffercol set line [string replace $line $prevchr $prevchr ""] set buffer [lreplace $buffer $bufferrow $bufferrow $line] set lastcol "" } } } } \u0008 - \u007f { # ^h && backspace if {$buffercol != 0} { if {$buffercol > [string length $line]} { set buffercol [string length $line] } set prevchr [expr {$buffercol - 1}] set line [string replace $line $prevchr $prevchr ""] incr buffercol -1 } set buffer [lreplace $buffer $bufferrow $bufferrow $line] set lastcol "" } default { if {$char == "\u0009"} { # ^i - insert tab space (4 spaces) set char " " } append newline [string range $line 0 [expr {$buffercol - 1}]] \ $char [string range $line $buffercol end] set line $newline set newline "" set buffer [lreplace $buffer $bufferrow $bufferrow $line] incr buffercol [string length $char] if {$buffercol > [string length $line]} { set buffercol [string length $line] } set lastcol "" } } if {$visible} { if {$ROW <= 1} {set ROW 1} if {$ROW >= ($IDX(ROWMAX) - 1)} {set ROW [expr {$IDX(ROWMAX) - 1}]} set COLUMN [expr {$buffercol + 1}] if {$COLUMN <= 1} {set COLUMN 1} if {$COLUMN >= $IDX(COLMAX)} {set COLUMN $IDX(COLMAX)} puts -nonewline $CURSOROFF$HOME set firstrow2display [expr {$bufferrow - $ROW +1}] set lastrow2display [expr {$firstrow2display + $IDX(ROWMAX) - 1}] set firstcol2display [expr {$buffercol - $COLUMN +1}] set lastcol2display [expr {$firstcol2display + $IDX(COLMAX) - 1}] if {($lastrow != $firstrow2display) || ($lastcol != $firstcol2display)} { for {set i $firstrow2display} {$i < $lastrow2display} {incr i} { puts -nonewline "\u001b\[K" puts [string range [lindex $buffer $i] $firstcol2display $lastcol2display ] } } set lastrow $firstrow2display set lastcol $firstcol2display set IDX(ROW) [expr {$bufferrow +1}] set IDX(COL) [expr {$buffercol +1}] idx $IDX(ROW) $IDX(COL) puts -nonewline "\u001b\[${ROW};${COLUMN}H" puts -nonewline $CURSORON flush stdout } } } proc status {msg} { global IDX set len [expr {$IDX(ROWCOL) - 1}] set str [format "%-${len}.${len}s" $msg] puts -nonewline "\u001b\[$IDX(ROWMAX);00H$str" } proc idx {row col} { global IDX set len $IDX(ROWCOLLEN) set str [format "%-${len}.${len}s" "LINE:$row COL:$col"] puts -nonewline "\u001b\[$IDX(ROWMAX);$IDX(ROWCOL)H$str" } #start of console editor program #puts -nonewline $CLEAR proc console_edit {fileName} { global CLEAR buffer HOME CURSOROFF CURSORON IDX #Script-Edit by Steve Redler IV steve@sr-tech.com 5-30-2001 set IDX(ROWMAX) 24 set IDX(COLMAX) 80 if {![catch {exec stty -a} err] && [regexp {rows (\d+); columns (\d+)} $err -> rows cols]} { set IDX(ROWMAX) $rows set IDX(COLMAX) $cols } set IDX(ROWCOLLEN) 15 set IDX(ROWCOL) [expr {$IDX(COLMAX) - $IDX(ROWCOLLEN)}] set CLEAR "\u001b\[2J" ; # \u001b == ESC set buffer [list {}] set HOME "\u001b\[1;1H" set CURSORON "\u001b\[?[expr {$IDX(ROWMAX)+1}]h" set CURSOROFF "\u001b\[?[expr {$IDX(ROWMAX)+1}]l" set infile [open $fileName RDWR] edittext $infile 0 close $infile puts -nonewline $CLEAR$HOME$CURSORON status "\u0007$fileName loaded" idx $IDX(ROW) 1 fconfigure stdin -buffering none -blocking 1 fconfigure stdout -translation crlf flush stdout exec stty raw -echo edittext stdin 1 status "Save '$fileName'? Y/n" flush stdout #fconfigure stdin -buffering full -blocking 1 set line [read stdin 1] exec stty -raw echo if {$line != "n"} { set outfile [open $fileName w ] puts "len of buffer [llength $buffer]" for {set i 0} {$i<[llength $buffer]} {incr i} { puts $outfile [lindex $buffer $i] #puts [lindex $buffer $i] } close $outfile status " Saved" } else { status " Aborted" } puts -nonewline $CLEAR$HOME exit 0 } console_edit $filename ---- [Category Application]