rlwrap:tclsh 多单词自动完成

rlwrap:tclsh 多单词自动完成

如何使用rlwrapfor获得多单词自动完成功能tclsh

示例:我键入file <space>然后按<tab> <tab>我只想查看 的子命令file,例如exists isdirectoryisfile

我尝试添加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_filterrlwrap -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/^-//; $_} @完成;
  }

  返回@完成;
}

相关内容