Bash और Zsh में सरल tab auto-completion लिखना
(mill-build.org)- Bash और Zsh में ऐसे tab auto-completion फीचर को लागू करने का तरीका पेश किया गया है जो पहले से complete हुए शब्दों पर भी description दिखाता है
- Bash और Zsh अलग-अलग tab auto-completion API का उपयोग करते हैं, और डिफ़ॉल्ट रूप से केवल Zsh में auto-completion के साथ description दिखाने की सुविधा होती है
_generate_foo_completionsसे candidates बनाए जाते हैं, और Bash मेंCOMPREPLY, जबकि Zsh मेंcompaddके जरिए उन्हें return करने वाली संरचना लागू की जाती है- Zsh की description सुविधा को Bash में भी लागू करने के लिए candidate string में description शामिल किया जाता है, और केवल single candidate होने पर description हटाया जाता है
- single candidate होने पर भी
<TAB>इनपुट पर description दिखाने के लिए जानबूझकर ambiguity जोड़ी जाती है - अंतिम script दोनों shells में एक जैसा user experience देता है, और partial completion, full completion, candidate description display तीनों को support करता है
समस्या की पृष्ठभूमि
- tab auto-completion कमांड या flags को explore करते समय उपयोगी है, खासकर जब कोई API या CLI tool पहली बार इस्तेमाल किया जा रहा हो
- Zsh डिफ़ॉल्ट रूप से सिर्फ तब description दिखाता है जब कई candidates हों, जबकि Bash में यह अलग configuration के बाद ही संभव है
- लेकिन पहले से complete हुए शब्द के लिए दोनों shells description नहीं दिखाते
- इसके कारण user को description देखने के लिए यह झंझट करना पड़ता है
- कुछ characters हटाने पड़ते हैं ताकि कई candidates match हों
- candidates की सूची देखने के लिए
<TAB>key दबानी पड़ती है - मनचाहा description visually ढूँढना पड़ता है
- फिर हटाए गए characters दोबारा टाइप कर command चलानी पड़ती है
समाधान का अवलोकन
- single candidate होने पर भी dummy candidate जोड़कर candidates को ambiguous बनाया जाता है
- इससे Bash और Zsh दोनों candidate list के साथ description output करने लगते हैं
- लेकिन यह ध्यान रखना ज़रूरी है कि actual command में description text insert न हो
बुनियादी अवधारणा
- tab auto-completion
<TAB>इनपुट पर current word और cursor position लेकर possible candidates की सूची return करता है - Bash: candidates को
COMPREPLYarray में assign किया जाता है - Zsh: candidates को
compaddcommand से register किया जाता है _generate_foo_completionsfunction candidate strings output करता है, और व्यवहार में इन्हें CLI की state के आधार पर dynamically generate किया जा सकता है
Bash और Zsh दोनों को support करना
_complete_foo_bashऔर_complete_foo_zshfunctions के जरिए हर shell के लिए अलग implementation की जाती हैif [ -n "${ZSH_VERSION:-}" ]; then ... elif [ -n "${BASH_VERSION:-}" ]; then ... fiसे shell का फर्क किया जाता है- user script को
.bashrcया.zshrcमें register करके apply कर सकता है
Zsh में description दिखाना
- candidate string के लिए
नाम: विवरणफ़ॉर्मेट का उपयोग किया जाता है - Zsh:
compadd -d raw -- $trimmedसे name और description को parallel arrays के रूप में pass किया जाता है - Bash: description वाला भाग हटाकर सिर्फ candidate को
COMPREPLYमें दिया जाता है (डिफ़ॉल्ट रूप से description support नहीं है)
Bash में description लागू करना
- कई candidates होने पर description शामिल string को वैसे ही expose किया जाता है
- केवल single candidate होने पर description हटाया जाता है
- Bash के इस व्यवहार का उपयोग किया जाता है कि auto-completion सिर्फ common prefix insert करता है, ताकि description actual input में शामिल न हो
single candidate पर भी description दिखाना
- complete हुए शब्द पर
<TAB>दबाने पर भी description दिखाने के लिए dummy candidate जोड़कर ambiguity बनाई जाती है - Zsh: दोनों parallel arrays (
raw,trimmed) में dummy candidate जोड़ा जाता है - Bash: single candidate होने पर
trimmedमें सिर्फ name जोड़ा जाता है
अंतिम परिणाम
- multiple candidates होने पर name + description दोनों दिखते हैं
- single candidate होने पर भी
<TAB>से description देखा जा सकता है - Bash और Zsh दोनों में एक जैसा अनुभव मिलता है
- लागू होने का उदाहरण:
$ foo <TAB> apple: a common fruit banana: starchy and high in potassium apricot: sour fruit... cherry: small and sweet...
1 टिप्पणियां
Hacker News राय
fish_update_completionsचलाना होता है~/.cache/fish/generated_completions/में बनाता हैcurlका-L→ 'Follow redirects',-O→ 'Write output to file named as remote file'car TABकाblkdiscardमें expand हो जाना, यानी non-prefix auto-completion, की वजह से cargo के PATH में न होने पर भी गलत व्यवहार होता है; यह बेहतर हो तो अच्छा होगा--helpमिलता है, उनके लिए सोच रहा हूँ कि क्या fish में zsh के_gnu_genericया bash केcomplete -F _longoptजैसी कोई सुविधा हैzypper search fish-completionचलाने पर 200 से ज्यादा packages दिखे, तो कुछ संदिग्ध-सा लगाcomplete-filenameजैसे functions होते हैं, जो context को नज़रअंदाज़ करके सिर्फ filename complete करते हैंlsसे complete करके फिर command बदलकर workaround करना पड़ता हैcomplete -rचलाने के बाद अगर सब कुछ मनचाहे तरीके से काम करता है, तो लगता है कि समस्या bash-completion script में है$fpathमें install किया जाए, तो वह cache हो जाती है और startup speed तेज हो जाती है_gnu_genericके जरिए--helpआधारित सरल completion संभव है--generateoption, और PHP Symfony के runtime completion generation जैसे उदाहरण हैं--completionstandard हो, जिसे common parser libraries अपने-आप implement करेंcomplete_kill_1array में signal names डालने परkillcommand के पहले argument की completion मिलती हैset-java-homefunction में~/apps/java/*सूची को version के रूप में complete कराने के लिए_describeका उपयोग