first beta - adding hints for similar commands, now - feature freezing

This commit is contained in:
2025-05-04 02:13:05 +03:00
parent 5a17e916eb
commit 83955aa046
7 changed files with 58 additions and 36 deletions
+2 -8
View File
@@ -11,13 +11,7 @@ from argenta.router import Router
from argenta.orchestrator import Orchestrator
from argenta.command.models import InputCommand
from argenta.app.utils import most_similar_command
while True:
cmd = input(">>> ")
if cmd == "exit":
break
else:
parse_cmd: InputCommand = InputCommand.parse(cmd)
print(f'name: {parse_cmd.get_trigger()}\n'
f'flags: {parse_cmd.get_input_flags().get_flags()}\n')
print(most_similar_command('case', ['case', 'tester', 'poster', 'caser']))
+2 -4
View File
@@ -2,8 +2,7 @@ from rich.console import Console
from argenta.command import Command
from argenta.command.flag.defaults import PredefinedFlags
from argenta.command.flag.models import Flag
from argenta.command.flags.models import Flags
from argenta.command.flags import Flags
from argenta.response import Response
from argenta.router import Router
@@ -13,8 +12,7 @@ work_router: Router = Router(title='Work points:')
console = Console()
@work_router.command(Command('get', 'Get Help', aliases=['help', 'Get_help'], flags=Flags(PredefinedFlags.PORT,
PredefinedFlags.HOST)))
@work_router.command(Command('get', 'Get Help', aliases=['help', 'Get_help'], flags=Flags(PredefinedFlags.PORT, PredefinedFlags.HOST)))
def command_help(response: Response):
print(response.status)
print(response.undefined_flags.get_flags())
+1 -1
View File
@@ -12,7 +12,7 @@ from argenta.orchestrator.argparser.arguments import BooleanArgument
arg_parser = ArgParser(processed_args=[BooleanArgument('repeat')])
app: App = App(dividing_line=DynamicDividingLine(),
autocompleter=AutoCompleter('./mock/.hist'),
repeat_command_groups=False)
repeat_command_groups=False,)
orchestrator: Orchestrator = Orchestrator(arg_parser)
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "argenta"
version = "1.0.0-alpha5"
version = "1.0.0-beta1"
description = "Python library for creating TUI"
authors = [{ name = "kolo", email = "kolo.is.main@gmail.com" }]
requires-python = ">=3.11, <4.0"
+36 -13
View File
@@ -219,22 +219,43 @@ class BaseApp:
self._registered_routers.add_registered_router(system_router)
def _most_similar_command(self, unknown_command: str) -> str | None:
all_commands = self._all_registered_triggers_in_lower if self._ignore_command_register else self._all_registered_triggers_in_default_case
matches: list[str] | list = sorted(cmd for cmd in all_commands if cmd.startswith(unknown_command))
if not matches:
matches: list[str] | list = sorted(cmd for cmd in all_commands if unknown_command.startswith(cmd))
if len(matches) == 1:
return matches[0]
elif len(matches) > 1:
return sorted(matches, key=lambda cmd: len(cmd))[0]
else:
return None
def _setup_default_view(self) -> None:
"""
Private. Sets up default app view
:return: None
"""
if not self._override_system_messages:
self._initial_message = f'\n[bold red]{text2art(self._initial_message, font="tarty1")}\n\n'
self._farewell_message = (f'[bold red]\n{text2art(f"\n{self._farewell_message}\n", font="chanky")}[/bold red]\n'
f'[red i]github.com/koloideal/Argenta[/red i] | [red bold i]made by kolo[/red bold i]\n')
self._description_message_gen = lambda command, description: (f'[bold red]{escape("[" + command + "]")}[/bold red] '
f'[blue dim]*=*=*[/blue dim] '
f'[bold yellow italic]{escape(description)}')
self._invalid_input_flags_handler = lambda raw_command: self._print_func(f'[red bold]Incorrect flag syntax: {escape(raw_command)}')
self._repeated_input_flags_handler = lambda raw_command: self._print_func(f'[red bold]Repeated input flags: {escape(raw_command)}')
self._empty_input_command_handler = lambda: self._print_func('[red bold]Empty input command')
self._unknown_command_handler = lambda command: self._print_func(f"[red bold]Unknown command: {escape(command.get_trigger())}")
self._prompt = '[italic dim bold]What do you want to do?\n'
self._initial_message = f'\n[bold red]{text2art(self._initial_message, font="tarty1")}\n\n'
self._farewell_message = (f'[bold red]\n{text2art(f"\n{self._farewell_message}\n", font="chanky")}[/bold red]\n'
f'[red i]github.com/koloideal/Argenta[/red i] | [red bold i]made by kolo[/red bold i]\n')
self._description_message_gen = lambda command, description: (f'[bold red]{escape("[" + command + "]")}[/bold red] '
f'[blue dim]*=*=*[/blue dim] '
f'[bold yellow italic]{escape(description)}')
self._invalid_input_flags_handler = lambda raw_command: self._print_func(f'[red bold]Incorrect flag syntax: {escape(raw_command)}')
self._repeated_input_flags_handler = lambda raw_command: self._print_func(f'[red bold]Repeated input flags: {escape(raw_command)}')
self._empty_input_command_handler = lambda: self._print_func('[red bold]Empty input command')
def unknown_command_handler(command: InputCommand) -> None:
cmd_trg: str = command.get_trigger()
mst_sim_cmd: str | None = self._most_similar_command(cmd_trg)
first_part_of_text = f"[red]Unknown command:[/red] [blue]{escape(cmd_trg)}[/blue]"
second_part_of_text = ('[red], most similar:[/red] ' + ('[blue]' + mst_sim_cmd + '[/blue]')) if mst_sim_cmd else ''
self._print_func(first_part_of_text + second_part_of_text)
self._unknown_command_handler = unknown_command_handler
def _pre_cycle_setup(self) -> None:
@@ -242,7 +263,6 @@ class BaseApp:
Private. Configures various aspects of the application before the start of the cycle
:return: None
"""
self._setup_default_view()
self._setup_system_router()
for router_entity in self._registered_routers:
@@ -254,6 +274,9 @@ class BaseApp:
self._autocompleter.initial_setup(self._all_registered_triggers_in_lower)
if not self._override_system_messages:
self._setup_default_view()
self._print_func(self._initial_message)
for message in self._messages_on_startup:
@@ -268,7 +291,7 @@ class BaseApp:
class App(BaseApp):
def __init__(self,
prompt: str = '[italic dim bold]What do you want to do?\n',
prompt: str = 'What do you want to do?\n',
initial_message: str = '\nArgenta\n',
farewell_message: str = '\nSee you\n',
exit_command: Command = Command('Q', 'Exit command'),
+5 -5
View File
@@ -139,11 +139,11 @@ class InputCommand(BaseCommand, Generic[InputCommandType]):
for k, _ in enumerate(list_of_tokens):
if _.startswith('-'):
if current_flag_name or len(_) < 2 or len(_[:_.rfind('-')]) > 3:
if len(_) < 2 or len(_[:_.rfind('-')]) > 3:
raise UnprocessedInputFlagException()
current_flag_name = _
else:
if not current_flag_name:
if not current_flag_name or current_flag_value:
raise UnprocessedInputFlagException()
current_flag_value = _
@@ -153,9 +153,9 @@ class InputCommand(BaseCommand, Generic[InputCommandType]):
continue
input_flag = InputFlag(name=current_flag_name[current_flag_name.rfind('-') + 1:],
prefix=cast(Literal['-', '--', '---'],
current_flag_name[:current_flag_name.rfind('-')+1]),
value=current_flag_value)
prefix=cast(Literal['-', '--', '---'],
current_flag_name[:current_flag_name.rfind('-')+1]),
value=current_flag_value)
all_flags = [flag.get_string_entity() for flag in input_flags.get_flags()]
if input_flag.get_string_entity() not in all_flags:
+11 -4
View File
@@ -1,5 +1,7 @@
from typing import Callable, Literal
from inspect import getfullargspec
from typing import Callable, Literal, Type
from inspect import getfullargspec, get_annotations
from rich.console import Console
from argenta.command import Command
from argenta.command.models import InputCommand
from argenta.response import Response, Status
@@ -12,8 +14,7 @@ from argenta.router.exceptions import (RepeatedFlagNameException,
class Router:
def __init__(self,
title: str = None):
def __init__(self, title: str = None):
"""
Public. Directly configures and manages handlers
:param title: the title of the router, displayed when displaying the available commands
@@ -157,6 +158,12 @@ class Router:
elif len(transferred_args) == 0:
raise RequiredArgumentNotPassedException()
arg_annotation: Type = get_annotations(func)[transferred_args[0]]
if not arg_annotation is Response:
Console().print(f'\n\n[b red]WARNING:[/b red] [i]The type of argument passed to the handler is [/i][blue]{Response}[/blue],'
f' [i]but[/i] [bold blue]{arg_annotation}[/bold blue] [i]is specified[/i]', highlight=False)
def set_command_register_ignore(self, _: bool) -> None:
"""