trait CompletionTrait
Adds completion to arguments and options.
@internal
Hierarchy
- trait \Composer\Command\CompletionTrait
File
-
vendor/
composer/ composer/ src/ Composer/ Command/ CompletionTrait.php, line 31
Namespace
Composer\CommandView source
trait CompletionTrait {
/**
* @see BaseCommand::requireComposer()
*/
public abstract function requireComposer(?bool $disablePlugins = null, ?bool $disableScripts = null) : Composer;
/**
* Suggestion values for "prefer-install" option
*
* @return list<string>
*/
private function suggestPreferInstall() : array {
return [
'dist',
'source',
'auto',
];
}
/**
* Suggest package names from root requirements.
*/
private function suggestRootRequirement() : \Closure {
return function (CompletionInput $input) : array {
$composer = $this->requireComposer();
return array_merge(array_keys($composer->getPackage()
->getRequires()), array_keys($composer->getPackage()
->getDevRequires()));
};
}
/**
* Suggest package names from installed.
*/
private function suggestInstalledPackage(bool $includeRootPackage = true, bool $includePlatformPackages = false) : \Closure {
return function (CompletionInput $input) use ($includeRootPackage, $includePlatformPackages) : array {
$composer = $this->requireComposer();
$installedRepos = [];
if ($includeRootPackage) {
$installedRepos[] = new RootPackageRepository(clone $composer->getPackage());
}
$locker = $composer->getLocker();
if ($locker->isLocked()) {
$installedRepos[] = $locker->getLockedRepository(true);
}
else {
$installedRepos[] = $composer->getRepositoryManager()
->getLocalRepository();
}
$platformHint = [];
if ($includePlatformPackages) {
if ($locker->isLocked()) {
$platformRepo = new PlatformRepository([], $locker->getPlatformOverrides());
}
else {
$platformRepo = new PlatformRepository([], $composer->getConfig()
->get('platform'));
}
if ($input->getCompletionValue() === '') {
// to reduce noise, when no text is yet entered we list only two entries for ext- and lib- prefixes
$hintsToFind = [
'ext-' => 0,
'lib-' => 0,
'php' => 99,
'composer' => 99,
];
foreach ($platformRepo->getPackages() as $pkg) {
foreach ($hintsToFind as $hintPrefix => $hintCount) {
if (str_starts_with($pkg->getName(), $hintPrefix)) {
if ($hintCount === 0 || $hintCount >= 99) {
$platformHint[] = $pkg->getName();
$hintsToFind[$hintPrefix]++;
}
elseif ($hintCount === 1) {
unset($hintsToFind[$hintPrefix]);
$platformHint[] = substr($pkg->getName(), 0, max(strlen($pkg->getName()) - 3, strlen($hintPrefix) + 1)) . '...';
}
continue 2;
}
}
}
}
else {
$installedRepos[] = $platformRepo;
}
}
$installedRepo = new InstalledRepository($installedRepos);
return array_merge(array_map(static function (PackageInterface $package) {
return $package->getName();
}, $installedRepo->getPackages()), $platformHint);
};
}
/**
* Suggest package names from installed.
*/
private function suggestInstalledPackageTypes(bool $includeRootPackage = true) : \Closure {
return function (CompletionInput $input) use ($includeRootPackage) : array {
$composer = $this->requireComposer();
$installedRepos = [];
if ($includeRootPackage) {
$installedRepos[] = new RootPackageRepository(clone $composer->getPackage());
}
$locker = $composer->getLocker();
if ($locker->isLocked()) {
$installedRepos[] = $locker->getLockedRepository(true);
}
else {
$installedRepos[] = $composer->getRepositoryManager()
->getLocalRepository();
}
$installedRepo = new InstalledRepository($installedRepos);
return array_values(array_unique(array_map(static function (PackageInterface $package) {
return $package->getType();
}, $installedRepo->getPackages())));
};
}
/**
* Suggest package names available on all configured repositories.
*/
private function suggestAvailablePackage(int $max = 99) : \Closure {
return function (CompletionInput $input) use ($max) : array {
if ($max < 1) {
return [];
}
$composer = $this->requireComposer();
$repos = new CompositeRepository($composer->getRepositoryManager()
->getRepositories());
$results = [];
$showVendors = false;
if (!str_contains($input->getCompletionValue(), '/')) {
$results = $repos->search('^' . preg_quote($input->getCompletionValue()), RepositoryInterface::SEARCH_VENDOR);
$showVendors = true;
}
// if we get a single vendor, we expand it into its contents already
if (\count($results) <= 1) {
$results = $repos->search('^' . preg_quote($input->getCompletionValue()), RepositoryInterface::SEARCH_NAME);
$showVendors = false;
}
$results = array_column($results, 'name');
if ($showVendors) {
$results = array_map(static function (string $name) : string {
return $name . '/';
}, $results);
// sort shorter results first to avoid auto-expanding the completion to a longer string than needed
usort($results, static function (string $a, string $b) {
$lenA = \strlen($a);
$lenB = \strlen($b);
if ($lenA === $lenB) {
return $a <=> $b;
}
return $lenA - $lenB;
});
$pinned = [];
// ensure if the input is an exact match that it is always in the result set
$completionInput = $input->getCompletionValue() . '/';
if (false !== ($exactIndex = array_search($completionInput, $results, true))) {
$pinned[] = $completionInput;
array_splice($results, $exactIndex, 1);
}
return array_merge($pinned, array_slice($results, 0, $max - \count($pinned)));
}
return array_slice($results, 0, $max);
};
}
/**
* Suggest package names available on all configured repositories or
* platform packages from the ones available on the currently-running PHP
*/
private function suggestAvailablePackageInclPlatform() : \Closure {
return function (CompletionInput $input) : array {
if (Preg::isMatch('{^(ext|lib|php)(-|$)|^com}', $input->getCompletionValue())) {
$matches = $this->suggestPlatformPackage()($input);
}
else {
$matches = [];
}
return array_merge($matches, $this->suggestAvailablePackage(99 - \count($matches))($input));
};
}
/**
* Suggest platform packages from the ones available on the currently-running PHP
*/
private function suggestPlatformPackage() : \Closure {
return function (CompletionInput $input) : array {
$repos = new PlatformRepository([], $this->requireComposer()
->getConfig()
->get('platform'));
$pattern = BasePackage::packageNameToRegexp($input->getCompletionValue() . '*');
return array_filter(array_map(static function (PackageInterface $package) {
return $package->getName();
}, $repos->getPackages()), static function (string $name) use ($pattern) : bool {
return Preg::isMatch($pattern, $name);
});
};
}
}
Members
Title Sort descending | Modifiers | Object type | Summary |
---|---|---|---|
CompletionTrait::requireComposer | abstract public | function | |
CompletionTrait::suggestAvailablePackage | private | function | Suggest package names available on all configured repositories. |
CompletionTrait::suggestAvailablePackageInclPlatform | private | function | Suggest package names available on all configured repositories or platform packages from the ones available on the currently-running PHP |
CompletionTrait::suggestInstalledPackage | private | function | Suggest package names from installed. |
CompletionTrait::suggestInstalledPackageTypes | private | function | Suggest package names from installed. |
CompletionTrait::suggestPlatformPackage | private | function | Suggest platform packages from the ones available on the currently-running PHP |
CompletionTrait::suggestPreferInstall | private | function | Suggestion values for "prefer-install" option |
CompletionTrait::suggestRootRequirement | private | function | Suggest package names from root requirements. |