如何使用rlwrap
for获得多单词自动完成功能tclsh
?
示例:我键入file
<space>
然后按<tab>
<tab>
我只想查看 的子命令file
,例如exists
isdirectory
或isfile
。
我尝试添加file\ isfile
(即转义空格)到完成文件中,但这没有帮助。它只是导致isfile
显示为另一个自动完成命令。
我想我可以使用过滤器完成多单词自动完成rlwrap
,但没有明显的例子/usr/share/rlwarp/filters/
可供我参考。
答案1
至少,有一个过滤器目录tclsh_filter
的示例rlwrap
(确保chmod +x
它):
#!/usr/bin/env perl
use strict;
use warnings;
use lib $ENV{RLWRAP_FILTERDIR};
use RlwrapFilter;
# log to some other terminal, so rlwrap terminal not cluttered up
# by any debug output - FIXME
my $DEBUG_TERMINAL = '/dev/pts/2';
open my $logfh, '>', $DEBUG_TERMINAL or die "aaaaaarrgh: $!\n";
my $filter = RlwrapFilter->new;
$filter->completion_handler(\&completion);
$filter->run;
sub completion {
my ($input, $prefix, @completions) = @_;
print $logfh "I,$input, P,$prefix, C,@completions\n";
# more complicated would be to use a lex-like scanner or Parser::MGC
# instead of this dumb regex against the input line, and even more
# complicated would be to return "exists" if the user has typed
# "file e" and is mashing tab, but that's more work
if ($input =~ m/file\s+$/) {
@completions = qw/exists isdirectory isfile/;
}
return @completions;
}
然后通过运行它rlwrap -z tclsh_filter tclsh
答案2
在优秀答案的帮助下特里格我为 编写了以下 tclsh 多字完成过滤器tclsh
。下面的脚本应存储tclsh_filter
在rlwrap -z tclsh_filter tclsh
.记得chmod +x tclsh_filter
。
#!/usr/bin/env perl 使用严格; 使用警告; 使用 lib $ENV{RLWRAP_FILTERDIR}; 使用RlwrapFilter; 我的 @tcl_cmds = qw/encoding if pid tcl_endOfWord eof incr pkg::create tcl_findLibrary after error info pkg_mkIndex tcl_startOfNextWord append eval interp proc tcl_startOfPreviousWord array exec join put tcl_wordBreakAfter auto_execok exit lappend pwd tcl_wordBreakBefore auto_import expr lindex re_syntax t cltest auto_load fblocked linsert 读取 tclvars auto_mkindex fconfigure 列表regexp 告诉 auto_mkindex_old fcopy llength 注册表时间 auto_qualify 文件加载 regsub 跟踪 auto_reset fileevent lrange 重命名未知 bgerror 文件名 lreplace 返回未设置的二进制刷新 lsearch 扫描更新中断 lset 寻求上层捕获 foreach lsort 设置 upvar cd 格式内存套接字变量时钟获取 msgcat 源 vwait 关闭 glob 命名空间split while concat 全局打开字符串 继续历史包 subst dde http parray switch/; # 下面是从 tcl.tk 网页复制粘贴的内容。 我的 $tcl_txt = <<END; 文件 atime 名称?时间? 文件属性名称 文件属性名称?选项? 文件属性名称?选项值选项值...? 文件通道?模式? 文件复制?-强制? ?--?源目标 文件复制?-强制? ?--?来源?来源...?目标目录 文件删除?-强制? ?--?路径名?路径名...? 文件目录名名称 文件可执行文件名称 文件存在名称 文件扩展名 文件是目录名 文件是文件名 文件连接名称?名称...? 文件链接?-链接类型?链接名称?目标? 文件 lstat 名称 varName 文件 mkdir dir ?dir ...? 文件 mtime 名称?时间? 文件 nativename 名称 文件规范化名称 文件所属名称 文件路径类型名称 文件可读名称 文件读取链接名称 文件重命名?-强制? ?--?源目标 文件重命名?-强制? ?--?来源?来源...?目标目录 文件根名名称 文件分隔符?名称? 文件大小名称 文件分割名称 文件统计名称 varName 文件系统名称 文件尾名 文件类型名称 文件卷 文件可写名称 字符串比较?-nocase??-length int?string1 string2 字符串等于 ?-nocase? ?-长度 int?字符串1 字符串2 第一个字符串 NeedleString haystackString ?startIndex? 字符串索引 字符串 charIndex 字符串是 alnum ?-strict? ?-failindex 变量名?细绳 字符串是字母 字符串是ascii 字符串是布尔值 字符串是控制 字符串是数字 字符串是双的 字符串为假 字符串是图 字符串是整数 弦较低 字符串是打印的 字符串是标点符号 字符串是空格 字符串为真 字符串位于上方 字符串是单词字符 字符串是x位 字符串最后一个needleString haystackString?lastIndex? 字符串长度 字符串 字符串映射 ?-nocase? 映射字符串 字符串匹配?-nocase?模式串 字符串范围 字符串 第一个 最后一个 字符串重复字符串计数 字符串替换字符串第一个最后一个?newstring? 字符串到下面的字符串?首先? ?最后的? 字符串到标题字符串?首先? ?最后的? 字符串顶部字符串?首先? ?最后的? 字符串修剪字符串?字符? 字符串修剪左字符串?字符? 字符串修剪右字符串?字符? 排序-ascii lsort-字典 lsort-整数 lsort-实数 lsort-命令命令 lsort-增加 lsort 递减 lsort -index 索引 lsort-唯一 正则表达式-关于 正则表达式扩展 正则表达式-索引 正则表达式行 正则表达式-linestop 正则表达式-lineanchor 正则表达式-nocase 正则表达式-全部 正则表达式-内联 正则表达式-起始索引 正则表达式—— 结尾 我的@multi; foreach 我的 $line (split /\n/, $tcl_txt) { $line =~ s/\?//g; $line =~ s/ - -/ --/g; $line =~ s/ \.\.\.//g; $line =~ s/\s{2,}/ /g; $line =~ s/\s+$//; 推@multi,$line; if ($line =~ /^(.*\s)(-\w+)\s(-\w+)(.*)$/) { 推@multi,“$1$3$2$4”; } } 我的 $filter = RlwrapFilter->new; $filter->completion_handler(\&completion); $过滤器->运行; 子完成{ 我的($输入,$前缀,@完成)= @_; $输入 =~ s/\s+/ /g; # 支持复合表达式的补全。 Hacky,有限的语法支持。 $输入=~s/^[^[]+\[//; $输入 =~ s/^.*;\s*//; # 如果最后一个完整的单词是选项,请删除它们,以便我们可以重新启动选项 # 匹配。 $输入 =~ s/(?:\s-\w+)+\s((?:-\w+)?)$/ $1/; 我的 $word_cnt = () = $input =~ m/\b\s+/g; 如果($word_cnt == 0){ @completions = grep /^\Q$input\E/, @tcl_cmds; } 别的 { 我的@mmatch = grep /^\Q$input\E/, @multi; @completions = map {my @F = split /\s/, $_; $F[$word_cnt]} @mmatch; # rlwrap 似乎有一个“特征”,其中以“-”开头的单词是 # 前面加上“-”,迫使我们删除破折号。缺点是 # 将列出不带“-”的选项。 @completions = 地图 {s/^-//; $_} @完成; } 返回@完成; }