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.orchestrator import Orchestrator
from argenta.command.models import InputCommand from argenta.command.models import InputCommand
from argenta.app.utils import most_similar_command
while True: print(most_similar_command('case', ['case', 'tester', 'poster', 'caser']))
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')
+2 -4
View File
@@ -2,8 +2,7 @@ from rich.console import Console
from argenta.command import Command from argenta.command import Command
from argenta.command.flag.defaults import PredefinedFlags from argenta.command.flag.defaults import PredefinedFlags
from argenta.command.flag.models import Flag from argenta.command.flags import Flags
from argenta.command.flags.models import Flags
from argenta.response import Response from argenta.response import Response
from argenta.router import Router from argenta.router import Router
@@ -13,8 +12,7 @@ work_router: Router = Router(title='Work points:')
console = Console() console = Console()
@work_router.command(Command('get', 'Get Help', aliases=['help', 'Get_help'], flags=Flags(PredefinedFlags.PORT, @work_router.command(Command('get', 'Get Help', aliases=['help', 'Get_help'], flags=Flags(PredefinedFlags.PORT, PredefinedFlags.HOST)))
PredefinedFlags.HOST)))
def command_help(response: Response): def command_help(response: Response):
print(response.status) print(response.status)
print(response.undefined_flags.get_flags()) 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')]) arg_parser = ArgParser(processed_args=[BooleanArgument('repeat')])
app: App = App(dividing_line=DynamicDividingLine(), app: App = App(dividing_line=DynamicDividingLine(),
autocompleter=AutoCompleter('./mock/.hist'), autocompleter=AutoCompleter('./mock/.hist'),
repeat_command_groups=False) repeat_command_groups=False,)
orchestrator: Orchestrator = Orchestrator(arg_parser) orchestrator: Orchestrator = Orchestrator(arg_parser)
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "argenta" name = "argenta"
version = "1.0.0-alpha5" version = "1.0.0-beta1"
description = "Python library for creating TUI" description = "Python library for creating TUI"
authors = [{ name = "kolo", email = "kolo.is.main@gmail.com" }] authors = [{ name = "kolo", email = "kolo.is.main@gmail.com" }]
requires-python = ">=3.11, <4.0" requires-python = ">=3.11, <4.0"
+27 -4
View File
@@ -219,12 +219,25 @@ class BaseApp:
self._registered_routers.add_registered_router(system_router) 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: def _setup_default_view(self) -> None:
""" """
Private. Sets up default app view Private. Sets up default app view
:return: None :return: None
""" """
if not self._override_system_messages: 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._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' 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') f'[red i]github.com/koloideal/Argenta[/red i] | [red bold i]made by kolo[/red bold i]\n')
@@ -234,7 +247,15 @@ class BaseApp:
self._invalid_input_flags_handler = lambda raw_command: self._print_func(f'[red bold]Incorrect flag syntax: {escape(raw_command)}') 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._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._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())}")
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: 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 Private. Configures various aspects of the application before the start of the cycle
:return: None :return: None
""" """
self._setup_default_view()
self._setup_system_router() self._setup_system_router()
for router_entity in self._registered_routers: for router_entity in self._registered_routers:
@@ -254,6 +274,9 @@ class BaseApp:
self._autocompleter.initial_setup(self._all_registered_triggers_in_lower) 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) self._print_func(self._initial_message)
for message in self._messages_on_startup: for message in self._messages_on_startup:
@@ -268,7 +291,7 @@ class BaseApp:
class App(BaseApp): class App(BaseApp):
def __init__(self, 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', initial_message: str = '\nArgenta\n',
farewell_message: str = '\nSee you\n', farewell_message: str = '\nSee you\n',
exit_command: Command = Command('Q', 'Exit command'), exit_command: Command = Command('Q', 'Exit command'),
+2 -2
View File
@@ -139,11 +139,11 @@ class InputCommand(BaseCommand, Generic[InputCommandType]):
for k, _ in enumerate(list_of_tokens): for k, _ in enumerate(list_of_tokens):
if _.startswith('-'): if _.startswith('-'):
if current_flag_name or len(_) < 2 or len(_[:_.rfind('-')]) > 3: if len(_) < 2 or len(_[:_.rfind('-')]) > 3:
raise UnprocessedInputFlagException() raise UnprocessedInputFlagException()
current_flag_name = _ current_flag_name = _
else: else:
if not current_flag_name: if not current_flag_name or current_flag_value:
raise UnprocessedInputFlagException() raise UnprocessedInputFlagException()
current_flag_value = _ current_flag_value = _
+11 -4
View File
@@ -1,5 +1,7 @@
from typing import Callable, Literal from typing import Callable, Literal, Type
from inspect import getfullargspec from inspect import getfullargspec, get_annotations
from rich.console import Console
from argenta.command import Command from argenta.command import Command
from argenta.command.models import InputCommand from argenta.command.models import InputCommand
from argenta.response import Response, Status from argenta.response import Response, Status
@@ -12,8 +14,7 @@ from argenta.router.exceptions import (RepeatedFlagNameException,
class Router: class Router:
def __init__(self, def __init__(self, title: str = None):
title: str = None):
""" """
Public. Directly configures and manages handlers Public. Directly configures and manages handlers
:param title: the title of the router, displayed when displaying the available commands :param title: the title of the router, displayed when displaying the available commands
@@ -157,6 +158,12 @@ class Router:
elif len(transferred_args) == 0: elif len(transferred_args) == 0:
raise RequiredArgumentNotPassedException() 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: def set_command_register_ignore(self, _: bool) -> None:
""" """