22

I have a PHP command line script which kicks off a job to a job server, with the job name being an argument. The job names are namespaced, such as Foo:Bar_Baz_JobName. Is there a way I could implement auto-completion, like how typing the first few letters of a filename and pressing tab bash completes the file name for you. I know it can be done, because tab-completion works on ubuntu with apt-get, I just don't know if it can be done in PHP.

Harold1983-
  • 3,329
  • 2
  • 23
  • 22

4 Answers4

15

Autocompletion is done using the GNU readline library, which apparently is accessible from PHP. Specifically, look at readline_completion_function. Usage is fairly simple; you call readline_completion_function with one argument, a callback function that handles the completion. The callback function takes the first few letters (basically, whatever you type before pressing TAB) as input and should return an array of possible matches.

David Z
  • 128,184
  • 27
  • 255
  • 279
  • 2
    Can you give a complete example? Where are you supposed to define this, and how to prevent execution of the rest of the file? – Lode Aug 24 '15 at 08:35
  • If you're having trouble figuring it out, it might be a matter for a separate question. – David Z Aug 24 '15 at 09:09
  • 1
    No, I'd say it doesn't. The question asks how to implement autocompletion. Asking where to define a function and how to prevent execution of the rest of the file is general stuff that falls outside the scope of how to implement autocompletion. – David Z Aug 24 '15 at 19:14
  • For me it would be, implement is more than naming a function. But fine. – Lode Aug 25 '15 at 19:40
  • Well... okay, I guess "how to implement" implies giving some code. But the question didn't literally ask how to implement. Basically, the way it was phrased, I think giving a full code sample is not necessary. – David Z Aug 25 '15 at 21:53
7

Yes! you can do this by PHP!

CLIFramework provides a command helps you generate the bash completion script by your command definitions.

You can also define your argument completion in PHP, the generated bash/zsh completion will return the execution result from PHP at the runtime:

https://github.com/c9s/CLIFramework

Screencast (bash):

enter image description here

Screencast (zsh):

enter image description here

c9s
  • 1,888
  • 19
  • 15
7

About readline_completion_function

I would say that considering the type of interaction you are looking for (apt-get autocomplete) this method is not good.

In fact before to get a autocomplete function you have to run the script and then you'll access the autocomplete function.

The autocomplete function is partial. So, it like the bash autocomplete not the zsh.

In the shell:

➜  ~ php test.php (enter) 
Custom command: (tab)
a b c
Custom command: (tab)
a b c

The code is:

<?php
// test.php
class AutoController
{

    private static function getCommandsArray()
    {
        $my_dir = array('a', 'b', 'c');
        return $my_dir;
    }

    /**
     * The callback which is returning an array with strings, which will be
     * auto-completed.
     *
     * @param $input
     * @param $index
     * @return array
     */
    private static function completionCallback($input, $index)
    {
        return self::getCommandsArray();
    }

    /**
     * The method which is handling the autocompletion. After it's runned, you can
     * autocomplete your commands by hitting the tab-button.
     */
    public function actionCompl()
    {
        readline_completion_function(array('self', 'completionCallback'));

        $command_input = readline("Custom command: ");

        passthru('echo ' . $command_input);
    }
}

$a = new AutoController();
$a->actionCompl();

About runtime autocomplete

As suggested by c9s it is possible to obtain this kind of functionality but extending autocomplete functionality of your bash, not with PHP.

So, if you see the autocomplete function of CLIFramework for example you'll see:

BashGenerator.php
ZshGenerator.php

Which is used to generate the bash script to extends the bash or zsh autocomplete.

So, it depends on the shell you are using the way you have to make the autocomplete.

Some references:

borracciaBlu
  • 4,017
  • 3
  • 33
  • 41
  • This answer made me understand what PHP manual failed to explain. The fact that your PHP-script must be running for `readline_completion_function()` to work. It's obvious when you think about it. Hitting tab when your script is not running is asking your CLI to autocomplete, not your PHP-script. Thank you for clarifying this! – Kalle Nov 11 '21 at 09:11
3

You can try using readline, more specifically, the readline_completion_function function.

Ionuț G. Stan
  • 176,118
  • 18
  • 189
  • 202