我正在尝试使用TCL做一些可变的自动完成(这是为jimtcl设计的)。
我在tclsh和jimsh中都尝试了以下序列:
% set VAR1 1
1
% set VAR2 2
2
% info vars
.... tcl_pkgPath VAR1 tcl_patchLevel VAR2 argc ...
% set pattern \$V*
$V*
% set vars_pattern [string range $pattern 1 end]
V*
% puts [lsort [info vars $vars_pattern]]
VAR1 VAR2
% 这很好。
但一旦我把这个写进了程序
% proc autocomplete_helper pattern {
# check for variables auto-completion
puts "pattern '$pattern'"
if {[regexp {\$\S+$} $pattern match]} {
set vars_pattern [string range $match 1 end]
puts "pattern '$vars_pattern'"
return [lsort [info vars $vars_pattern]]
}
puts "other stuff to do"
}
% autocomplete_helper zerazer
pattern 'zerazer'
other stuff to do
% autocomplete_helper \$V*
pattern '$V*'
pattern 'V*
% 你知道为什么这不管用吗?
发布于 2021-08-19 07:26:49
info vars命令对它当前的上下文很敏感(很明显,它返回当前可见的变量),并将事物移动到一个过程中来改变它。正确的解决方法是使用uplevel在不同的上下文中运行命令,要么在调用者的上下文中运行uplevel 1,要么在全局上下文中运行uplevel #0 (堆栈顶部的上下文)。
在这种情况下,我们需要谨慎一点,因为模式中可能包含元字符(这可能很奇怪,但是合法的),而uplevel是eval-like;list命令将确保我们有一个格式良好的命令。在明显的点(其他一切不变)将这一行放入您的过程中。
# The double quotes around #0 are to fool the highlighter used on Stack Overflow
return [lsort [uplevel "#0" [list info vars $vars_pattern]]]有了这个,我就能做到:
% autocomplete_helper {$e*}
pattern '$e*'
pattern 'e*'
env errorCode errorInfo在我看来是对的。
发布于 2021-08-18 22:28:49
这是一个命名空间问题。
proc有自己的命名空间。当您在tclsh提示符下运行info vars时,这是全局::命名空间。
在proc中最简单的方法是将::添加到info vars中。
返回[lsort vars ::$vars_pattern]
返回值将包括::名称空间前缀,因此如果需要,首先删除它。
有趣的是,你看到了一个自动完成应用程序的问题。我已经编写了一个Tcl脚本,将我的所有进程、命令、命名空间等转储到json文件中,我将这些文件读入Vim中,用于定制的自动完成插件。我在写这篇文章时发现了同样的问题。
https://stackoverflow.com/questions/68839781
复制相似问题