'''[info] complete''' indicates whether a string is a complete Tcl script. ** Synopsis ** : '''[info] complete''' ''script'' ** Description ** Returns '''`1`''' if ''script'' is a complete in the sense that the following things are syntactically complete: * braced words * quoted words * command substitutions (brackets) * array element names * commands Otherwise, `info complete` returns '''`0`'''. 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. A command is not considered complete if it ends in a backslash followed by a newline: ====== info complete \\\n # -> 0 ====== However, a script ending in just a backslash may be complete: ====== info complete \\ # -> 1 ====== Therefore, when using `info complete` on a line that has been read from a channel using `[gets]`, the `\n` stripped off by `[gets]` should be re-added first. See also issue [https://core.tcl.tk/tcl/tktview?name=1775878%|%1775878]. `info complete` is not a full Tcl syntax checker, and there are some values that it considers complete even though they contain syntax errors. As previously stated, the purpose of `info complete` is to determine whether enough of the script has been read to parse it as a sequence of complete commands. ** Examples ** [Tool Protocol Language]: uses info complete to parse data that is formatted as a syntactically valid Tcl script. ** Not for validating [list%|%lists] ** [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: ======none % 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 ====== ** Trailing Backslash ** <> [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\" ;# 1 complete \"a\" ;# 1 # 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 ====== [AMG]: Therefore, the desired functionality (for the use case described at the top of this page) can be had simply: ====== proc complete {script} { info complete $script\n } ====== That's cool. As far as I know, this version of `complete` gives exactly the same results as the one involving `[regexp]`. [PYK] 2014-04-23: It's also the solution implemented to fix issue [https://core.tcl.tk/tcl/tktview?name=1775878%|%1775878] <> <> Command | Tcl syntax