一次在利用symfony的时候,创造利用命令行的时候有些关键字会自动提示。
先容
随着laravel,symfony等框架的盛行,命令行工具越来越盛行,但是很多时候命令太多,根本无法记住所有参数,或者参数太长输入太未便利。
这时是否也想拥有一个像IDE中的自动补全功能?
手摸手,一起撸一个自动补全工具
获取命令行字符串
想自动补全,必须获取命令行输入的数据,那么如何获取数据呢?
详细可以参考官方文档 PHP获取命令输入,这里我们利用一种写法
$c = fread(\STDIN, 1);
这样我们就可以获取每次输入的按键。
获取单个字符
进行了上面的操作往后,我们已经可以获取到输入的内容,但是创造一个问题,我们必须按下回车往后才可以获取到输入的内容,纵然我们设置了fread最大读取的长度,那么究竟是什么问题的?
原来Linux终端中,默认是必须按下回车的。那么我们必须关闭这个功能。为了防止我们利用其他软件涌现问题,我们不须要该功能后须要将其关闭。
//实行如下命令后,就可以一个字符一个字符的获取了$sttyMode = shell_exec('stty -g');shell_exec('stty -icanon -echo');//恢复原来的状态shell_exec(sprintf('stty %s', $sttyMode));
这时,我们在进行测试
$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));
下面我们在优化一下,当输入A往后,让光标在A的后边
这样一个大略单纯的自动补全工具就出身了。下文,我们一起来优化这个工具。
备注:Windows不支持自动补全