readline_completion_function

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

readline_completion_function注册完成函数

描述

readline_completion_function(callable $callback): bool

此函数注册完成函数。这与您在使用 Bash 时按下 Tab 键获得的功能相同。

参数

callback

您必须提供一个已存在函数的名称,该函数接受一个部分命令行并返回一个可能的匹配项数组。

返回值

成功时返回 true,失败时返回 false

添加笔记

用户贡献笔记 6 个笔记

chris AT w3style DOT co UK
14 年前
关于编写回调函数时有用变量的一些信息。

似乎没有办法像使用纯 C 库一样设置 rl_basic_word_break_characters,因此正如之前的用户指出的那样,您只会在回调函数中收到输入缓冲区中的当前单词。例如,如果您正在输入“big bro|ther”,其中竖线是您按下 TAB 时光标的位置,您将收到 (string) “brother” 和 (int) 4 作为您的回调参数。

但是,可以(轻松地)获取有关用户输入到 readline 缓冲区中的更多有用信息。readline_info() 是关键。它将返回一个包含以下内容的数组

"line_buffer" => (string)
行缓冲区的全部内容(+ 一些错误**)

"point" => (int)
缓冲区中光标的当前位置

"end" => (int)
缓冲区中最后一个字符的位置

因此,对于上面的示例,您将得到

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

由此,您可以轻松地执行多词匹配。

** 注意:line_buffer 有时似乎在字符串末尾包含伪数据。幸运的是,由于提供了 $end,因此您可以使用 substr() 获取正确的值。**

您需要返回的匹配项是可以用 $input 替换的完整单词,因此您的算法可能粗略地类似于

<?php

function your_callback($input, $index) {
// 获取有关当前缓冲区的信息
$rl_info = readline_info();

// 找出整个输入是什么
$full_input = substr($rl_info['line_buffer'], 0, $rl_info['end']);

$matches = array();

// 根据整个输入缓冲区获取所有匹配项
foreach (phrases_that_begin_with($full_input) as $phrase) {
// 只将输入的末尾(此词开始的位置)
// 添加到 matches 数组中
$matches[] = substr($phrase, $index);
}

return
$matches;
}

?>
cameron at cloudix dot co dot nz
9 年前
readline 扩展可能有点不稳定,因为 libedit 中存在错误(PHP 5.3.10-1ubuntu3.15 with Suhosin-Patch (cli) (built: Oct 29 2014 12:19:04))。

我在自动完成函数中创建了许多段错误,返回一个空数组

// 自动完成
readline_completion_function(function($Input, $Index){

global $Commands;

// 过滤匹配项
$Matches = array();
foreach(array_keys($Commands) as $Command)
if(stripos($Command, $Input) === 0)
$Matches[] = $Command;

return $Matches;
});

我发现向 matches 数组添加一个空字符串可以防止段错误

// 自动完成
readline_completion_function(function($Input, $Index){

global $Commands;

// 过滤匹配项
$Matches = array();
foreach(array_keys($Commands) as $Command)
if(stripos($Command, $Input) === 0)
$Matches[] = $Command;

// 阻止段错误
if($Matches == false)
$Matches[] = '';

return $Matches;
});

希望这对某些人有所帮助。
i dot a dot belousov dot 88 at gmail dot com
9 个月前
如果您想对历史记录也使用自动完成,您可以像这样进行

readline_completion_function(function($input, $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
15 年前
注意:传递给注册函数的第一个参数不是用户输入的完整命令行,而是只有最后部分,即最后一个空格后的部分。

例如
<?php
function my_readline_completion_function($string, $index) {
// 如果用户正在输入:
// mv file.txt directo[TAB]
// 那么:
// $string = directo
// $index 是光标在行中的位置:
// $index = 19;

$array = array(
'ls',
'mv',
'dar',
'exit',
'quit',
);

// 在这里,我决定不对第一个参数(第 0 个参数)返回文件名自动完成。
if ($index) {
$ls = `ls`;
$lines = explode("\n", $ls);
foreach (
$lines AS $key => $line) {
if (
is_dir($line)) {
$lines[$key] .= '/';
}
$array[] = $lines[$key];
}
}
// 这将返回我们的函数列表以及当前文件系统中的文件列表(如果存在)。
// php 将根据用户输入自行过滤。
return $array;
}
?>
john at weider dot cc
21 年前
似乎注册的函数可以接受 2 个参数,第一个是部分字符串,第二个是数字,当等于 0 时表示在输入的第一个参数上按下了 Tab 键。否则,它看起来像是返回了字符串中的位置。

这是处理 shell 命令行输入的必要信息。
david at acz dot org
19 年前
此函数可以简单地返回所有可能的匹配项数组(无论当前用户输入如何),readline 将自行处理匹配。这可能比尝试在 PHP 中处理部分匹配要快得多。
To Top