Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Bash completion of aliased commands

Hybrid View

  1. #1
    Join Date
    Oct 2006
    Beans
    513

    Bash completion for aliased commands

    Problem: When you alias some command, custom completion no longer works.
    Eg.
    Code:
    alias agi='sudo apt-get install'
    agi fire<tab> # does not work
    This pretty much removes the advantage of having the alias in the first place. Especially when you want to install libgnome-settings-daemon-dev

    Solution:
    Most completers are defined as a bash function. My solution wraps the original completer. This obviously only works for function completers. (ie. complete -F).

    This should in principle work on any distribution with a recent bash and the completion pacackge. It's tested on feisty.

    make-completion-wrapper.sh :
    Code:
    # Author.: Ole J
    # Date...: 23.03.2008
    # License: Whatever
    
    # Wraps a completion function
    # make-completion-wrapper <actual completion function> <name of new func.>
    #                         <command name> <list supplied arguments>
    # eg.
    # 	alias agi='apt-get install'
    # 	make-completion-wrapper _apt_get _apt_get_install apt-get install
    # defines a function called _apt_get_install (that's $2) that will complete
    # the 'agi' alias. (complete -F _apt_get_install agi)
    #
    function make-completion-wrapper () {
    	local function_name="$2"
    	local arg_count=$(($#-3))
    	local comp_function_name="$1"
    	shift 2
    	local function="
    function $function_name {
    	((COMP_CWORD+=$arg_count))
    	COMP_WORDS=( "$@" \${COMP_WORDS[@]:1} )
    	"$comp_function_name"
    	return 0
    }"
    	eval "$function"
    	echo $function_name
    	echo "$function"
    }
    This will wrap a completer, adjusting the aliased arguments. Save it in a file called make-completion-wrapper.sh or add it to your ~/.bashrc file

    To find out what the completer function is called:
    Open a terminal and type:
    Code:
    complete -p <command name>
    Example:
    Code:
    $ complete -p apt-get
    complete -o filenames -F _apt_get apt-get
    $ complete -p oocalc 
    complete -o filenames -d -X '.[^./]*' -F _ooexp_ oocalc
    The blue output is the name of the completer function, and the red is extra information. If -F is missing you can not use this method to wrap the completer.

    As an example of usage lets add completion to alias agi='apt-get install' and alias acsh='apt-cache show'
    Add this to your ~/.bashrc :
    Code:
    # ...
    . /home/me/path-to-make-completion-wrapper.sh # or the content of make-completion-wrapper.sh
    # aliases and completion code:
    alias agi='sudo apt-get install'
    make-completion-wrapper _apt_get _agi apt-get install
    complete -o filenames -F _agi agi
    alias acsh='apt-cache show'
    make-completion-wrapper _apt_cache _acsh apt-cache show
    complete -o filenames -F _acsh acsh
    - Note that we've duplicted the red output from complete -p.
    - _agi and _acsh are arbitrary names, but to avoid name crashes, you should pick something distinct.

    If you just want to test if it works, paste the above code (substitute path to make-completion-wrapper.sh first) in a terminal and try to type
    Code:
    agi fire<tab><tab>
    Just remove the changes in your ~/.bashrc if you want to remove the completion or if something went wrong.

    Related information
    http://ubuntuforums.org/showthread.p...ash+completion
    http://www.debian-administration.org/articles/316
    http://www.debian-administration.org/articles/317

    PS: It shoud be possible to completely automate this process by parsing the output from complete
    Last edited by olejorgen; June 3rd, 2009 at 10:22 PM.
    Donation links
    Free hardware
    Petition for free drivers
    If every forum member donated $1 to FSF, they would almost double their income

  2. #2
    Join Date
    Dec 2008
    Location
    USA
    Beans
    39
    Distro
    Ubuntu 8.04 Hardy Heron

    Re: Bash completion of aliased commands

    Thanks very much. This is awesome.

  3. #3
    Join Date
    Nov 2008
    Location
    Natick, Massachusetts
    Beans
    1
    Distro
    Ubuntu 8.10 Intrepid Ibex

    Re: Bash completion of aliased commands

    When I followed these steps for "gv" aliasing "gvim" it did not work:

    Code:
    # Autocomplete made to work for alias gv="gvim"
    # $ complete -p gvim
    complete -o filenames -F _filedir_xspec gvim
     . /home/ben/customhome/make-completion-wrapper.sh
    alias gv='gvim'
    make-completion-wrapper _filedir_xspec _gv gvim
    complete -o filenames -F _gv gvim
    source ~/.bashrc

    produces

    Code:
    _gv
    
    function _gv {
    	((COMP_CWORD+=0))
    	COMP_WORDS=( gvim ${COMP_WORDS[@]:1} )
    	_filedir_xspec
    	return 0
    }
    And the completion still doesn't work. Funny, I don't remember having to do anything for autocompletion to work for aliased functions in ubuntu 8.

    Mayhaps i am working too hard to try to save two letters...

  4. #4
    Join Date
    Aug 2009
    Beans
    2

    Re: Bash completion of aliased commands

    Quote Originally Posted by benjamin-agaric View Post
    When I followed these steps for "gv" aliasing "gvim" it did not work:

    *snip*

    And the completion still doesn't work. Funny, I don't remember having to do anything for autocompletion to work for aliased functions in ubuntu 8.

    Mayhaps i am working too hard to try to save two letters...
    I doubt you're still looking, three years later, but for searchers:
    In the last line, you were telling complete to attach your new _gv function to the word 'gvim' - that should have been 'gv'.

    However, you don't actually need this wrapper script for your case.
    Because you are aliasing a single word for another single word, you can simply apply the original completion function (_filedir_xspec) directly:
    Code:
    complete -o filenames -F _filedir_xspec gv
    This wrapper is for cases where you are adding extra words to the alias, so the original function won't work by itself - you type "agi", for example, but the completion function expects to see both "apt-get" and also "install".

    Quote Originally Posted by justmailnaveen View Post
    Does it still works. I mean on ubuntu 11.04
    Yes, I'm using it happily on 11.10.
    Only change I made was to remove the two 'echo' lines at the bottom - they are just for debugging.

    Thanks olejorgen, much appreciated.

  5. #5
    Join Date
    May 2012
    Beans
    1

    Re: Bash completion of aliased commands

    cool wrapper..
    i've started writing it into my bashrc in order to use all my git aliases, when i realized i have a lot of code reuse, so i wrote this function:

    # usage: gitalias <alias> <original command>
    function gitalias () {
    alias $1="$2"
    make-completion-wrapper _git _$1i $2
    complete -o bashdefault -o default -o nospace -F _$1i $1
    }

    and now instead of writing 3 lines per alias i'm simply replacing
    alias gc='git checkout
    with:
    gitalias gc 'git checkout'

    if you want to use this for anything other than git, just replace the '_git' in the middle with your completer function (or with $3...)

    oh, and you might wanna change its name as well...

  6. #6
    Join Date
    Oct 2012
    Beans
    1

    Re: Bash completion of aliased commands

    update:
    Seems like this might have been the effect of . ~/.bashrc instead of reloading the terminal, leaving some old functions intact.

    It might also be that it works when you use a function instead of an alias.


    I've tried to use this wrapper (slightly renamed by removing make to remove confusion) with:

    alias makeb='make "$@" | grep -i "built"'
    completion-wrapper _make _makeb make
    complete -o bashdefault -o default -o nospace -F _makeb makeb


    Now when I type:

    makeb motor

    without autocompletion, it makes the motor and outputs the lines where "built" appears. With autocompletion, I can autocomplete on command line correctly, but when I run the command I get:

    grep: motor: No such file or directory

    This leads me to believe the command it executes is:

    make | grep -i "built" motor

    Instead of:

    make motor | grep -i "built"

    Now, I think there is a solution in passing on the parameters a certain way, but I don't see how that can be done right now. Perhaps someone else will find a way. In the meanwhile, I'll keep experimenting.
    Last edited by verqix; October 20th, 2012 at 04:23 PM.

  7. #7
    Join Date
    Aug 2007
    Location
    Bangkok, TH
    Beans
    410

    Re: Bash completion of aliased commands

    Thank you! Works great.

  8. #8
    Join Date
    Nov 2009
    Beans
    1

    Re: Bash completion for aliased commands

    Thanks for your post.

    Quote Originally Posted by olejorgen View Post
    PS: It shoud be possible to completely automate this process by parsing the output from complete
    I followed through on your suggestion and wrote a snippet that will run through all your aliases and add a wrapper where possible:

    http://stackoverflow.com/questions/3...793178#1793178

  9. #9
    Join Date
    Jul 2011
    Beans
    1

    Re: Bash completion for aliased commands

    Does it still works. I mean on ubuntu 11.04

  10. #10
    Join Date
    Jul 2012
    Beans
    7

    Re: Bash completion of aliased commands

    HELP! i',m sorry for reviving this old post, but this isn't (entirely) working for me!

    Here is my output of "complete -p apt-get":
    bash: complete: apt-get: no hay completado de especificación
    (in english it would be "bash:complete: apt-get: no completion specification")

    BUT when i do "apt-get <tab> <tab>" i still get the autocompletion feature. IN FACT, when i "complete -p apt-get" after that, i get "complete -F _apt_get apt-get"

    Then, my alias do autocomplete, but if i close that terminal, it does not do that anymore..

    any clues?

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •