fix(completion): scan nested commands in unfinished braced args #37

Merged
Christoph merged 1 commits from #36 into main 2026-09-08 19:21:50 +00:00
4 changed files with 63 additions and 1 deletions
Showing only changes of commit 82e13cf7ce - Show all commits
+26
View File
@@ -17,6 +17,19 @@
],
"cwd": "${env:TEMP}/nx-post-support-vscode-debug",
"outFiles": ["${env:TEMP}/nx-post-support-vscode-debug/dist/**/*.js"],
"linux": {
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"${workspaceFolder}",
"${workspaceFolder}/test/test.tcl"
],
"cwd": "${workspaceFolder}",
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"resolveSourceMapLocations": [
"${workspaceFolder}/dist/**/*.js",
"!**/node_modules/**"
]
},
"sourceMaps": true,
"resolveSourceMapLocations": [
"${env:TEMP}/nx-post-support-vscode-debug/dist/**/*.js",
@@ -50,6 +63,19 @@
],
"cwd": "${env:TEMP}/nx-post-support-vscode-debug",
"outFiles": ["${env:TEMP}/nx-post-support-vscode-debug/dist/**/*.js"],
"linux": {
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"${workspaceFolder}",
"${workspaceFolder}/test/test.tcl"
],
"cwd": "${workspaceFolder}",
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"resolveSourceMapLocations": [
"${workspaceFolder}/dist/**/*.js",
"!**/node_modules/**"
]
},
"sourceMaps": true,
"resolveSourceMapLocations": [
"${env:TEMP}/nx-post-support-vscode-debug/dist/**/*.js",
+7
View File
@@ -15,6 +15,13 @@
"${workspaceFolder}",
"${env:TEMP}\\nx-post-support-vscode-debug"
],
"linux": {
"command": "npm",
"args": ["run", "compile:debug"],
"options": {
"cwd": "${workspaceFolder}"
}
},
"problemMatcher": [],
"presentation": {
"reveal": "always",
+7 -1
View File
@@ -1009,7 +1009,13 @@ def _current_command_segment(line_prefix: str) -> str:
starts.append(brace_starts[-1] + 1)
if bracket_starts:
starts.append(bracket_starts[-1] + 1)
return line_prefix[max(starts) :]
start = max(starts)
if brace_starts and start == brace_starts[-1] + 1:
# An unfinished braced body or expression can itself contain commands
# (for example, ``if {[string compare ...``). Scan that inner context
# independently, while keeping completed braced arguments opaque.
return _current_command_segment(line_prefix[start:])
return line_prefix[start:]
def _tokenize_command_segment(segment: str) -> list[str]:
@@ -204,6 +204,29 @@ def test_string_completion_handles_nested_commands_and_is_values():
}
def test_string_completion_inside_braced_conditions_and_bodies():
for prefix in ("if {", "while {", "proc example {} { if {"):
subcommands = _argument_completion_labels(prefix + "[string ")
assert subcommands is not None
assert {"compare", "equal", "is"} <= subcommands
assert _argument_completion_labels(prefix + "[string compare -") == {
"-length", "-nocase"
}
assert _argument_completion_labels(
prefix + "[string compare -nocase "
) == {"-length"}
def test_closed_braced_arguments_do_not_change_completion_context():
assert _argument_completion_labels("puts {[string compare }") is None
assert _argument_completion_labels(
"if {[string equal a b]} {string compare "
) == {"-length", "-nocase"}
assert _argument_completion_labels(
"if {[string equal a b] && [string is integer "
) == {"-failindex", "-strict"}
def test_dict_array_namespace_file_and_info_subcommands():
dict_items = _argument_completion_labels("dict ")
assert dict_items is not None