diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-19 00:10:22 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-19 00:11:03 +0900 |
| commit | c839244d8d09f3036ebfee8eef7eb6b147e593ab (patch) | |
| tree | fe48c94f2c2e62468beef5ff1a8f3cff6adeef4f /crates/shirabe/src/command/completion_trait.rs | |
| parent | 48839250146b217e2756ed3c0e624fd341b54d6c (diff) | |
| download | php-shirabe-c839244d8d09f3036ebfee8eef7eb6b147e593ab.tar.gz php-shirabe-c839244d8d09f3036ebfee8eef7eb6b147e593ab.tar.zst php-shirabe-c839244d8d09f3036ebfee8eef7eb6b147e593ab.zip | |
fix(compile): fix various compile errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/command/completion_trait.rs')
| -rw-r--r-- | crates/shirabe/src/command/completion_trait.rs | 278 |
1 files changed, 5 insertions, 273 deletions
diff --git a/crates/shirabe/src/command/completion_trait.rs b/crates/shirabe/src/command/completion_trait.rs index 4e04441..1d45651 100644 --- a/crates/shirabe/src/command/completion_trait.rs +++ b/crates/shirabe/src/command/completion_trait.rs @@ -1,276 +1,8 @@ //! ref: composer/src/Composer/Command/CompletionTrait.php -use crate::composer::Composer; -use crate::package::base_package::{self, BasePackage}; -use crate::package::package_interface::PackageInterface; -use crate::repository::composite_repository::CompositeRepository; -use crate::repository::installed_repository::InstalledRepository; -use crate::repository::platform_repository::PlatformRepository; -use crate::repository::repository_interface::{self, RepositoryInterface}; -use crate::repository::root_package_repository::RootPackageRepository; -use shirabe_external_packages::composer::pcre::preg::Preg; -use shirabe_external_packages::symfony::component::console::completion::completion_input::CompletionInput; -use shirabe_php_shim::preg_quote; +// TODO(cli-completion): CompletionTrait powered shell completion for command arguments and +// options. The PHP version exposes Closures that resolve to package names, types, etc. We do not +// port that surface yet — see TODO(cli-completion) markers in each command for the original +// suggestions. -pub trait CompletionTrait { - fn require_composer( - &self, - disable_plugins: Option<bool>, - disable_scripts: Option<bool>, - ) -> Composer; - - fn suggest_prefer_install(&self) -> Vec<String> { - vec!["dist".to_string(), "source".to_string(), "auto".to_string()] - } - - fn suggest_root_requirement(&self) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> { - Box::new(move |_input: &CompletionInput| -> Vec<String> { - let composer = self.require_composer(None, None); - - let requires: Vec<String> = composer - .get_package() - .get_requires() - .keys() - .cloned() - .collect(); - let dev_requires: Vec<String> = composer - .get_package() - .get_dev_requires() - .keys() - .cloned() - .collect(); - [requires, dev_requires].concat() - }) - } - - fn suggest_installed_package( - &self, - include_root_package: bool, - include_platform_packages: bool, - ) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> { - Box::new(move |input: &CompletionInput| -> Vec<String> { - let composer = self.require_composer(None, None); - let mut installed_repos: Vec< - Box<dyn crate::repository::repository_interface::RepositoryInterface>, - > = Vec::new(); - - if include_root_package { - installed_repos.push(Box::new(RootPackageRepository::new( - composer.get_package().clone(), - ))); - } - - let locker = composer.get_locker(); - if locker.is_locked() { - installed_repos.push(Box::new(locker.get_locked_repository(true))); - } else { - installed_repos.push(Box::new( - composer.get_repository_manager().get_local_repository(), - )); - } - - let mut platform_hint: Vec<String> = Vec::new(); - if include_platform_packages { - let platform_repo = if locker.is_locked() { - PlatformRepository::new(vec![], locker.get_platform_overrides()) - } else { - PlatformRepository::new(vec![], composer.get_config().get("platform")) - }; - if input.get_completion_value() == "" { - // to reduce noise, when no text is yet entered we list only two entries for ext- and lib- prefixes - let mut hints_to_find: indexmap::IndexMap<String, i64> = - indexmap::IndexMap::new(); - hints_to_find.insert("ext-".to_string(), 0); - hints_to_find.insert("lib-".to_string(), 0); - hints_to_find.insert("php".to_string(), 99); - hints_to_find.insert("composer".to_string(), 99); - - 'pkg_loop: for pkg in platform_repo.get_packages() { - for (hint_prefix, hint_count) in hints_to_find.iter_mut() { - if pkg.get_name().starts_with(hint_prefix.as_str()) { - if *hint_count == 0 || *hint_count >= 99 { - platform_hint.push(pkg.get_name().to_string()); - *hint_count += 1; - } else if *hint_count == 1 { - hints_to_find.remove(hint_prefix); - platform_hint.push(format!( - "{}...", - &pkg.get_name()[..pkg - .get_name() - .len() - .saturating_sub(3) - .max(hint_prefix.len() + 1)] - )); - } - continue 'pkg_loop; - } - } - } - } else { - installed_repos.push(Box::new(platform_repo)); - } - } - - let installed_repo = InstalledRepository::new(installed_repos); - - let mut result: Vec<String> = installed_repo - .get_packages() - .iter() - .map(|package| package.get_name().to_string()) - .collect(); - result.extend(platform_hint); - result - }) - } - - fn suggest_installed_package_types( - &self, - include_root_package: bool, - ) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> { - Box::new(move |_input: &CompletionInput| -> Vec<String> { - let composer = self.require_composer(None, None); - let mut installed_repos: Vec< - Box<dyn crate::repository::repository_interface::RepositoryInterface>, - > = Vec::new(); - - if include_root_package { - installed_repos.push(Box::new(RootPackageRepository::new( - composer.get_package().clone(), - ))); - } - - let locker = composer.get_locker(); - if locker.is_locked() { - installed_repos.push(Box::new(locker.get_locked_repository(true))); - } else { - installed_repos.push(Box::new( - composer.get_repository_manager().get_local_repository(), - )); - } - - let installed_repo = InstalledRepository::new(installed_repos); - - let mut types: Vec<String> = installed_repo - .get_packages() - .iter() - .map(|package| package.get_type().to_string()) - .collect(); - types.sort(); - types.dedup(); - types - }) - } - - fn suggest_available_package( - &self, - max: i64, - ) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> { - Box::new(move |input: &CompletionInput| -> Vec<String> { - if max < 1 { - return Vec::new(); - } - - let composer = self.require_composer(None, None); - let repos = - CompositeRepository::new(composer.get_repository_manager().get_repositories()); - - let mut results: Vec<String>; - let mut show_vendors = false; - if !input.get_completion_value().contains('/') { - let search_results = repos.search( - format!("^{}", preg_quote(input.get_completion_value(), None)), - repository_interface::SEARCH_VENDOR, - None, - ); - results = search_results.iter().map(|r| r.name.clone()).collect(); - show_vendors = true; - } else { - results = Vec::new(); - } - - // if we get a single vendor, we expand it into its contents already - if results.len() <= 1 { - let search_results = repos.search( - format!("^{}", preg_quote(input.get_completion_value(), None)), - repository_interface::SEARCH_NAME, - None, - ); - results = search_results.iter().map(|r| r.name.clone()).collect(); - show_vendors = false; - } - - if show_vendors { - let mut results: Vec<String> = results - .into_iter() - .map(|name| format!("{}/", name)) - .collect(); - - // sort shorter results first to avoid auto-expanding the completion to a longer string than needed - results.sort_by(|a, b| { - let len_a = a.len(); - let len_b = b.len(); - if len_a == len_b { - a.cmp(b) - } else { - len_a.cmp(&len_b) - } - }); - - let mut pinned: Vec<String> = Vec::new(); - - // ensure if the input is an exact match that it is always in the result set - let completion_input = format!("{}/", input.get_completion_value()); - if let Some(exact_index) = results.iter().position(|x| x == &completion_input) { - pinned.push(completion_input); - results.remove(exact_index); - } - - let take_count = (max as usize).saturating_sub(pinned.len()); - let mut final_results = pinned; - final_results.extend(results.into_iter().take(take_count)); - return final_results; - } - - results.into_iter().take(max as usize).collect() - }) - } - - fn suggest_available_package_incl_platform( - &self, - ) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> { - Box::new(move |input: &CompletionInput| -> Vec<String> { - let matches = - if Preg::is_match(r"{^(ext|lib|php)(-|$)|^com}", input.get_completion_value()) { - self.suggest_platform_package()(input) - } else { - Vec::new() - }; - - let max = 99i64 - matches.len() as i64; - let mut result = matches; - result.extend(self.suggest_available_package(max)(input)); - result - }) - } - - fn suggest_platform_package(&self) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> { - Box::new(move |input: &CompletionInput| -> Vec<String> { - let repos = PlatformRepository::new( - vec![], - self.require_composer(None, None) - .get_config() - .get("platform"), - ); - - let pattern = - base_package::package_name_to_regexp(&format!("{}*", input.get_completion_value())); - - repos - .get_packages() - .iter() - .map(|package| package.get_name().to_string()) - .filter(|name| Preg::is_match(&pattern, name)) - .collect() - }) - } -} +pub trait CompletionTrait {} |
