2012-07-24 43 views
3

我开发了一个包含可执行脚本(rubygems术语为application file)的gem。调用的时候,我想完成一个指定目录的文件名(这是不是当前工作目录),像这样:一个宝石二进制文件可以自己完成标签吗?

foo edit my<tab> 

被扩展为:

foo edit myfile 

我能做什么包括一个安装shell完成的脚本。如果这是唯一的解决方案 - 很好。但是我想知道是否有一种方法可以将用户从额外的步骤中解放出来,并直接在我的创业板中包含完成项。

所以:有没有办法让宝石自带标签填写?

回答

1

当你键入的命令来启动你的脚本,脚本尚未运行。它们在输入时仍不能干预自己的论点。如果可能,可以让gem文件安装bash完成文件,并修改用户的~/.bashrc文件以将其作为安装过程的一部分加载。

+0

我知道:(我希望解决这个“安装过程” - 不管它是一个约定(“把你的完成点放在这里,他们将被自动使用”)或其他东西... – awendt 2012-07-25 09:46:46

0

看看Ruby的Abbrev模块。 (About.com也有一些useful information

从文档:

 
Calculate the set of unique abbreviations for a given set of strings. 

require 'abbrev' 
require 'pp' 

pp Abbrev::abbrev(['ruby', 'rules']).sort 
Generates: 

[["rub", "ruby"], 
["ruby", "ruby"], 
["rul", "rules"], 
["rule", "rules"], 
["rules", "rules"]] 
Also adds an abbrev method to class Array. 

我读到的目录,文件和子目录传递给其它名称,并将结果转换成散列。注意用户类型。如果他们按标签看看他们键入的内容是否与散列中的键匹配。如果它输入的内容是唯一的并且可以解析为该元素的值。

这是如何将缩略的输出到一个哈希:

irb(main):009:0> hash = Hash[%w[ruby rules].abbrev] 
=> {"rub"=>"ruby", "rule"=>"rules", "rul"=>"rules", "ruby"=>"ruby", "rules"=>"rules"} 
+0

我想我没有清楚地陈述我的问题:我不想以编程方式使用Tab完成,我只是想以某种方式在调用脚本时“捆绑”shell的完成脚本。或者我读了你的答案错了? – awendt 2012-07-24 12:51:16

+1

你不清楚。 gem是Ruby代码,再加上一些额外的元数据来让它正确安装。 Shell自动完成取决于用户运行的shell;我使用BASH和自动完成适用于传递给所有可执行文件的所有文件/文件夹。我写的Ruby脚本由于shell而自动拥有它。 shell可以告诉脚本里面的命令,但我不想让这个gem搞乱,这对我,用户来说是这样做的。 – 2012-07-24 14:55:29

+0

是的,我想这是一个宝石摆弄用户外壳的问题。我想最好的办法是在shell上转储完成脚本,以便用户可以复制它... – awendt 2012-07-25 09:49:07

0

虽然chepner已经得出正确的结论,安装是不可避免的,但我会建议看看其他项目如何解决这个问题。


的特拉维斯CI 特拉维斯宝石提供首次执行安装完工。它节省完成脚本〜/ .travis/travis.sh然后追加以下至的.bashrc

# added by travis gem 
[ -f ~/.travis/travis.sh ] && source ~/.travis/travis.sh 

前面的例子是有点侵入。有关更自由放任的方法,请参阅Python的pip(与Ruby的gem类似)。它有一个隐藏的完成选项,它向stdout输出一个bash或zsh完成脚本。由用户决定如何获取它。

pip completion --bash输出以下:

# pip bash completion start 
_pip_completion() 
{ 
    COMPREPLY=($(COMP_WORDS="${COMP_WORDS[*]}" \ 
        COMP_CWORD=$COMP_CWORD \ 
        PIP_AUTO_COMPLETE=1 $1)) 
} 
complete -o default -F _pip_completion pip 
# pip bash completion end 

在一个有些不同,但是相关说明...如果你看一下上述脚本完成,你会发现它做的东西比较奇特。它使用第三个选项,而不是使用静态完成列表(必须经常更新并且容易出现错误)或通过解析帮助消息动态生成完成(通常无法接受地较慢)。它直接在pip中传递命令行状态,以使其生成完成。


也许最相关的,也是最伟大的方法是创建一个Ruby宝石的全局完成脚本。用户只需安装一个全局完成gem(没有任何解决方法),然后完成即可用于任何其他gem。据我所知,没有人在Ruby中实现过。对于Python实现,请参阅argcomplete

安装如下:

pip install argcomplete 
activate-global-python-argcomplete --dest=/path/to/bash_completion.d 

脚本很容易适应。它基本上是一个单线程来将您的解析器对象传递给argcomplete。

相关问题