Reputation: 13
Considering the following code:
puts "What show command would you like to execute?"
set cmd [gets stdin]
proc makeLC {str} {
puts "begin"
puts $str
set lStr [string tolower $str]
set lStr [string trim $lStr]
puts "after low and trim"
puts $lStr
set lenStr [string length $lStr]
for {set i 0} {$i < $lenStr} {incr i} {
puts [string index $lStr $i]
}
return $lStr
}
set lcmd [makeLC $cmd]
When a user types "test12345" then backspaces to display "test123" then adds "67" to finally display "test12367" puts $lStr returns "test12367" but the "for" loop will display "test12345 67" the spaces between "12345" and "67" I believe are "\b\b".
Why the inconsistancy?
and how do I ensure that when passing $lStr that "test12367" is assigned and "test12345 67" is not
Upvotes: 1
Views: 900
Reputation: 137567
Normally, Tcl programs on Unix are run in a terminal in “cooked” mode. Cooked mode terminals handle all the line editing for you; you can simply just read the finished lines as they are produced. It's very easy to work with cooked mode. But you can also put the terminal into raw mode, where (typically) the application decides to handle all the key strokes directly itself. (It's usual to turn off echoing of characters at the same time so applications handle the output side as well as the input side.) This is what editors like vi and emacs do, and so does the readline library (used in many programs, like bash). Raw mode is a lot more fiddly to work with, but gives you much more control. Separately from this is whether what is typed is echoed so it can be seen; for example, there's also non-echoing cooked mode, which is useful for passwords.
In your case, it sounds very much like the terminal is in echoing raw mode (unusual!) and your application expects it to be in echoing cooked mode; you're getting the actual character sent from the keyboard when the delete key is pressed (or maybe the backspace key; there's a lot of complexity down there!) which is highly unusual. To restore sanity, do:
# No raw, Yes echo
exec stty -raw echo <@stdin >@stdout
There's something conceptually similar on Windows, but it works through totally different system calls.
Upvotes: 2
Reputation: 55443
Consider using tclreadline
which wraps GNU readline providing full support for interactive command-line editing.
Another solution which relies on the presence of an external tool is to wrap the call to the Tcl shell in rlwrap
:
rlwrap tclsh /path/to/script/file.tcl
Upvotes: 0