Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tab Completion for bash #203

Open
generalredneck opened this issue Oct 22, 2018 · 24 comments
Open

Tab Completion for bash #203

generalredneck opened this issue Oct 22, 2018 · 24 comments

Comments

@generalredneck
Copy link
Contributor

Feature Request

As a lando user, I would like to be able to press the <TAB> key and have a list of options I can select from so that typing out commands is faster.

This would probably take the form of a simple bash completions script. I don't have the gist of it but something along the lines of the following script in it's simplest form put into /etc/bash_completion.d/

#/usr/bin/env bash
_dothis_completions()
{
  COMPREPLY=($(compgen -W "$(lando)" "${COMP_WORDS[1]}"))
}

complete -F _dothis_completions lando
@dustinleblanc
Copy link
Collaborator

Cool idea @generalredneck! This is definitely not high priority, but might be a nice to have. I am going to put this in carbonite for now, but if you want to do some research and we get some general ideas going around from @pirog and @serundeputy, maybe it can be included in the future

@pirog
Copy link
Member

pirog commented Oct 23, 2018

I support this but i also have no ideas on how to accomplish this and no desire to do any work to make it happen ;) aka someone else is going to have to take the lead here!

@generalredneck
Copy link
Contributor Author

generalredneck commented Oct 23, 2018

I'll see what I can do. I don't know how to alter the deb package to do the install... be a learning speriance.

@pirog
Copy link
Member

pirog commented Oct 23, 2018

@generalredneck im guessing these are going to be the relevant files you will want to look at

@tylers-username
Copy link

tylers-username commented Nov 15, 2018

I played around with https://github.com/f/omelette as a plugin for proof of concept. It is lightweight, has zero dependencies, is cross-platform compatible and works with both zsh and bash. If anything, it may serve as inspiration for how to proceed if the Lando team builds the feature out from a scratch.

Edit: Looks like yargs, which is already included in Lando, has this built-in for bash.

@jcheek
Copy link

jcheek commented Jan 10, 2019

I played around with https://github.com/f/omelette as a plugin for proof of concept. It is lightweight, has zero dependencies, is cross-platform compatible and works with both zsh and bash. If anything, it may serve as inspiration for how to proceed if the Lando team builds the feature out from a scratch.

@tylerssn do you have anything concrete yet? I'd be willing to do a little bit of coding to help make this happen, although I'm a novice at node.

@tylers-username
Copy link

tylers-username commented Jan 13, 2019

Given that yargs is already included in Lando and that Lando is not in the autocompletion business - Omelette may be a bit much to integrate at the moment, despite it's lightweight and platform compatibility.

Yargs gives us bash autocompletion and Zsh can support it as well with the following two lines:

# Enable bash completion support in Zsh
autoload -U +X bashcompinit && bashcompinit
eval "$(lando completion)"
# Or, in development: eval "$(./bin/lando.js completion)"

To see a functional proof of concept in Lando:

  1. Modify bin/lando.js:22 from const yargs = require('yargs') to const yargs = require('yargs').completion(); This makes bin/lando.js completion available to bash and you can see Lando tooling is populating at bin/lando.js --get-yargs-completions.
  2. Now that Lando is serving auto completed tooling, tell bash how to use it: bin/lando.js completion >> ~/.bashrc && source ~/.bashrc.

(Zsh users will need to execute bash bin/lando.js completion >> ~/.zshrc && source ~/.zshrc

You can now execute bin/lando.js <tab> and should see Lando tooling populating.

Obstacles for integration with Lando:

  1. Autocompleted commands such as destroy [appserver] are treated as two separate commands. I think this can be overcome by using the callback in .completion() to modify the suggestion handler.

  2. Automating ~/.bashrc setup. I think this can be tackled with a tooling command such as lando --autocomplete=on|off and using RegEx to identify/replace/remove the required script.

    # ~/.bashrc
    
    #### Lando Autocomplete Identifier ####
    {output of bin/lando.js  completion}
    #### Lando Autocomplete Identifier ####
  3. Autocompleting command options. Currently my example works on commands but it does not work on their options. I believe there is a solution to this and it is described here, we just need to decide the best method of implementation.

@tylers-username
Copy link

tylers-username commented Jan 13, 2019

@jcheek - Here's a working implementation that someone can take from here. I won't be spending much more time on it after this weekend.

Features:

  • Observes tasks listed in lando.tasks and provides completion suggestions by name.
  • Allows tasks to provide their own suggestions by reading a new string array property from Lando tasks called completion. Example:
    # plugins/lando-core/tasks/version.js
    module.exports = lando => ({
      command: 'version',
      completion: ['suggestionOne', 'suggestionTwo'],
      describe: 'Display the lando version',
      run: () => {
        console.log('v' + lando.config.version);
      },
    });
  • bin/lando.js <tab>
    • Lists all commands by task.name as completion suggestions.
    • Testable with bin/lando.js --get-yargs-completion or bin/lando.js <tab>
  • bin/lando.js {task.name} <tab>
    • List suggestions made available by task.completion. This is a property that can be added to any task. To test this out modify plugins/lando-core/tasks/version.js so that it has property completion: ['suggestionOne', 'suggestionTwo'].
    • Testable with bin/lando.js --get-yargs-completion version or bin/lando.js version <tab>.

Setup:

  1. Add lando-autocomplete to the plugins directory.
  2. Add this to ./plugins/lando-autocomplete/index.js
    'use strict';
    
    const _ = require('lodash');
    
    const getCommandArgumentCompletion = (tasksList, userInput) => {
     let commands = [];
     _.forEach(_.sortBy(tasksList, 'command'), task => {
       const isCommandMatch = userInput !== task.name;
       if (isCommandMatch) {
         return;
       }
       commands = task.completion;
     });
    
     const missingCompletion = !commands instanceof Array;
     if (missingCompletion) {
       console.log('Missing completion');
       return;
     }
    
     return commands;
    };
    
    const getCommandCompletion = tasksList => {
     const commands = [];
     _.forEach(_.sortBy(tasksList, 'command'), task => {
       commands.push(task.name);
     });
    
     return commands;
    };
    
    module.exports = lando => {
     const pluginAddedObserverCount = 1;
     // Suppress max listener warnings
     lando.events.setMaxListeners(lando.events.getMaxListeners() + pluginAddedObserverCount);
    
    // Register completion feature
     lando.events.on('post-bootstrap', 99999, lando => {
       return new Promise((resolve, reject) => {
         resolve(require('yargs').completion(
           'completion',
           'For use by bash auto-complete',
           (userInput, argv) => new Promise((resolve, reject) => {
             
             // If user is tab completing bin/lando.js <tab>, do this.
             if (!userInput) {
               resolve(getCommandCompletion(lando.tasks.tasks));
             }
    
            // If user is tab completing bin/lando.js command <tab>, do this.
            resolve(getCommandArgumentCompletion(lando.tasks.tasks, userInput));
            })
        ));
       });
     });
    };
  3. Add lando-autocomplete to config.yml's plugin list.

Key Issue: I have a promise mess. bin/lando.js --get-yargs-completion and bin/lando.js --get-yargs-completion version always list all available tasks and version suggestions as expected. However, intermittently, bin/lando.js <tab> does not list any commands. I belive this is because Lando is exiting before the promise is fulfilled. bin/lando.js version <tab> does not have this issue.

@edurenye
Copy link
Contributor

edurenye commented Mar 7, 2019

For Ubuntu 18.10 I added the plugin in ~/.lando/plugins following the instructions, added the plugin in ~/.lando/config.yml
It detected the plugin, but I got an error, it could not find lodash dependency, so I added it with npm install -g lodash and replaced const _ = require('lodash'); for const _ = require('/usr/lib/node_modules/lodash');

But then I had the following error:
error: Problem loading plugin lando-autocomplete from /home/user/.lando/plugins/lando-autocomplete/index.js: TypeError: process.binding(...).internalModuleReadFile is not a function at Object.fs.internalModuleReadFile.fs.internalModuleReadJSON (pkg/prelude/bootstrap.js:1127:36) at internalModuleReadJSON (internal/modules/cjs/loader.js:31:68) at readPackage (internal/modules/cjs/loader.js:156:16) at tryPackage (internal/modules/cjs/loader.js:172:13) at Function.Module._findPath (internal/modules/cjs/loader.js:282:18) at Function.Module._resolveFilename (internal/modules/cjs/loader.js:589:25) at Function.Module._resolveFilename (pkg/prelude/bootstrap.js:1270:44) at Function.Module._load (internal/modules/cjs/loader.js:518:25) at Module.require (internal/modules/cjs/loader.js:648:17) at Module.require (pkg/prelude/bootstrap.js:1157:31) at require (internal/modules/cjs/helpers.js:20:18) at Object.<anonymous> (/home/user/.lando/plugins/lando-autocomplete/index.js:3:11) at Module._compile (internal/modules/cjs/loader.js:700:30) at Module._compile (pkg/prelude/bootstrap.js:1213:32) at Object.Module._extensions..js (internal/modules/cjs/loader.js:711:10) at Module.load (internal/modules/cjs/loader.js:610:32)

I was using rc13 version of lando.

@edurenye
Copy link
Contributor

edurenye commented Mar 8, 2019

Looks like this is fixed in the version 4.3.7 of pkg: vercel/pkg#461
So Lando needs to update this dependency.

@tylers-username
Copy link

tylers-username commented Mar 13, 2019

@edurenye - My example was more than likely built on RC1 so you'd certainly have to make some changes to get this into a working state.

@edurenye
Copy link
Contributor

That problem with node that was also showing up in the rc1 is gone now, the plugin is loaded fine without errors.
I use zsh, so I proceeded with the following.
I added the plugin and everything I did before.
Now the line to change is in lib/cli.js instead of bin/lando.js, I replaced in line 110:
return require('yargs').help(false).version(false).argv;
for:
return require('yargs').help(false).version(false).completion().argv;
Run:
~/lando/bin/lando.js completion >> ~/.zshrc && source ~/.zshrc

This added the following to ~/.zshrc
###-begin-lando.js-completions-###
#
# yargs command completion script
#
# Installation: .//home/user/lando/bin/lando.js completion >> ~/.bashrc
# or .//home/user/lando/bin/lando.js completion >> ~/.bash_profile on OSX.
#
_yargs_completions()
{
local cur_word args type_list

`cur_word="${COMP_WORDS[COMP_CWORD]}"
args=("${COMP_WORDS[@]}")`

`# ask yargs to generate completions.`
`type_list=$(.//home/user/lando/bin/lando.js --get-yargs-completions "${args[@]}")`

`COMPREPLY=( $(compgen -W "${type_list}" -- ${cur_word}) )`

`# if no match was found, fall back to filename completion`
`if [ ${#COMPREPLY[@]} -eq 0 ]; then
  COMPREPLY=( $(compgen -f -- "${cur_word}" ) )
fi`

`return 0`

}
complete -F _yargs_completions lando.js
###-end-lando.js-completions-###
Although the autocomplete does not work and ~/lando/bin/lando.js --get-yargs-completions just gives me "completion" but tabbing does not give me even that.

@stale
Copy link

stale bot commented Apr 18, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions and please check out this if you are wondering why we auto close issues.

@stale stale bot added the stale label Apr 18, 2019
@edurenye
Copy link
Contributor

Do not close this issue, this is a really interesting feature

@stale stale bot removed the stale label Apr 19, 2019
@stale
Copy link

stale bot commented May 19, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions and please check out this if you are wondering why we auto close issues.

@stale stale bot added the stale label May 19, 2019
@pirog
Copy link
Member

pirog commented May 20, 2019

unstale

@stale stale bot removed the stale label May 20, 2019
@stale
Copy link

stale bot commented Jun 19, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions and please check out this if you are wondering why we auto close issues.

@stale stale bot added the stale label Jun 19, 2019
@tylers-username
Copy link

@edurenye - if it helps, testing this was tricky in the dev env when calling bin/lando.js. If I recall correctly, I had to create an alias such as landoDev to the Lando bin file in order for Zsh and Bash to start completing.

@stale stale bot removed the stale label Jun 21, 2019
@stale
Copy link

stale bot commented Jul 21, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions and please check out this if you are wondering why we auto close issues.

@stale stale bot added the stale label Jul 21, 2019
@stale stale bot closed this as completed Jul 28, 2019
@pirog pirog removed the stale label Feb 24, 2020
@allanlaal
Copy link

please reopen this :)
(and delete stalebot - it just spams and makes us spam issues with non-content)

@reynoldsalec reynoldsalec reopened this Mar 24, 2022
@reynoldsalec
Copy link
Member

From maintainer convos I know that we're looking at moving to a different CLI construction tool with Lando 4.x, probably in the next year. Added relevant tags and re-opened.

@stale
Copy link

stale bot commented May 22, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions and please check out this if you are wondering why we auto close issues.

@stale stale bot added the stale label May 22, 2023
@edurenye
Copy link
Contributor

Will the use of oclif help fix this? Should we move this issue to https://github.com/lando/cli ?

@stale stale bot removed the stale label May 29, 2023
@pirog
Copy link
Member

pirog commented May 30, 2023

@edurenye i do think OCLIF has some utils around tab completion however. i think the difficulty is going to be around completion of commands that differ from app to app.

@pirog pirog transferred this issue from lando/lando May 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants