diff options
Diffstat (limited to 'crates/shirabe-external-packages/src/symfony/console/completion')
6 files changed, 0 insertions, 573 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/console/completion/completion_input.rs b/crates/shirabe-external-packages/src/symfony/console/completion/completion_input.rs deleted file mode 100644 index f8bddcee..00000000 --- a/crates/shirabe-external-packages/src/symfony/console/completion/completion_input.rs +++ /dev/null @@ -1,435 +0,0 @@ -//! ref: composer/vendor/symfony/console/Completion/CompletionInput.php - -use crate::symfony::console::input::argv_input::ArgvInput; -use crate::symfony::console::input::input_definition::InputDefinition; -use crate::symfony::console::input::input_option::InputOption; -use shirabe_php_shim::{PhpMixed, php_regex}; - -/// An input specialized for shell completion. -/// -/// This input allows unfinished option names or values and exposes what kind of -/// completion is expected. -#[derive(Debug, Clone)] -pub struct CompletionInput { - inner: ArgvInput, - tokens: Vec<String>, - current_index: i64, - completion_type: String, - completion_name: Option<String>, - completion_value: String, -} - -impl CompletionInput { - pub const TYPE_ARGUMENT_VALUE: &'static str = "argument_value"; - pub const TYPE_OPTION_VALUE: &'static str = "option_value"; - pub const TYPE_OPTION_NAME: &'static str = "option_name"; - pub const TYPE_NONE: &'static str = "none"; - - /// Converts a terminal string into tokens. - /// - /// This is required for shell completions without COMP_WORDS support. - pub fn from_string(input_str: &str, current_index: i64) -> anyhow::Result<Self> { - let tokens = shirabe_php_shim::preg_match_all( - php_regex!("/(?<=^|\\s)(['\"]?)(.+?)(?<!\\\\)\\1(?=$|\\s)/"), - input_str, - ); - - Self::from_tokens(tokens[0].clone(), current_index) - } - - /// Create an input based on an COMP_WORDS token list. - /// - /// `tokens` is the set of split tokens (e.g. COMP_WORDS or argv), - /// `current_index` the index of the cursor (e.g. COMP_CWORD). - pub fn from_tokens(tokens: Vec<String>, current_index: i64) -> anyhow::Result<Self> { - let mut input = Self { - inner: ArgvInput::new(Some(tokens.clone()), None)?, - tokens: vec![], - current_index: 0, - completion_type: String::new(), - completion_name: None, - completion_value: String::new(), - }; - input.tokens = tokens; - input.current_index = current_index; - - Ok(input) - } - - pub fn bind(&mut self, definition: &InputDefinition) -> anyhow::Result<()> { - self.inner - .base_bind(definition, |argv, token, parse_options| { - Ok(CompletionInput::parse_token(argv, token, parse_options)) - })?; - - let relevant_token = self.get_relevant_token(); - if "-" == &relevant_token[0..1] { - // the current token is an input option: complete either option name or option value - let parts = shirabe_php_shim::explode_with_limit("=", &relevant_token, 2); - let option_token = parts.first().cloned().unwrap_or_default(); - let option_value = parts.get(1).cloned().unwrap_or_default(); - - let option = self.get_option_from_token(&option_token); - if option.is_none() && !self.is_cursor_free() { - self.completion_type = Self::TYPE_OPTION_NAME.to_string(); - self.completion_value = relevant_token; - - return Ok(()); - } - - if let Some(option) = &option - && option.accept_value() - { - self.completion_type = Self::TYPE_OPTION_VALUE.to_string(); - self.completion_name = Some(option.get_name().to_string()); - self.completion_value = if !option_value.is_empty() { - option_value - } else if !shirabe_php_shim::str_starts_with(&option_token, "--") { - shirabe_php_shim::substr(&option_token, 2, None) - } else { - String::new() - }; - - return Ok(()); - } - } - - let previous_token = self.tokens[(self.current_index - 1) as usize].clone(); - if "-" == &previous_token[0..1] - && !shirabe_php_shim::trim(&previous_token, Some("-")).is_empty() - { - // check if previous option accepted a value - let previous_option = self.get_option_from_token(&previous_token); - if let Some(previous_option) = &previous_option - && previous_option.accept_value() - { - self.completion_type = Self::TYPE_OPTION_VALUE.to_string(); - self.completion_name = Some(previous_option.get_name().to_string()); - self.completion_value = relevant_token; - - return Ok(()); - } - } - - // complete argument value - self.completion_type = Self::TYPE_ARGUMENT_VALUE.to_string(); - - let mut argument_name: Option<String> = None; - let argument_names: Vec<String> = self - .inner - .inner - .definition - .get_arguments() - .keys() - .cloned() - .collect(); - for current_argument_name in argument_names { - // PHP's foreach assigns the key variable before the body runs, so on break - // $argumentName still names the first argument that has no bound value. - argument_name = Some(current_argument_name.clone()); - if !self - .inner - .inner - .arguments - .contains_key(¤t_argument_name) - { - break; - } - - let argument_value = self.inner.inner.arguments[¤t_argument_name].clone(); - self.completion_name = Some(current_argument_name.clone()); - if let PhpMixed::List(argument_value) = &argument_value { - self.completion_value = argument_value - .last() - .map(|v| v.to_string()) - .unwrap_or_default(); - } else { - self.completion_value = argument_value.to_string(); - } - } - - if self.current_index >= self.tokens.len() as i64 { - let argument_name = argument_name.unwrap_or_default(); - if !self.inner.inner.arguments.contains_key(&argument_name) - || self - .inner - .inner - .definition - .get_argument(&PhpMixed::String(argument_name.clone())) - .unwrap() - .is_array() - { - self.completion_name = Some(argument_name); - self.completion_value = String::new(); - } else { - // we've reached the end - self.completion_type = Self::TYPE_NONE.to_string(); - self.completion_name = None; - self.completion_value = String::new(); - } - } - - Ok(()) - } - - /// Returns the type of completion required. - /// - /// TYPE_ARGUMENT_VALUE when completing the value of an input argument - /// TYPE_OPTION_VALUE when completing the value of an input option - /// TYPE_OPTION_NAME when completing the name of an input option - /// TYPE_NONE when nothing should be completed - pub fn get_completion_type(&self) -> String { - self.completion_type.clone() - } - - /// The name of the input option or argument when completing a value. - /// - /// Returns null when completing an option name. - pub fn get_completion_name(&self) -> Option<String> { - self.completion_name.clone() - } - - /// The value already typed by the user (or empty string). - pub fn get_completion_value(&self) -> String { - self.completion_value.clone() - } - - pub fn must_suggest_option_values_for(&self, option_name: &str) -> bool { - Self::TYPE_OPTION_VALUE == self.get_completion_type() - && Some(option_name.to_string()) == self.get_completion_name() - } - - pub fn must_suggest_argument_values_for(&self, argument_name: &str) -> bool { - Self::TYPE_ARGUMENT_VALUE == self.get_completion_type() - && Some(argument_name.to_string()) == self.get_completion_name() - } - - pub fn get_first_argument(&self) -> Option<String> { - self.inner.get_first_argument() - } - - /// PHP `CompletionInput::parseToken` (called back from `ArgvInput::base_bind`). Takes the - /// embedded ArgvInput instead of `&mut self` because the parse loop already holds the - /// exclusive borrow of it. - fn parse_token(inner: &mut ArgvInput, token: &str, parse_options: bool) -> bool { - match inner.parse_token(token, parse_options) { - Ok(value) => return value, - Err(_e) => { - // suppress errors, completed input is almost never valid - } - } - - parse_options - } - - fn get_option_from_token(&self, option_token: &str) -> Option<std::rc::Rc<InputOption>> { - let option_name = shirabe_php_shim::ltrim(option_token, Some("-")); - if option_name.is_empty() { - return None; - } - - if "-" - == option_token - .chars() - .nth(1) - .map(|c| c.to_string()) - .unwrap_or_else(|| " ".to_string()) - { - // long option name - return if self.inner.inner.definition.has_option(&option_name) { - self.inner.inner.definition.get_option(&option_name).ok() - } else { - None - }; - } - - // short option name - let first = &option_name[0..1]; - if self.inner.inner.definition.has_shortcut(first) { - self.inner - .inner - .definition - .get_option_for_shortcut(first) - .ok() - } else { - None - } - } - - /// The token of the cursor, or the last token if the cursor is at the end of the input. - fn get_relevant_token(&self) -> String { - let index = if self.is_cursor_free() { - self.current_index - 1 - } else { - self.current_index - }; - self.tokens[index as usize].clone() - } - - /// Whether the cursor is "free" (i.e. at the end of the input preceded by a space). - fn is_cursor_free(&self) -> bool { - let nr_of_tokens = self.tokens.len() as i64; - if self.current_index > nr_of_tokens { - // LogicException: recoverable usage as a "convenient fatal error"; panic. - panic!("Current index is invalid, it must be the number of input tokens or one more."); - } - - self.current_index >= nr_of_tokens - } -} - -/// PHP: `CompletionInput extends ArgvInput` — the inherited `InputInterface` surface, -/// forwarded to the embedded `ArgvInput`. `bind` dispatches to the specialized -/// `CompletionInput::bind` above, matching PHP's virtual dispatch. -impl crate::symfony::console::input::input_interface::InputInterface for CompletionInput { - fn dup( - &self, - ) -> std::rc::Rc< - std::cell::RefCell<dyn crate::symfony::console::input::input_interface::InputInterface>, - > { - std::rc::Rc::new(std::cell::RefCell::new(self.clone())) - } - - fn get_first_argument(&self) -> Option<String> { - self.inner.get_first_argument() - } - - fn __to_string(&self) -> String { - self.to_string() - } - - fn has_parameter_option(&self, values: PhpMixed, only_params: bool) -> bool { - crate::symfony::console::input::input_interface::InputInterface::has_parameter_option( - &self.inner, - values, - only_params, - ) - } - - fn get_parameter_option( - &self, - values: PhpMixed, - default: PhpMixed, - only_params: bool, - ) -> PhpMixed { - crate::symfony::console::input::input_interface::InputInterface::get_parameter_option( - &self.inner, - values, - default, - only_params, - ) - } - - fn bind(&mut self, definition: &InputDefinition) -> anyhow::Result<()> { - CompletionInput::bind(self, definition) - } - - fn validate(&mut self) -> anyhow::Result<()> { - crate::symfony::console::input::input_interface::InputInterface::validate(&mut self.inner) - } - - fn get_arguments(&self) -> indexmap::IndexMap<String, PhpMixed> { - crate::symfony::console::input::input_interface::InputInterface::get_arguments(&self.inner) - } - - fn get_argument(&self, name: &str) -> anyhow::Result<PhpMixed> { - crate::symfony::console::input::input_interface::InputInterface::get_argument( - &self.inner, - name, - ) - } - - fn set_argument(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { - crate::symfony::console::input::input_interface::InputInterface::set_argument( - &mut self.inner, - name, - value, - ) - } - - fn has_argument(&self, name: &str) -> bool { - crate::symfony::console::input::input_interface::InputInterface::has_argument( - &self.inner, - name, - ) - } - - fn get_options(&self) -> indexmap::IndexMap<String, PhpMixed> { - crate::symfony::console::input::input_interface::InputInterface::get_options(&self.inner) - } - - fn get_option(&self, name: &str) -> anyhow::Result<PhpMixed> { - crate::symfony::console::input::input_interface::InputInterface::get_option( - &self.inner, - name, - ) - } - - fn set_option(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { - crate::symfony::console::input::input_interface::InputInterface::set_option( - &mut self.inner, - name, - value, - ) - } - - fn has_option(&self, name: &str) -> bool { - crate::symfony::console::input::input_interface::InputInterface::has_option( - &self.inner, - name, - ) - } - - fn is_interactive(&self) -> bool { - crate::symfony::console::input::input_interface::InputInterface::is_interactive(&self.inner) - } - - fn set_interactive(&mut self, interactive: bool) { - crate::symfony::console::input::input_interface::InputInterface::set_interactive( - &mut self.inner, - interactive, - ) - } - - fn as_streamable( - &self, - ) -> Option< - &dyn crate::symfony::console::input::streamable_input_interface::StreamableInputInterface, - > { - crate::symfony::console::input::input_interface::InputInterface::as_streamable(&self.inner) - } - - fn as_streamable_mut( - &mut self, - ) -> Option< - &mut dyn crate::symfony::console::input::streamable_input_interface::StreamableInputInterface, - >{ - crate::symfony::console::input::input_interface::InputInterface::as_streamable_mut( - &mut self.inner, - ) - } -} - -impl std::fmt::Display for CompletionInput { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut str = String::new(); - let mut last_i: i64 = 0; - for (i, token) in self.tokens.iter().enumerate() { - let i = i as i64; - last_i = i; - str += token; - - if self.current_index == i { - str += "|"; - } - - str += " "; - } - - if self.current_index > last_i { - str += "|"; - } - - write!(f, "{}", shirabe_php_shim::rtrim(&str, None)) - } -} diff --git a/crates/shirabe-external-packages/src/symfony/console/completion/completion_suggestions.rs b/crates/shirabe-external-packages/src/symfony/console/completion/completion_suggestions.rs deleted file mode 100644 index 02938552..00000000 --- a/crates/shirabe-external-packages/src/symfony/console/completion/completion_suggestions.rs +++ /dev/null @@ -1,76 +0,0 @@ -//! ref: composer/vendor/symfony/console/Completion/CompletionSuggestions.php - -use crate::symfony::console::completion::suggestion::Suggestion; -use crate::symfony::console::input::input_option::InputOption; - -/// PHP union type `string|Suggestion` used by `suggestValue`/`suggestValues`. -#[derive(Debug)] -pub enum StringOrSuggestion { - String(String), - Suggestion(Suggestion), -} - -/// Stores all completion suggestions for the current input. -#[derive(Debug)] -pub struct CompletionSuggestions { - value_suggestions: Vec<Suggestion>, - option_suggestions: Vec<std::rc::Rc<InputOption>>, -} - -impl Default for CompletionSuggestions { - fn default() -> Self { - Self::new() - } -} - -impl CompletionSuggestions { - pub fn new() -> Self { - Self { - value_suggestions: vec![], - option_suggestions: vec![], - } - } - - /// Add a suggested value for an input option or argument. - pub fn suggest_value(&mut self, value: StringOrSuggestion) -> &mut Self { - self.value_suggestions.push(match value { - StringOrSuggestion::Suggestion(value) => value, - StringOrSuggestion::String(value) => Suggestion::new(value), - }); - - self - } - - /// Add multiple suggested values at once for an input option or argument. - pub fn suggest_values(&mut self, values: Vec<StringOrSuggestion>) -> &mut Self { - for value in values { - self.suggest_value(value); - } - - self - } - - /// Add a suggestion for an input option name. - pub fn suggest_option(&mut self, option: std::rc::Rc<InputOption>) -> &mut Self { - self.option_suggestions.push(option); - - self - } - - /// Add multiple suggestions for input option names at once. - pub fn suggest_options(&mut self, options: Vec<std::rc::Rc<InputOption>>) -> &mut Self { - for option in options { - self.suggest_option(option); - } - - self - } - - pub fn get_option_suggestions(&self) -> &Vec<std::rc::Rc<InputOption>> { - &self.option_suggestions - } - - pub fn get_value_suggestions(&self) -> &Vec<Suggestion> { - &self.value_suggestions - } -} diff --git a/crates/shirabe-external-packages/src/symfony/console/completion/output.rs b/crates/shirabe-external-packages/src/symfony/console/completion/output.rs deleted file mode 100644 index 6bb0a2e8..00000000 --- a/crates/shirabe-external-packages/src/symfony/console/completion/output.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod bash_completion_output; -pub mod completion_output_interface; - -pub use bash_completion_output::*; -pub use completion_output_interface::*; diff --git a/crates/shirabe-external-packages/src/symfony/console/completion/output/bash_completion_output.rs b/crates/shirabe-external-packages/src/symfony/console/completion/output/bash_completion_output.rs deleted file mode 100644 index a5c70bd5..00000000 --- a/crates/shirabe-external-packages/src/symfony/console/completion/output/bash_completion_output.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! ref: composer/vendor/symfony/console/Completion/Output/BashCompletionOutput.php - -use crate::symfony::console::completion::completion_suggestions::CompletionSuggestions; -use crate::symfony::console::completion::output::completion_output_interface::CompletionOutputInterface; -use crate::symfony::console::output::output_interface::OutputInterface; - -#[derive(Debug)] -pub struct BashCompletionOutput; - -impl CompletionOutputInterface for BashCompletionOutput { - fn write(&self, suggestions: &CompletionSuggestions, output: &dyn OutputInterface) { - let mut values: Vec<String> = suggestions - .get_value_suggestions() - .iter() - .map(|suggestion| suggestion.get_value()) - .collect(); - for option in suggestions.get_option_suggestions() { - values.push(format!("--{}", option.get_name())); - if option.is_negatable() { - values.push(format!("--no-{}", option.get_name())); - } - } - output.writeln(&[values.join("\n")], 0); - } -} diff --git a/crates/shirabe-external-packages/src/symfony/console/completion/output/completion_output_interface.rs b/crates/shirabe-external-packages/src/symfony/console/completion/output/completion_output_interface.rs deleted file mode 100644 index b1a77e56..00000000 --- a/crates/shirabe-external-packages/src/symfony/console/completion/output/completion_output_interface.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! ref: composer/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php - -use crate::symfony::console::completion::completion_suggestions::CompletionSuggestions; -use crate::symfony::console::output::output_interface::OutputInterface; - -/// Transforms the `CompletionSuggestions` object into output readable by the shell completion. -pub trait CompletionOutputInterface: std::fmt::Debug { - fn write(&self, suggestions: &CompletionSuggestions, output: &dyn OutputInterface); -} diff --git a/crates/shirabe-external-packages/src/symfony/console/completion/suggestion.rs b/crates/shirabe-external-packages/src/symfony/console/completion/suggestion.rs deleted file mode 100644 index a7db5c39..00000000 --- a/crates/shirabe-external-packages/src/symfony/console/completion/suggestion.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! ref: composer/vendor/symfony/console/Completion/Suggestion.php - -/// Represents a single suggested value. -#[derive(Debug)] -pub struct Suggestion { - value: String, -} - -impl Suggestion { - pub fn new(value: String) -> Self { - Self { value } - } - - pub fn get_value(&self) -> String { - self.value.clone() - } -} - -impl std::fmt::Display for Suggestion { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.get_value()) - } -} |
