diff --git a/trogon/introspect.py b/trogon/introspect.py index b0855ed..dcc49fe 100644 --- a/trogon/introspect.py +++ b/trogon/introspect.py @@ -41,6 +41,8 @@ class OptionSchema: required: bool = False is_flag: bool = False is_boolean_flag: bool = False + hidden: bool = False + hide_input: bool = False flag_value: Any = "" opts: list = field(default_factory=list) counting: bool = False @@ -134,6 +136,8 @@ def process_command( type=param.type, is_flag=param.is_flag, is_boolean_flag=param.is_bool_flag, + hidden=param.hidden, + hide_input=param.hide_input, flag_value=param.flag_value, counting=param.count, opts=param.opts, diff --git a/trogon/widgets/form.py b/trogon/widgets/form.py index b084c3e..364fc63 100644 --- a/trogon/widgets/form.py +++ b/trogon/widgets/form.py @@ -132,6 +132,9 @@ def compose(self) -> ComposeResult: if options: yield Label(f"Options", classes="command-form-heading") for option in options: + if option.hide_input: + continue + controls = ParameterControls(option, id=option.key) if self.first_control is None: self.first_control = controls @@ -172,6 +175,8 @@ def _form_changed(self) -> None: # For each of the options in the schema for this command, # lets grab the values the user has supplied for them in the form. for option in command.options: + if option.hide_input: + continue parameter_control = self.query_one(f"#{option.key}", ParameterControls) value = parameter_control.get_values() for v in value.values: diff --git a/trogon/widgets/parameter_controls.py b/trogon/widgets/parameter_controls.py index 3ea3b13..77b2f0d 100644 --- a/trogon/widgets/parameter_controls.py +++ b/trogon/widgets/parameter_controls.py @@ -84,9 +84,7 @@ def apply_filter(self, filter_query: str) -> bool: name_contains_query = any( filter_query in name.casefold() for name in self.schema.name ) - help_contains_query = ( - filter_query in help_text.casefold() - ) + help_contains_query = filter_query in help_text.casefold() should_be_visible = name_contains_query or help_contains_query self.display = should_be_visible @@ -115,10 +113,16 @@ def compose(self) -> ComposeResult: help_text = getattr(schema, "help", "") or "" multiple = schema.multiple is_option = isinstance(schema, OptionSchema) + hidden = getattr(schema, "hidden", False) nargs = schema.nargs label = self._make_command_form_control_label( - name, argument_type, is_option, schema.required, multiple=multiple + name=name, + type=argument_type, + is_option=is_option, + hidden=hidden, + is_required=schema.required, + multiple=multiple, ) first_focus_control: Widget | None = ( None # The widget that will be focused when the form is focused. @@ -204,8 +208,14 @@ def make_widget_group(self) -> Iterable[Widget]: multiple = schema.multiple required = schema.required is_option = isinstance(schema, OptionSchema) + hidden = getattr(schema, "hidden", False) label = self._make_command_form_control_label( - name, parameter_type, is_option, required, multiple + name=name, + type=parameter_type, + is_option=is_option, + hidden=hidden, + is_required=required, + multiple=multiple, ) # Get the types of the parameter. We can map these types on to widgets that will be rendered. @@ -220,7 +230,11 @@ def make_widget_group(self) -> Iterable[Widget]: for _type in parameter_types: control_method = self.get_control_method(_type) control_widgets = control_method( - default, label, multiple, schema, schema.key + default=default, + label=label, + multiple=multiple, + schema=schema, + control_id=schema.key, ) yield from control_widgets @@ -341,9 +355,7 @@ def make_text_control( schema: OptionSchema | ArgumentSchema, control_id: str, ) -> Widget: - control = Input( - classes=f"command-form-input {control_id}", - ) + control = Input(classes=f"command-form-input {control_id}") yield control return control @@ -403,17 +415,18 @@ def _make_command_form_control_label( name: str | list[str], type: click.ParamType, is_option: bool, + hidden: bool, is_required: bool, multiple: bool, ) -> Text: if isinstance(name, str): text = Text.from_markup( - f"{name}[dim]{' multiple' if multiple else ''} {type.name}[/] {' [b red]*[/]required' if is_required else ''}" + f"{name}[dim]{' multiple' if multiple else ''} {type.name}[/] {' [b red]*[/]required' if is_required else ''} {'[dim] (hidden)' if hidden else ''}" ) else: names = Text(" / ", style="dim").join([Text(n) for n in name]) text = Text.from_markup( - f"{names}[dim]{' multiple' if multiple else ''} {type.name}[/] {' [b red]*[/]required' if is_required else ''}" + f"{names}[dim]{' multiple' if multiple else ''} {type.name}[/] {' [b red]*[/]required' if is_required else ''} {'[dim] (hidden)' if hidden else ''}" ) if isinstance(type, (click.IntRange, click.FloatRange)):