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

Allow for more shell build-in completions #33

Open
aik099 opened this issue Jan 31, 2015 · 6 comments
Open

Allow for more shell build-in completions #33

aik099 opened this issue Jan 31, 2015 · 6 comments

Comments

@aik099
Copy link
Contributor

aik099 commented Jan 31, 2015

The compgen is interesting program in Bash, that provides auto-complete for various things in the system. For example:

  • -a means Names of alias
  • -b means Names of shell builtins
  • -c means Names of all commands
  • -d means Names of directory
  • -e means Names of exported shell variables
  • -f means Names of file and functions
  • -g means Names of groups
  • -j means Names of job
  • -k means Names of Shell reserved words
  • -s means Names of service
  • -u means Names of userAlias names
  • -v means Names of shell variables

Maybe there is something similar in ZSH: http://www.csse.uwa.edu.au/programming/linux/zsh-doc/zsh_23.html

What I think we should do is to abstract shell interaction on PHP level and not via IFs in generated hook. Right now if we want to auto-complete usernames in system we need to update the hook and that's not very convenient.

@stecman
Copy link
Owner

stecman commented Feb 2, 2015

More built-in completions would be good, and they would certainly need to be implementations of CompletionInterface. I wouldn't want to have an enormous number of library provided completions, but having some common ones built in would be helpful.

What I think we should do is to abstract shell interaction on PHP level and not via IFs in generated hook. Right now if we want to auto-complete usernames in system we need to update the hook and that's not very convenient.

All completions should to be implemented in PHP unless there is a really good reason for doing otherwise. The path completion built-in is the only behaviour deferred to the parent shell at the moment, and there is good reason for it being part of the hook (explained below).

If we were going to provide username completion, it would look something like this:

class SystemUsersCompletion implements CompletionInterface
{
    public function run()
    {
        exec('cat /etc/passwd | grep -v "^#" | cut -d":" -f1', $usernames);
        return $usernames;
    }
}

The PHP implementation exception for ShellPathCompletion

Currently this library does defer to the shell hooks for ShellPathCompletion, but only because it needs to; the command that it needs to run is a completion system function (_filedir/_path_files) that expects to be run in directly in the context of the shell's completion system. It might be possible to run these functions from PHP, but that would require replicating the environment the functions expect to run in, which is potentially unreliable and would need to be kept up to date with external changes to the completion systems. There's a bit more detail in the commit that introduced this functionality

compgen -f [path] looks like it can be run from PHP code for completing filesystem paths, but there doesn't appear to be a ZSH equivalent (something that can be run independently of the completion system). More importantly, path completion behaviour is particular to each shell. I think it's important to use the path completion function provided by the running completion system as this will have the behaviour the user expects.

@aik099
Copy link
Contributor Author

aik099 commented Feb 2, 2015

Interesting, what getcwd() will return if we decide to manually auto-complete paths from PHP?

For example:

  • I'm in /some/folder folder
  • app is in /other/folder folder
  • I run app command-name TAB

I expect current working directory to be /some/folder, but I guess it wold be /other/folder instead because we run completion command from that folder.

@stecman
Copy link
Owner

stecman commented Feb 3, 2015

A process always starts with its current working directory set the same as the process that created it.

A child process created via fork(2) inherits its parent's current working directory. The current working directory is left unchanged by execve(2). - chdir man page

This library doesn't change the working directory, so completion is always in the context of the directory you are in when you trigger completion - regardless of where the program/code is located (unless user-code changes the directory of course).

@aik099
Copy link
Contributor Author

aik099 commented Feb 3, 2015

OK.

About compgen: maybe we can use it because it's not bash specific app, it's just an app. And usually Bash is installed on any machine and then people go and install zsh. So compgen should be available.

The compgen -u sounds more error prone, then manually parsing /etc/passwd anyway.

@stecman
Copy link
Owner

stecman commented Feb 3, 2015

compgen is actually built into BASH, so it can't be run as a standalone program. You can do this though (provided the system has BASH installed):

exec("bash -c 'compgen -u'");

Just playing around with this now I can't figure out what determines the shell PHP uses with exec, passthru etc, but it's not guaranteed to be the same as the shell you're operating in. In my tests on OSX for example it's always bash, and on Ubuntu it's always sh. In any case, I wouldn't want to introduce a dependency on BASH unnecessarily, so yeah we'll try to avoid using compgen.

@aik099
Copy link
Contributor Author

aik099 commented Feb 3, 2015

On Ubuntu /bin/sh is symlink to Bash clone shell. On Slackware it's symlink to /bin/bash. But I do agree, that using one shell features in another shell is bad idea.

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

2 participants