Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash script with user defined functions in autocomplete

Tags:

linux

bash

shell

I need my bash script to get function names from user. The script should assist the users by auto completing the functions defined inside the same bash script file.

Eg:

myBash.sh

#!/usr/bash
function func1()
{
    echo "In func1 func"
}

function func2()
{
    echo "In func2 func"
}

function myFunc1()
{
    echo "In myFunc1 func"
}

while [ 1 ]
do
    echo -n "cmd>"
    read $userCmd
    $userCmd
done

]$ ./mybash.sh
cmd> my<tab><tab>
myFunc1

cmd> func<tab><tab>
func1 func2

This is my required output. How to accompany this?

like image 483
Ashwin Avatar asked Mar 07 '26 18:03

Ashwin


1 Answers

This workaround should do the trick.

    #!/bin/bash

    func1() {
        echo "You are in func1: $@"
    }
    
    func2() {
        echo "You are in func2: $@"
    }

    myFunc1() {
        echo "You are in myFunc1: $@"
    }
    
    # usage: autocomplete "word1 word2 ..."
    autocomplete() {
         # try to autocomplete the last word, and 
         # keep a record of the rest of the input
         OTHER_WORDS="${READLINE_LINE% *} " 
         if [[ ${#OTHER_WORDS} -ge ${#READLINE_LINE} ]]; then 
             # if there is only 1 word...
             OTHER_WORDS="" 
         fi
         
         # the -W flag tells compgen to read autocomplete
         # from the 1st argument provided, then we
         # evaluate the last word of the current line
         # through compgen
         AUTOCOMPLETE=($(compgen -W $1 "${READLINE_LINE##* }"))
         if [[ ${#AUTOCOMPLETE[@]} == 1 ]]; then 
             # if there is only 1 match, substitute it
             READLINE_LINE="$OTHER_WORDS${AUTOCOMPLETE[0]} "
             # position the cursor at the end of the word
             READLINE_POINT=${#READLINE_LINE}
         else
             #...otherwise print the possibilities
             echo -e "cmd> $READLINE_LINE\n${AUTOCOMPLETE[@]}" 
         fi
    }
    
    # list the values to be autocompleted
    MYFUNC="func1 func2 myFunc1" 
    # enable line editing
    set -o emacs
    # call autocomplete when TAB is pressed
    bind -x '"\t":"autocomplete \$MYFUNC"';   
    while read -ep "cmd> "; do
        # history is just a nice bonus
        history -s $REPLY
        eval ${REPLY}
    done

To try it :

    ]$ ./mybash.sh
    cmd> my<tab>
    cmd> myFunc1
    
    cmd> func<tab>
    func1 func2
    
    cmd> func1 hello, world!
    You are in func2: hello, world!

    cmd> func1 my<tab>
    cmd> func1 myFunc1

As mentioned in my previous comment, have a look at this question. It uses a nice trick to auto detect all inner functions in order to use it as auto-complete values.

like image 170
Aserre Avatar answered Mar 09 '26 12:03

Aserre



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!