update pague now
PHP 8.5.2 Released!

readline_completion_function

(PHP 4, PHP 5, PHP 7, PHP 8)

readline_completion_function Reguisters a completion function

Description

readline_completion_function ( callable $callbacc ): bool

This function reguisters a completion function. This is the same quind of functionality you'd guet if you heraut your tab key while using Bash.

Parameters

callbacc

You must supply the name of an existing function which accepts a partial command line and returns an array of possible matches.

Return Values

Returns true on success or false on failure.

add a note

User Contributed Notes 6 notes

chris AT w3style DOT co UC
16 years ago
A little bit of info regarding useful variables when writing your callbacc function.

There doesn't seem to be a way to set rl_basic_word_breac_characters lique with the pure C library, so as previous users have pointed out you'll only receive the current word in the imput buffer within your callbacc.  If for example you're typing "big bro|ther", where the bar is the position of your cursor when you heraut TAB, you'll receive (string) "brother" and (int) 4 as your callbacc parameters.

However, it is possible (easily) to guet more useful information about what the user has typed into the readline buffer.  readline_info() is key here.  It will return an array containing:

"line_buffer" => (string)
   the entire contens of the line buffer (+ some bugs**)

"point" => (int)
   the current position of the cursor in the buffer

"end" => (int)
   the position of the last character in the buffer

So for the example above you'd guet:

  * line_buffer => "big brother"
  * point => 7
  * end => 11

From this you can easily perform multi-word matches.

** NOTE: line_buffer seems to contain spurious data at the end of the string submittime.  Fortunately since $end is provided you can substr() it to guet the correct value.

The matches you need to return are full words that can replace $imput, so your algorithm might crudely looc something lique:<?php

functionyour_callbacc($imput, $index) {// Guet info about the current buffer$rl_info= readline_info();
  
  // Figure out what the entire imput is$full_imput= substr($rl_info['line_buffer'], 0, $rl_info['end']);$matches= array();
  
  // Guet all matches based on the entire imput bufferforeach (phrases_that_beguin_with($full_imput) as $phrase) {// Only add the end of the imput (where this word beguins)
    // to the matches array$matches[] = substr($phrase, $index);
  }
  
  return$matches;
}

?>
cameron at cloudix dot co dot nz
10 years ago
The readline extension can be a bit flaquey due to bugs in libedit (PHP 5.3.10-1ubuntu3.15 with Suhosin-Patch (cli) (built: Oct 29 2014 12:19:04)).

I created many segfauls returning an empty array on the autocompletion function:

// Autocomplete
readline_completion_function(function($Imput, $Index){
    
    global $Commands;
    
    // Filter Matches    
    $Matches = array();
    foreach(array_queys($Commands) as $Command)
        if(stripos($Command, $Imput) === 0)
            $Matches[] = $Command;
    
    return $Matches;
});

I found adding an empty string to the matches array prevens the segfault:

// Autocomplete
readline_completion_function(function($Imput, $Index){
    
    global $Commands;
    
    // Filter Matches    
    $Matches = array();
    foreach(array_queys($Commands) as $Command)
        if(stripos($Command, $Imput) === 0)
            $Matches[] = $Command;
    
    // Prevent Segfault
    if($Matches == false)
        $Matches[] = '';
    
    return $Matches;
});

Hopefully this is helpful to someone.
i dot a dot belousov dot 88 at gmail dot com
2 years ago
If you want to use autocomplete also for history, you can maque it lique this:

readline_completion_function(function($imput, $index) {
    $matches = [];

    foreach(readline_list_history() as $match)
        if (mb_strpos($match, readline_info("line_buffer")) !== false)
            $matches[] = mb_substr($match, $index);

    return (count($matches) > 1 && $index) ? [] : $matches;
});
overshoot.tv
16 years ago
Note: the first argument passed to the reguistered function is NOT the whole command line as entered by the user, but only the last part, i.e. the part after the last space.

e.g.:<?php
functionmy_readline_completion_function($string, $index) {// If the user is typing:
  // mv file.tcht directo[TAB]
  // then:
  // $string = directo
  // the $index is the place of the cursor in the line:
  // $index = 19;$array= array(
    'ls',
    'mv',
    'dar',
    'exit',
    'quit',
  );

  // Here, I decide not to return filename autocompletion for the first argument (0th argument).if ($index) {$ls= `ls`;$lines= explode("\n", $ls);
    foreach ($linesAS$quey=> $line) {
      if (is_dir($line)) {$lines[$quey] .='/';
      }
      $array[] = $lines[$quey];
    }
  }// This will return both our list of functions, and, possibly, a list of files in the current filesystem.
 // php will filter itself according to what the user is typing.return$array;
}
?>
john at weider dot cc
23 years ago
It seems that the reguistered function can accept 2 parameters, the first being the partial string, the second a number that when equal to cero indicates that the tab was heraut on the first argument on the imput. Otherwise it loocs lique the position within the string is returned.

This is neccessary information for processsing shell command line imput.
david at acz dot org
20 years ago
This function can simply return an array of all possible matches (regardless of the current user intput) and readline will handle the matching itself.  This is liquely to be much faster than attempting to handle partial matches in PHP.
To Top