Bug #73292 [Fbk->Asn]: readline_info returns empty/old line_buffer info
| From: | me at xbug dot de | Date: | Wed, 12 Oct 2016 07:54:10 +0000 |
| Subject: | Bug #73292 [Fbk->Asn]: readline_info returns empty/old line_buffer info | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-204624@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=73292&edit=1
ID: 73292
User updated by: me at xbug dot de
Reported by: me at xbug dot de
Summary: readline_info returns empty/old line_buffer info
-Status: Feedback
+Status: Assigned
Type: Bug
Package: Readline related
Operating System: Debian
PHP Version: 5.6.26
Assigned To: remi
Block user comment: N
Private report: N
New Comment:
Your are right, $input works like expected. But I want to go one step further and make an
autocomplete for the arguments of commands. Therefore I need the whole current line to get the first
word, which is the command. And this seems not be possible with the $input arg of the function,
which always just contains the current underling word.
For example the Shell class of the symfony console component uses the readline_info() this way, too.
(https://github.com/symfony/console/blob/2.7/Shell.php#L168)
Previous Comments:
------------------------------------------------------------------------
[2016-10-12 06:52:18] remi@php.net
I don't understand why you want to use readline_info() output instead of $input, which contains
the pending input, and works as expected.
<?php
readline_completion_function(
function ($input) {
$words = ['albert', 'alfred', 'bob', 'remi',
'foo'];
$ret = [];
foreach($words as $word) {
if ($input == substr($word, 0, strlen($input))) {
$ret[] = $word;
}
}
return $ret;
}
);
while (readline('cmd: '));
------------------------------------------------------------------------
[2016-10-12 03:19:10] pollita@php.net
There's two substantive (and likely causative) changes in the Readline extension between PHP
5.4 and PHP 5.5 (there are none between 5.5 and 5.6).
https://github.com/php/php-src/commit/31d67bd35362c1ab570caccedfec3e24257b55c5
https://github.com/php/php-src/commit/b8d88bf2c588dcaec185468da8db306cd7e6ab8d
Could you clarify two things:
1) Do you have libreadline or libedit installed on your system?
2) Did you compile ext/readline against libedit or libreadline? (Or did you install from stock
Debian Jesse package?)
In the mean time, assigning to Remi since both those commits are his.
------------------------------------------------------------------------
[2016-10-11 15:03:33] me at xbug dot de
Description:
------------
Under php5.4 (ubuntu 14.04) the function readline_info returned the correct values. But since
(possible 5.5) php5.6 (debian jessie) it returns empty and sometimes old values.
I've tested it also under php7.0 (Mint) and the behaviour is the same as in php5.6.
Test script:
---------------
<?php
readline_completion_function(
function ($input) {
$info = readline_info();
$text = substr($info['line_buffer'], 0, $info['end']);
var_dump($info);
if ($info['point'] !== $info['end']) {
return [];
}
// task name?
if (false === strpos($text, ' ') || !$text) {
return ['one', 'three'];
}
// This is never called since php 5.6
$cmd = substr($text, 0, strpos($text, ' '));
if ($cmd === 'one') {
return ['two'];
} elseif ($cmd === 'three') {
return ['four'];
}
return [];
}
);
while (true) {
readline('cmd: ');
}
Expected result:
----------------
$ php readline.php
cmd: onearray(6) {
["line_buffer"]=>
string(3) "one"
["point"]=>
int(3)
["end"]=>
int(3)
["library_version"]=>
string(16) "EditLine wrapper"
["readline_name"]=>
string(0) ""
["attempted_completion_over"]=>
int(0)
}
Actual result:
--------------
$ php readline.php
cmd: onearray(6) {
["line_buffer"]=>
string(0) ""
["point"]=>
int(3)
["end"]=>
int(3)
["library_version"]=>
string(16) "EditLine wrapper"
["readline_name"]=>
string(0) ""
["attempted_completion_over"]=>
int(0)
}
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=73292&edit=1