Skip to content

tmlapp/complete-alias

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

complete-alias

automagical shell alias completion;

  • works with all common aliases, even self-aliases;

  • one completion function, for all aliases;

  • alias completion as easy as type-and-tab;

install

  1. install dependency bash-completion;

    • linux:

      install bash-completion using system package manager:

      dnf install bash-completion     ##  fedora
      apt install bash-completion     ##  debian
      

      for other linux distros, see faq;

    • macos (experimental):

      install bash-completion homebrew formulae version 2:

      brew install bash-completion@2
      
    • windows (experimental):

      see faq;

  2. source complete_alias in ~/.bash_completion:

    . {complete_alias}
    

    where {complete_alias} is the path of complete_alias;

usage

  1. edit aliases to complete in complete_alias:

    for example, to complete aliases foo, bar and baz:

    complete -F _complete_alias foo
    complete -F _complete_alias bar
    complete -F _complete_alias baz
    
  2. to complete an alias, type it and press <tab>;

example

to complete alias sctl aliased to systemctl:

$ alias sctl='systemctl'
$ cp complete_alias ~/.complete_alias
$ echo ". ~/.complete_alias" >> ~/.bash_completion
$ echo "complete -F _complete_alias sctl" >> ~/.complete_alias
$ sctl <tab>
add-requires
add-wants
cancel
cat
condreload
...

config

to config complete-alias, set these envars before sourcing the main script:

  • COMPAL_AUTO_UNMASK

    this is a bool; default is 0; when set to 1, enables auto unmask; when set to 0, uses manual unmask;

    auto unmask automatically manages non-alias command completions, but incurs a small overhead on source; manual unmask is the traditional way of setting non-alias command completions, which is static and faster but requires user intervention if the preset is not satisfying;

compat

  • support for gnu bash(>=4.4) on linux is aimed;

  • support for older versions of bash is uncertain;

  • support for other shells is possible but unlikely;

  • support for other operating systems is experimental;

faq

  • how to install it on windows?

    support for windows is limited to msys2 and git for windows:

    • msys2:

      msys2 features pacman so you can install like linux:

      pacman -S bash-completion
      cat complete_alias >> ~/.bash_completion
      
    • git for windows:

      tldr: steal bash_completion and source it before complete_alias;

      git for windows provides git bash, which is a minimal environment based on msys2; for what matters here, git bash does not have package manager; so the above install procedure does not apply;

      the idea is, you must somehow get bash-completion and load it before complete-alias in a shell environment; for example, you can download bash-completion package from a msys2 mirror; however, the easiest solution i found to make things work is to simply download the main script bash_completion from its git repo; this does not give you its entirety, but is good enough to work;

      now you have 2 files: bash_completion and complete_alias; you need to source them in this order in ~/.bashrc:

      . ~/.bash_completion.sh
      . ~/.complete_alias.sh
      

      attention: here we renamed the files; we cannot use ~/.bash_completion because this is the very filename sourced by the very script; using this filename will cause an infinite loop;

      now install is complete; add your own aliases in ~/.complete_alias.sh;

  • how to install bash-completion on other linux distros?

    these commands are sourced from wikis and users:

    pacman -S bash-completion               ##  arch
    yum install bash-completion             ##  centos
    emerge --ask app-shells/bash-completion ##  gentoo
    zypper install bash-completion          ##  suse
    apt install bash-completion             ##  ubuntu
    

    these commands are not tested; open a ticket if you find them not working;

  • how to complete all my aliases?

    run this one-liner after all aliases have been defined:

    complete -F _complete_alias "${!BASH_ALIASES[@]}"
    

    it works like this:

    complete -F _complete_alias foo
    complete -F _complete_alias bar
    complete -F _complete_alias baz
    ...
    

    note that if you simply put this one-liner in complete_alias code, things may not work, depending on the order of file sourcing, which in turn varies across user configurations; the correct way to use this one-liner is to put it in the same file where aliases are defined; for example, if your aliases are defined in ~/.bashrc, then that file should look like this:

    alias foo='...'
    alias bar='...'
    alias baz='...'
    ...
    complete -F _complete_alias "${!BASH_ALIASES[@]}"
    
  • sudo completion is not working correctly?

    there is a known case with sudo that can go wrong; for example:

    $ unalias sudo
    $ complete -r sudo
    $ alias ls='ping'
    $ complete -F _complete_alias ls
    $ sudo ls <tab>
    {ip}
    {ip}
    {ip}
    ...
    

    here we are expecting a list of files, but the completion reply is a list of ip addrs; the reason is, the completion function for sudo is almost always _sudo, which is provided by bash-completion; this function strips sudo then meta-completes the remaining command line; in our case, this is ls to be completed by _complete_alias; but there is no way for _complete_alias to see the original command line, and so it cannot tell ls from sudo ls; as a result, ls and sudo ls are always completed the same even when they should not; unfortunately, there is nothing _complete_alias can do here;

    the easiest solution is to make sudo a self-alias:

    $ alias sudo='sudo'
    $ complete -F _complete_alias sudo
    $ alias ls='ping'
    $ complete -F _complete_alias ls
    $ sudo ls <tab>
    {file}
    {file}
    {file}
    ...
    

    this gives _complete_alias a chance to see the original command line, then decide what is the right thing to do; you may add a trailing space to sudo alias body if you like it that way, and things still work correctly (listing ip addrs is correct in this case):

    $ alias sudo='sudo '
    $ complete -F _complete_alias sudo
    $ alias ls='ping'
    $ complete -F _complete_alias ls
    $ sudo ls <tab>
    {ip}
    {ip}
    {ip}
    ...
    

license

The source code is licensed under the GNU General Public License v3.0.

Copyright (C) 2016-2021 Cyker Way

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Packages

No packages published

Languages

  • Shell 100.0%