Version 10 of info complete

Updated 2011-11-18 16:03:49 by dkf
info complete command

Returns 1 if command is a complete Tcl command in the sense of having no unclosed quotes, braces, brackets or array element names, If the command doesn't appear to be complete then 0 is returned. This command is typically used in line-oriented input environments to allow users to type in commands that span multiple lines; if the command isn't complete, the script can delay evaluating it until additional lines have been typed to complete the command.

RS: Could it be that info complete can be used generally to check whether a string can be parsed as a list? I used to use

 expr {![catch {llength $x}]}

for that purpose...

The answer: "no". It is possible for a string to be "info complete" but not be a list. To wit:

  % set foo "{this is a test}{more stuff}"
  {this is a test}{more stuff}
  % llength $foo
  list element in braces followed by "{more" instead of space
  % info complete $foo
  1

AMG: It seems odd to me that [info complete] doesn't return false when its argument has a trailing backslash (or an odd number of trailing backslashes), since that's normally used to signify that the command is continued onto the next line. An interactive shell relying on [info complete] likely has to implement its own check for trailing backslashes, e.g.:

proc complete {script} {
    expr {[info complete $script] && [regexp {(?:^|[^\\])(?:\\\\)*$} $script]}
}

Example usage:

# single word
info complete a            ;# 1
complete      a            ;# 1

# two words
info complete a\ b         ;# 1
complete      a\ b         ;# 1

# unclosed quote
info complete \"a          ;# 0
complete      \"a          ;# 0

# closed quote
info complete \"a\"        ;# 0
complete      \"a\"        ;# 0

# unclosed brace
info complete \{a          ;# 0
complete      \{a          ;# 0

# closed brace
info complete \{a\}        ;# 1
complete      \{a\}        ;# 1

# unclosed nested brace
info complete \{\{a\}      ;# 0
complete      \{\{a\}      ;# 0

# line ends in double backslash
info complete a\\\\        ;# 1
complete      a\\\\        ;# 1

# line ends in single backslash
info complete a\\          ;# 1
complete      a\\          ;# 0

DKF: The key is that info complete in those cases sees a backslash at the end of a string which is OK, complete. It's when the backslash is followed by a newline that things are magically different:

puts [info complete "abc\\"]        ;# 1
puts [info complete "abc\\\n"]      ;# 0
puts [info complete "abc\\\ndef"]   ;# 1
puts [info complete "abc\\\n "]     ;# 1