PHP Conference Japan 2024

readline_completion_function

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

readline_completion_function注册一个完成函数

描述

readline_completion_function(可调用 $callback): 布尔值

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

参数

callback

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

返回值

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

添加注释

用户贡献的注释 6 个注释

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

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

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

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

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

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

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

* 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[] = substr($phrase, $index);
}

return
$matches;
}

?>
cameron at cloudix dot co dot nz
9 年前
由于 libedit 中的错误,readline 扩展可能有点不稳定(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;
});

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

// 自动完成
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
1 年前
如果您想对历史记录也使用自动完成,您可以像这样操作

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
22 年前
似乎已注册的函数可以接受 2 个参数,第一个是部分字符串,第二个是一个数字,当等于零时表示在输入的第一个参数上按下了 Tab 键。否则,它看起来像返回了字符串中的位置。

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