<?php
/*
* This file is part of Psy Shell.
*
* (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Psy\Readline;
/**
* A Readline interface implementation for GNU Readline.
*
* This is by far the coolest way to do it, if you can.
*
* Oh well.
*/
class GNUReadline implements Readline
{
/** @var string|false */
protected $historyFile;
/** @var int */
protected $historySize;
/** @var bool */
protected $eraseDups;
/**
* GNU Readline is supported iff `readline_list_history` is defined. PHP
* decided it would be awesome to swap out GNU Readline for Libedit, but
* they ended up shipping an incomplete implementation. So we've got this.
*
* NOTE: As of PHP 7.4, PHP sometimes has history support in the Libedit
* wrapper, so that will use the GNUReadline implementation as well!
*/
public static function isSupported(): bool
{
return \function_exists('readline') && \function_exists('readline_list_history');
}
/**
* Check whether this readline implementation supports bracketed paste.
*
* Currently, the GNU readline implementation does, but the libedit wrapper does not.
*/
public static function supportsBracketedPaste(): bool
{
return self::isSupported() && \stripos(\readline_info('library_version') ?: '', 'editline') === false;
}
public function __construct($historyFile = null, $historySize = 0, $eraseDups = false)
{
$this->historyFile = ($historyFile !== null) ? $historyFile : false;
$this->historySize = $historySize;
$this->eraseDups = $eraseDups;
\readline_info('readline_name', 'psysh');
}
/**
* {@inheritdoc}
*/
public function addHistory(string $line): bool
{
if ($res = \readline_add_history($line)) {
$this->writeHistory();
}
return $res;
}
/**
* {@inheritdoc}
*/
public function clearHistory(): bool
{
if ($res = \readline_clear_history()) {
$this->writeHistory();
}
return $res;
}
/**
* {@inheritdoc}
*/
public function listHistory(): array
{
return \readline_list_history();
}
/**
* {@inheritdoc}
*/
public function readHistory(): bool
{
\readline_read_history();
\readline_clear_history();
return \readline_read_history($this->historyFile);
}
/**
* {@inheritdoc}
*/
public function readline(?string $prompt = null)
{
return \readline($prompt);
}
/**
* {@inheritdoc}
*/
public function redisplay()
{
\readline_redisplay();
}
/**
* {@inheritdoc}
*/
public function writeHistory(): bool
{
// We have to write history first, since it is used
// by Libedit to list history
if ($this->historyFile !== false) {
$res = \readline_write_history($this->historyFile);
} else {
$res = true;
}
if (!$res || !$this->eraseDups && !$this->historySize > 0) {
return $res;
}
$hist = $this->listHistory();
if (!$hist) {
return true;
}
if ($this->eraseDups) {
// flip-flip technique: removes duplicates, latest entries win.
$hist = \array_flip(\array_flip($hist));
// sort on keys to get the order back
\ksort($hist);
}
if ($this->historySize > 0) {
$histsize = \count($hist);
if ($histsize > $this->historySize) {
$hist = \array_slice($hist, $histsize - $this->historySize);
}
}
\readline_clear_history();
foreach ($hist as $line) {
\readline_add_history($line);
}
if ($this->historyFile !== false) {
return \readline_write_history($this->historyFile);
}
return true;
}
}
How To Payment
Making a payment on our website is quick and secure. Start by logging in or creating an account. Select your preferred payment method, input the required details, and review the information. Once you confirm everything is correct, click on the "Submit Payment" button. You’ll receive instant confirmation and can track your payment status through your account dashboard. It’s an easy and secure process.