2012-07-24 45 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。

相關問題