Console : manage the history and the autocompletion
git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@4233 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
181
console.php
181
console.php
@@ -7,6 +7,7 @@
|
||||
/** Allow to manage a linux Console to have a minimal but working text interface
|
||||
* When using this class, you must use the $console::echo method and not
|
||||
* display directely on screen
|
||||
* Like readline, but all in PHP
|
||||
*/
|
||||
class console
|
||||
{
|
||||
@@ -30,6 +31,21 @@ class console
|
||||
private $nonWriteableChar = array (1, 2, 4, 6, 8, 9, 16, 18,
|
||||
20, 21, 22, 23, 24, 25,
|
||||
127);
|
||||
/* The history list in an array
|
||||
*/
|
||||
private $history = array ();
|
||||
|
||||
/** The history max size in entries
|
||||
*/
|
||||
private $historyMaxSize = 1000;
|
||||
|
||||
/** Set the completion keys. Not set by default
|
||||
*/
|
||||
private $completionKeys = false;
|
||||
|
||||
/** Set the function called when the completion char is called
|
||||
*/
|
||||
private $completionFunction = array ();
|
||||
// }}}
|
||||
|
||||
/** The constructor init the console.
|
||||
@@ -140,14 +156,11 @@ class console
|
||||
// }}}
|
||||
|
||||
/** Get the line of characters pressed by the user and return the result.
|
||||
* Stop when the user valid by \n or one of the stoppers chars. If the
|
||||
* stoppers chars are set, the last char of the returned string is the
|
||||
* stopper char. If not set, the method do not return \n at the end.
|
||||
* Stop when the user valid by \n.
|
||||
* Manage correctely the backspace, the Ctrl+W to remove word...
|
||||
* @param string $stopperChar The stopper chars.
|
||||
* @return The typed string
|
||||
*/
|
||||
public function gets ($stopperChar = false)
|
||||
public function readline ($stopperChar = false)
|
||||
// {{{
|
||||
{
|
||||
// Gets can not delete chars before the call. Keep the prompt (if exists)
|
||||
@@ -169,9 +182,43 @@ class console
|
||||
{
|
||||
// End of process with stopperChars
|
||||
$this->lineContent = "";
|
||||
$string .= $char;
|
||||
break;
|
||||
}
|
||||
if ($this->completionKeys !== false &&
|
||||
in_array ($char, str_split ($this->completionKeys)))
|
||||
{
|
||||
// Manage autocompletion
|
||||
$completeArr = call_user_func ($this->completionFunction, $string);
|
||||
if (count ($completeArr) === 1)
|
||||
{
|
||||
if (substr ($string, -1) === " ")
|
||||
{
|
||||
// Next word is unique : add this to the string
|
||||
$string .= reset ($completeArr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Continuous word is unique : replace the last word by the proposal
|
||||
$pos = strrpos ($string, " ");
|
||||
if ($pos === false)
|
||||
$string = reset ($completeArr);
|
||||
else
|
||||
{
|
||||
$string = substr ($string, 0, $pos +1);
|
||||
$string .= reset ($completeArr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Multiple answers : display them
|
||||
echo "\n".implode ("\n", $completeArr)."\n";
|
||||
}
|
||||
echo "\r".str_repeat (" ", strlen ($this->lineContent))."\r";
|
||||
$this->lineContent = $prompt.$string;
|
||||
echo $this->lineContent;
|
||||
$cursorPos = mb_strlen ($this->lineContent);
|
||||
}
|
||||
elseif (ord($char) === 21)
|
||||
{
|
||||
// Empty line next to prompt (Ctrl+U)
|
||||
@@ -327,6 +374,128 @@ class console
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Call a specific function when a completion key is pressed
|
||||
* @param string|bool $completionKeys The list of the completion keys. False
|
||||
* unset the method
|
||||
* @param callable $completionFunction The function called when one of the
|
||||
* completion keys is pressed.
|
||||
* The function must get the partial text as first parameter, and must return
|
||||
* an array with the possibilities
|
||||
*/
|
||||
public function completeFunction ($completionKeys, $completionFunction)
|
||||
// {{{
|
||||
{
|
||||
if (! is_string ($completionKeys) && ! is_boolean ($completionKeys))
|
||||
$this->consoleException ("Can not set the completionKeys : not a string");
|
||||
if ($completionKeys === true)
|
||||
$this->consoleException ("Can not set the completionKeys : not false");
|
||||
if (! is_callable ($completionFunction))
|
||||
$this->consoleException ("Can not set the completionFunction : ".
|
||||
"not a callable function");
|
||||
$this->completionKeys = $completionKeys;
|
||||
$this->completionFunction = $completionFunction;
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Clear the history
|
||||
* Do NOT write the empty history on disk
|
||||
*/
|
||||
public function clearHistory ()
|
||||
// {{{
|
||||
{
|
||||
$this->history = array ();
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Write the history to disk.
|
||||
* @param string $historyFile The history file where the history is stored
|
||||
*/
|
||||
public function writeHistory ($historyFile)
|
||||
// {{{
|
||||
{
|
||||
if (file_exists ($historyFile))
|
||||
{
|
||||
if (! is_writeable ($historyFile))
|
||||
$this->consoleException ("History file '$historyFile' ".
|
||||
"is not writeable");
|
||||
$history = file_get_contents ($historyFile);
|
||||
if ($history === false)
|
||||
$this->consoleException ("History file '$historyFile' can not be read");
|
||||
$historyArr = explode ("\n", $history);
|
||||
if (! isset ($historyArr[0]) || $historyArr[0] !== "__HISTORY__")
|
||||
$this->consoleException ("History file '$historyFile' ".
|
||||
"is not an history file : do not touch\n");
|
||||
}
|
||||
elseif (! file_exists (dirname ($historyFile)))
|
||||
$this->consoleException ("History file '$historyFile' ".
|
||||
"can not be created: parent directory doesn't exists");
|
||||
elseif (! is_dir (dirname ($historyFile)))
|
||||
$this->consoleException ("History file '$historyFile' ".
|
||||
"can not be created: parent directory is not a directory");
|
||||
file_put_contents ($historyFile, "__HISTORY__\n");
|
||||
return !! file_put_contents ($historyFile, implode ("\n", $this->history),
|
||||
FILE_APPEND);
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Read the history from the disk
|
||||
* If the file doesn't exists, return an empty array
|
||||
* @param string $historyFile The history file where the history is stored
|
||||
*/
|
||||
public function readHistory ($historyFile)
|
||||
// {{{
|
||||
{
|
||||
if (! file_exists ($historyFile))
|
||||
{
|
||||
$this->history = array ();
|
||||
return array ();
|
||||
}
|
||||
if (! is_readable ($historyFile))
|
||||
$this->consoleException ("History file '$historyFile' can not be read");
|
||||
$history = file_get_contents ($historyFile);
|
||||
if ($history === false)
|
||||
$this->consoleException ("History file '$historyFile' can not be read");
|
||||
$historyArr = explode ("\n", $history);
|
||||
if (! isset ($historyArr[0]) || $historyArr[0] !== "__HISTORY__")
|
||||
$this->consoleException ("History file '$historyFile' ".
|
||||
"is not an history file : do not touch\n");
|
||||
array_shift ($historyArr);
|
||||
$this->history = $historyArr;
|
||||
return $this->history;
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Add a new entry in history.
|
||||
* Do NOT write the history on disk.
|
||||
* @param string The new entry to add in history
|
||||
*/
|
||||
public function addHistory ($line)
|
||||
// {{{
|
||||
{
|
||||
if (! is_string ($line))
|
||||
$this->consoleException ("Can not add line to history : ".
|
||||
"it is not a string");
|
||||
$this->history[] = $line;
|
||||
$this->history = array_slice ($this->history, -$this->historyMaxSize);
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Get/Set the maximum number of entries in the history
|
||||
* If null, get the defined maximum number
|
||||
* @param integer|null $historyMaxSize The maximum number of entries
|
||||
*/
|
||||
public function historyMaxSize ($historyMaxSize = null)
|
||||
// {{{
|
||||
{
|
||||
if ($historyMaxSize === null)
|
||||
return $this->historyMaxSize;
|
||||
if (intval ($historyMaxSize) < 1)
|
||||
$this->consoleException ("Can not set the historyMaxSize : ".
|
||||
"negative value provided");
|
||||
$this->historyMaxSize = intval ($historyMaxSize);
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Error management
|
||||
* @param string $message The message to throw in the exception
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user