Git Product home page Git Product logo

zsh-bash-completions-fallback's Introduction

zsh-bash-completions-fallback

This plugin is intended to use the bash completions when a zsh completion is not available.

While this could be supported natively via bashcompinit, this doesn't actually work most of the times, as completion scripts may use syntax not supported by zsh, and so it's just better to implement this querying the bash itself, using a bash script called at completion time (based on Brian Baffa implementation and including various fixes to support commands and completion parameters).

Make sure you load this after other plugins to prevent their completions to be replaced by the (simpler) bash ones.

Most of all bash completions can now work as they precisely do in bash, as per the compopt simulation that is added here. It may be used to control the output or avoid adding spaces or limit the results.

The plugin by default works by lazy-loading the completions the first time you hit TAB to complete a command, however this can be controlled using the $ZSH_BASH_COMPLETIONS_FALLBACK_LAZYLOAD_DISABLE parameter, to load them all on startup.

If a new bash completion has been installed in the system, you can just restart zsh or call _bash_completions_load, if instead you want this to be handled automatically, you can use $ZSH_BASH_COMPLETIONS_FALLBACK_LAZYLOAD_AUTO_UPDATE to update all the the available completions at every TAB-completion. This is disabled by default, to avoid IO operations at each completion, but it is still very fast in most of the platforms.

Once loaded you can see all the completions available via bash (through this script) using:

_bash_completions_fallback_list_handled_completions

Requirements

Install

Using Oh-my-zsh:

  1. Clone this repository in oh-my-zsh's plugins directory:

     git clone https://github.com/3v1n0/zsh-bash-completions-fallback ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-bash-completions-fallback
    
  2. Activate the plugin in ~/.zshrc (make sure it's set as the last one not to replace completions provided by other plugins):

     plugins=( [plugins...] zsh-bash-completions-fallback)
    
  3. Source ~/.zshrc (or restart zsh) to take changes into account

     source ~/.zshrc
    

Using Zinit:

  • If you're using normal loading mode:

      # Replace `light` with `load` if you want some more debugging
      zinit ice depth=1 # optional, but avoids downloading the full history
      zinit light 3v1n0/zsh-bash-completions-fallback
    
  • If you're using turbo mode, you can avoid using the internal lazy mode:

      zinit wait lucid nocd depth=1 \
        atinit='ZSH_BASH_COMPLETIONS_FALLBACK_LAZYLOAD_DISABLE=true' \
          for 3v1n0/zsh-bash-completions-fallback
    
  • Add those to your ~/.zshrc to keep the changes persistent

Using other plugins manager:

    # Depending on the tool the syntax may vary but it's generally just
    $your_plugin_manager 3v1n0/zsh-bash-completions-fallback

Manual installation:

  1. Clone this repository in a folder (like ~/.zsh-bash-completions-fallback):

     git clone https://github.com/3v1n0/zsh-bash-completions-fallback $HOME/.zsh-bash-completions-fallback
    
  2. Add to your ~/.zshrc:

     source $HOME/.zsh-bash-completions-fallback/zsh-bash-completions-fallback.plugin.zsh
    
  3. Source ~/.zshrc (or restart zsh) to start using the plugin

     # This plugin requires compinit, so make sure that your ~/.zshrc or
     # your package manager loads it before, otherwise this is needed
     #autoload -U compinit && compinit
     source ~/.zshrc
    
  4. Of course in case you want to test it temporary you just have to source the plugin file (zsh-bash-completions-fallback.plugin.zsh)

Configuration

This script defines the following global variables. You may override their default values only after having loaded this script into your ZSH session.

  • ZSH_BASH_COMPLETIONS_FALLBACK_PATH overrides the default bash completions path that is set to /usr/share/bash-completion by default.

  • ZSH_BASH_COMPLETIONS_FALLBACK_REPLACE_ALL set (to any value) to allow to replace all the zsh completions, even if we already have one for the given command.

  • ZSH_BASH_COMPLETIONS_FALLBACK_WHITELIST an array of commands for which we want to enable the bash completions, this allow to filter the commands to use a bash completion for. Set it to a value such as (gdbus zramctl) to enable it only for the gdbus and zramctl commands. This also can be used with $ZSH_BASH_COMPLETIONS_FALLBACK_REPLACE_ALL to only use a subset of completions from bash only.

  • ZSH_BASH_COMPLETIONS_FALLBACK_BLACKLIST an array of commands for which we want to disable the bash completions.

  • ZSH_BASH_COMPLETIONS_FALLBACK_REPLACE_LIST an array of commands for which we want to give priority to the bash completions over the zsh ones. So, in case a zsh completion for such commands is available, we just ignore it and replace it with the bash ones. This has no effect if $ZSH_BASH_COMPLETIONS_FALLBACK_REPLACE_ALL is set.

  • ZSH_BASH_COMPLETIONS_FALLBACK_PRELOAD_ALL set this variable (to any value) to always preload completions even for non-available commands. We don't do it by default and if any command is added at later times, the user can manually call _bash_completions_load (or source this file again)

  • ZSH_BASH_COMPLETIONS_FALLBACK_LAZYLOAD_DISABLE set this variable (to any value) in order to disable the lazy loading of the completions at the fist time the tab-completion is triggered. By setting this the completions are loaded instead at startup.

  • ZSH_BASH_COMPLETIONS_FALLBACK_LOAD_NATIVE_COMPLETIONS set this variable to a value that is different from true not to ask the bash for all its suported completions, but only relying in the provided completion files.

  • ZSH_BASH_COMPLETIONS_FALLBACK_LAZYLOAD_AUTO_UPDATE set this variable (to any value) to automatically check for new completions and to install them at every tab-completion if the threshold from the last update set in $ZSH_BASH_COMPLETIONS_FALLBACK_AUTO_UPDATE_THRESHOLD has passed. This is not affected by the value of $ZSH_BASH_COMPLETIONS_FALLBACK_LAZYLOAD_DISABLE and it will work both in case lazy loading is enabled or not.

  • ZSH_BASH_COMPLETIONS_FALLBACK_AUTO_UPDATE_THRESHOLD: Sets a threshold (in seconds) to check if the completions have been changed in case the lazy load update is enabled. This is set by default at 300 seconds.

zsh-bash-completions-fallback's People

Contributors

3v1n0 avatar freed-wu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

zsh-bash-completions-fallback's Issues

Support of multiple paths under ZSH_BASH_COMPLETIONS_FALLBACK_PATH

Given typical macOS installation with homebrew, the user ends up with bash completions under two distinct paths:

% ll /usr/local/etc/bash_completion.d
total 0
lrwxr-xr-x 1 igorurazov admin 75 Feb 10 12:50 ag.bashcomp.sh -> ../../Cellar/the_silver_searcher/2.2.0/etc/bash_completion.d/ag.bashcomp.sh
lrwxr-xr-x 1 igorurazov admin 67 May 25 11:29 aws_bash_completer -> ../../Cellar/awscli/2.0.16/etc/bash_completion.d/aws_bash_completer
lrwxr-xr-x 1 igorurazov admin 36 Feb 10 12:38 brew -> ../../Homebrew/completions/bash/brew
lrwxr-xr-x 1 igorurazov admin 85 Feb 10 12:39 brew-services -> ../../Homebrew/Library/Taps/homebrew/homebrew-services/completions/bash/brew-services
lrwxr-xr-x 1 igorurazov admin 51 May 20 12:24 fd.bash -> ../../Cellar/fd/8.1.0/etc/bash_completion.d/fd.bash
lrwxr-xr-x 1 igorurazov admin 59 May 21 14:42 gapplication -> ../../Cellar/glib/2.64.3/etc/bash_completion.d/gapplication
lrwxr-xr-x 1 igorurazov admin 52 May 21 14:42 gdbus -> ../../Cellar/glib/2.64.3/etc/bash_completion.d/gdbus
lrwxr-xr-x 1 igorurazov admin 50 May 21 14:42 gio -> ../../Cellar/glib/2.64.3/etc/bash_completion.d/gio
lrwxr-xr-x 1 igorurazov admin 67 May 20 12:25 git-completion.bash -> ../../Cellar/git/2.26.2_1/etc/bash_completion.d/git-completion.bash
lrwxr-xr-x 1 igorurazov admin 61 May 20 12:25 git-prompt.sh -> ../../Cellar/git/2.26.2_1/etc/bash_completion.d/git-prompt.sh
lrwxr-xr-x 1 igorurazov admin 56 May 21 14:42 gresource -> ../../Cellar/glib/2.64.3/etc/bash_completion.d/gresource
lrwxr-xr-x 1 igorurazov admin 56 May 21 14:42 gsettings -> ../../Cellar/glib/2.64.3/etc/bash_completion.d/gsettings
lrwxr-xr-x 1 igorurazov admin 48 May 20 12:23 mas -> ../../Cellar/mas/1.6.4/etc/bash_completion.d/mas
lrwxr-xr-x 1 igorurazov admin 50 May 21 14:42 npm -> ../../Cellar/node/14.3.0/etc/bash_completion.d/npm*
lrwxr-xr-x 1 igorurazov admin 64 Apr 13 11:28 tig-completion.bash -> ../../Cellar/tig/2.5.1/etc/bash_completion.d/tig-completion.bash*
lrwxr-xr-x 1 igorurazov admin 49 May  4 13:28 tmux -> ../../Cellar/tmux/3.1b/etc/bash_completion.d/tmux
% ll /usr/local/share/bash-completion/completions/
total 0
lrwxr-xr-x 1 igorurazov admin 74 May 21 14:42 gapplication -> ../../../Cellar/glib/2.64.3/share/bash-completion/completions/gapplication
lrwxr-xr-x 1 igorurazov admin 67 May 21 14:42 gdbus -> ../../../Cellar/glib/2.64.3/share/bash-completion/completions/gdbus
lrwxr-xr-x 1 igorurazov admin 65 May 21 14:42 gio -> ../../../Cellar/glib/2.64.3/share/bash-completion/completions/gio
lrwxr-xr-x 1 igorurazov admin 71 May 21 14:42 gresource -> ../../../Cellar/glib/2.64.3/share/bash-completion/completions/gresource
lrwxr-xr-x 1 igorurazov admin 71 May 21 14:42 gsettings -> ../../../Cellar/glib/2.64.3/share/bash-completion/completions/gsettings
lrwxr-xr-x 1 igorurazov admin 64 Feb 10 12:48 mtr -> ../../../Cellar/mtr/0.93_1/share/bash-completion/completions/mtr

In addition to this, bash AFAIK can load completions from /etc/bash_completions.d/ and even ~/.local/{etc/bash_completion.d|share/bash-completion/completions too.

Ideally I think this plugin should support all of those paths and let user to specify additional paths the completions can be found.

Doesn't work if /etc/bash_completion is missing

If you want to check if one of bash_completion exists the correct operator it this statement is &&:

if ! [ -f /etc/bash_completion ] &&
   ! [ -f "$_bash_completions/bash_completion" ]; then
   return 1;
fi

But I really don't understand why it needed at all. Just check that bash-completion/completions directory exists. It should be enough.

No complete menu when lazy load enabled

initial double Tab is very annoying to me.

Weird this should not happen, the first tab should call the normal completion function no?
It may be a bit slower, but nothing big.

Originally posted by @3v1n0 in #3 (comment)

Yeah, when I executed your plugin in xtrace mode I saw the problem:

image

After commenting the line

unset _bash_completion_previous_binding
it starts work as expected.

bash completion for lftp cannot be loaded by zsh

For other program, such as lftpget (provided by package lftp together with program lftp) can work.

% lftp -<TAB>
# nothing happens
% bash
$ lftp -<TAB>
-c         -d         -e         -f         --help     --norc     -p         -s         -u         --version

[bug] source bash completion prior to zsh completion

python-pip has its bash-completion:

❯ pacman -Ql python-pip|rg -N /usr/share/bash-completion/completions/pip
python-pip /usr/share/bash-completion/completions/pip

And zsh have a completion for pip, too:

❯ head -n1 /usr/share/zsh/functions/Completion/Unix/_pip
#compdef -P pip[0-9.]#

Actual

However, if user use this plugin, this plugin will source bash completion not zsh completion.

Expected

Source zsh completion, only when zsh completion is not found and bash completion exists, source bash completion.

Completion

If user change the first line of zsh completion:

❯ head -n1 /usr/share/zsh/functions/Completion/Unix/_pip
#compdef pip

This bug can disappear. I think this plugin don't know compdef -P is zsh completion?

Thanks.

bash-completions-getter.sh: line 178: _completion_loader: command not found

I'm trying to make this work on NixOS and I'm getting the following error:

/nix/store/0ibqj2ysg8602by5azn2rgm64w6gmsnd-source/bash-completions-getter.sh: line 178: _completion_loader: command not found

It seems that when bash is run in non-interactive mode, this function is not defined on NixOS. I can resolve the issue with the following change, but I'm not sure how generic it is and whether it would work on other distributions.

diff --git a/zsh-bash-completions-fallback.plugin.zsh b/zsh-bash-completions-fallback.plugin.zsh
index 61402cb..4609ff9 100644
--- a/zsh-bash-completions-fallback.plugin.zsh
+++ b/zsh-bash-completions-fallback.plugin.zsh
@@ -12,7 +12,7 @@ function _bash_completions_fallback_completer {
         ZSH_WORDBREAKS="$WORDCHARS" \
         ZSH_WORDS="${words[@]}" \
         ZSH_CURRENT=$((CURRENT-1)) \
-        bash -c \
+        bash -i -c \
         "source ${_bash_completions_getter_path}; get_completions")}");
 
     local -a -U bopts=("${(ps: :)${(@f)out:0:1}}");
@@ -83,7 +83,7 @@ function _bash_completions_fetch_supported_commands {
 
     if [ -n "${ZSH_BASH_COMPLETIONS_FALLBACK_LOAD_NATIVE_COMPLETIONS-:true}" ]; then
         local out=("${(u@f)$( \
-            bash -c \
+            bash -i -c \
             "source ${_bash_completions_getter_path}; get_defined_completions")}");
         _bash_completions_commands+=($out)
     fi

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.