PHP--手摸手,教你擼一個會自動補全的命令行工具1

前言

一次在使用symfony的時候,發現使用命令行的時候有些關鍵字會自動提示。php

clipboard.png

介紹

隨着laravel,symfony等框架的流行,命令行工具愈來愈流行,可是不少時候命令太多,根本沒法記住全部參數,或者參數太長輸入太不方便。
這時是否也想擁有一個像IDE中的自動補全功能?laravel

手摸手,一塊兒擼一個自動補全工具

獲取命令行字符串

想自動補全,必須獲取命令行輸入的數據,那麼如何獲取數據呢?
具體能夠參考官方文檔 PHP獲取命令輸入,這裏咱們使用一種寫法shell

$c = fread(\STDIN, 1);

這樣咱們就能夠獲取每次輸入的按鍵。框架

clipboard.png

獲取單個字符

進行了上面的操做之後,咱們已經能夠獲取到輸入的內容,可是發現一個問題,咱們必須按下回車之後才能夠獲取到輸入的內容,即便咱們設置了fread最大讀取的長度,那麼到底是什麼問題的?
原來Linux終端中,默認是必須按下回車的。那麼咱們必須關閉這個功能。爲了防止咱們使用其餘軟件出現問題,咱們不須要該功能後須要將其關閉。工具

//執行以下命令後,就能夠一個字符一個字符的獲取了
$sttyMode = shell_exec('stty -g');
shell_exec('stty -icanon -echo');

//恢復原來的狀態
shell_exec(sprintf('stty %s', $sttyMode));

這時,咱們在進行測試測試

clipboard.png

$sttyMode = shell_exec('stty -g');
shell_exec('stty -icanon -echo');
$c = fread(\STDIN, 1);
var_dump($c);
shell_exec(sprintf('stty %s', $sttyMode));

簡易自動補全

<?php
 $sttyMode = shell_exec('stty -g');
shell_exec('stty -icanon -echo');
$autoComplete = [
    "Auto",
    "Complete"
];
$inputStream = STDIN;
while (!feof($inputStream)) {
    $c = fread($inputStream, 1);

    //是否是空
    if (false === $c || empty($c)) {
        throw new Exception('Aborted.');
    } elseif ("\177" === $c) { // 刪除按鍵
        //printf(177);
    } elseif ("\033" === $c) {
        // printf(033);
        // $c .= fread($inputStream, 2);
        // printf($c);
    } elseif (\ord($c) < 32) {
        // if ("\t" === $c || "\n" === $c) {
        //     if ("\n" === $c) {
        //         break;
        //     }
        // }
        continue;
    } else {
        if ("\x80" <= $c) {
            $c .= fread($inputStream, ["\xC0" => 1, "\xD0" => 1, "\xE0" => 2, "\xF0" => 3][$c & "\xF0"]);
        }
        printf("\r\033[k");

        foreach($autoComplete as $one){
            if (strpos($one,$c)===0){
                printf($one);
            }
        }
    }
}


shell_exec(sprintf('stty %s', $sttyMode));

clipboard.png

下面咱們在優化一下,當輸入A之後,讓光標在A的後邊優化

clipboard.png
這樣一個簡易的自動補全工具就誕生了。下文,咱們一塊兒來優化這個工具。spa

備註:Windows不支持自動補全.net

相關文章
相關標籤/搜索