qrush / sub

a delicious way to organize programs
http://37signals.com/svn/posts/3264-automating-with-convention-introducing-sub
MIT License
1.74k stars 148 forks source link

Add argument chain to --complete to make multiple level compeltion possible #12

Closed Nattle closed 1 year ago

Nattle commented 11 years ago

I want to be able to tab complete the list of servers in this example: sub setup setupServers (foo, bar baz)

I dont see any easy way to do this, but I cold be wrong. If the list of completed arguments was passed to --complete then I would be able to parse down them and return completions to an arbitrary depth.

:)

andreaja commented 11 years ago

The following patch solves the issue:

diff --git a/completions/sub.bash b/completions/sub.bash
index 40eac81..37c210c 100644
--- a/completions/sub.bash
+++ b/completions/sub.bash
@@ -6,7 +6,7 @@ _sub() {
     COMPREPLY=( $(compgen -W "$(sub commands)" -- "$word") )
   else
     local command="${COMP_WORDS[1]}"
-    local completions="$(sub completions "$command")"
+    local completions="$(sub completions "$command" ${COMP_WORDS[@]:2})"
     COMPREPLY=( $(compgen -W "$completions" -- "$word") )
   fi
 }
Nattle commented 11 years ago

This is awesome and very powerful. Thanks so much. I would have done it myself by I got lost after the 2nd or 3rd line of bash scripting :)

Is there any way the script could more gracefully handle a tree like structure? Like if sub-server supplied (foo, bar, baz) and tab completing "sub server bar" automatically looked at sub-server-bar first for completions. That certianly requires some careful thought the effects of that change, but it would make building a robust command structure much easier.

bradical commented 11 years ago

This might be similar but I'm looking to provide multiple levels of auto-completion for a server name for the first argument and a user for the second:

sub ssh host user

Currently trying to accomplish with:

if [ "$1" = "--complete" ]; then
  exec echo "server1 server2 server3"
fi

if [ "$2" = "--complete" ]; then
  exec echo "ec2-user root"
fi

Is this the same idea?

matschaffer commented 10 years ago

This seems to do the trick for zsh. Though I'm still getting stumped on how to write a script that handles both partial completions (e.g., first letter) and multi level completions.

Seems like we'll need something at the bash/zsh level to know if it's a full word coming in but I haven't figured it out yet.

diff --git a/completions/nf.zsh b/completions/nf.zsh
index 01aef31..0b16dbf 100644
--- a/completions/nf.zsh
+++ b/completions/nf.zsh
@@ -12,7 +12,7 @@ _nf() {
   if [ "${#words}" -eq 2 ]; then
     completions="$(nf commands)"
   else
-    completions="$(nf completions "${word}")"
+    completions="$(nf completions "${word}" ${words[3,-1]})"
   fi

   reply=("${(ps:\n:)completions}")