PHP Conference Japan 2024

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
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)
如果 (stripos($Command, $Input) === 0)
$Matches[] = $Command;

返回 $Matches;
});

我發現新增一個空字串到匹配陣列可以防止 segmentation fault

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

global $Commands;

// 過濾匹配項
$Matches = array();
foreach(array_keys($Commands) as $Command)
如果 (stripos($Command, $Input) === 0)
$Matches[] = $Command;

// 防止 Segmentation Fault
如果 ($Matches == false)
$Matches[] = '';

返回 $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)
如果 (mb_strpos($match, readline_info("line_buffer")) !== false)
$matches[] = mb_substr($match, $index);

返回 (count($matches) > 1 && $index) ? [] : $matches;
});
overshoot.tv
15 年前
注意:傳遞給已註冊函數的第一個參數並非使用者輸入的完整命令列,而只是最後一部分,即最後一個空格之後的部分。

例如:
<?php
函式 my_readline_completion_function($string, $index) {
// 如果使用者正在輸入:
// mv file.txt directo[TAB]
// 則:
// $string = directo
// $index 是游標在行中的位置:
// $index = 19;

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

// 在此,我決定不為第一個參數(第 0 個參數)返回檔名自動完成。
如果 ($index) {
$ls = `ls`;
$lines = explode("\n", $ls);
foreach (
$lines 作為 $key => $line) {
if (
is_dir($line)) {
$lines[$key] .= '/';
}
$array[] = $lines[$key];
}
}
// 這將返回我們的函數列表,以及可能返回目前檔案系統中的檔案列表。
// php 會根據使用者輸入的內容自行過濾。
返回 $array;
}
?>
john at weider dot cc
22 年前
看來已註冊的函式可以接受兩個參數,第一個是部分字串,第二個是一個數字,當它等於零時,表示在輸入的第一個參數上按下了 Tab 鍵。否則,它看起來會返回字串中的位置。

這是處理 shell 命令列輸入的必要資訊。
david at acz dot org
19 年前
這個函式可以簡單地返回所有可能匹配項的陣列(無論目前的使用者輸入為何),readline 會自行處理匹配。這可能比嘗試在 PHP 中處理部分匹配要快得多。
To Top