diff --git a/metrics/handlers.py b/metrics/handlers.py
index 996257c..4f42044 100644
--- a/metrics/handlers.py
+++ b/metrics/handlers.py
@@ -12,7 +12,7 @@ from argenta.response import Response
from argenta.router import Router
from .benchmarks.core.models import BenchmarkGroupResult
from .benchmarks.entity import benchmarks as registered_benchmarks
-from .services.report_generator import ReportGenerator
+from .services.report_table_generator import ReportTableGenerator
from .services.system_info_reader import get_system_info
from .services.diagram_generator import DiagramGenerator
from .services.release_generator import ReleaseGenerator
@@ -34,7 +34,7 @@ POSITIVE_INTEGER_PATTERN = re.compile(r"^[1-9]\d*$")
)
)
def all_print_handler(response: Response) -> None:
- report_generator = ReportGenerator(get_system_info())
+ report_generator = ReportTableGenerator(get_system_info())
without_system_info = response.input_flags.get_flag_by_name("without-system-info", with_status=ValidationStatus.VALID)
if not without_system_info:
@@ -92,7 +92,7 @@ def run_type_handler(response: Response) -> None:
console.print(f" • {t}")
return
- report_generator = ReportGenerator(get_system_info())
+ report_generator = ReportTableGenerator(get_system_info())
without_system_info = response.input_flags.get_flag_by_name("without-system-info", with_status=ValidationStatus.VALID)
if not without_system_info:
diff --git a/metrics/services/__init__.py b/metrics/services/__init__.py
index fd0f6e0..ee3ba46 100644
--- a/metrics/services/__init__.py
+++ b/metrics/services/__init__.py
@@ -1,6 +1,6 @@
from .diagram_generator import DiagramGenerator
-from .report_generator import ReportGenerator
+from .report_table_generator import ReportTableGenerator
from .system_info_reader import get_system_info
from .release_generator import ReleaseGenerator
-__all__ = ["DiagramGenerator", "ReportGenerator", "get_system_info", "ReleaseGenerator"]
+__all__ = ["DiagramGenerator", "ReportTableGenerator", "get_system_info", "ReleaseGenerator"]
diff --git a/metrics/services/report_generator.py b/metrics/services/report_table_generator.py
similarity index 99%
rename from metrics/services/report_generator.py
rename to metrics/services/report_table_generator.py
index 5c383fb..658020d 100644
--- a/metrics/services/report_generator.py
+++ b/metrics/services/report_table_generator.py
@@ -6,7 +6,7 @@ from ..benchmarks.core.models import BenchmarkGroupResult
from metrics.services.system_info_reader import SystemInfo
-class ReportGenerator:
+class ReportTableGenerator:
def __init__(self, system_info: SystemInfo):
self.system_info = system_info
self._cached_benchmark_tables: dict[int, Table] = {}
diff --git a/mock/local_test.py b/mock/local_test.py
index ddfa8c5..f912443 100644
--- a/mock/local_test.py
+++ b/mock/local_test.py
@@ -1,4 +1,22 @@
-from argenta import App
+from prompt_toolkit.shortcuts import checkboxlist_dialog
+from prompt_toolkit.styles import Style
-app = App()
-app._autocompleter.initial_setup(set())
\ No newline at end of file
+results = checkboxlist_dialog(
+ title="CheckboxList dialog",
+ text="What would you like in your breakfast ?",
+ values=[
+ ("eggs", "Eggs"),
+ ("bacon", "Bacon"),
+ ("croissants", "20 Croissants"),
+ ("daily", "The breakfast of the day")
+ ],
+ style=Style.from_dict({
+ 'dialog': 'bg:#cdbbb3',
+ 'button': 'bg:#bf99a4',
+ 'checkbox': '#e8612c',
+ 'dialog.body': 'bg:#a9cfd0',
+ 'dialog shadow': 'bg:#c98982',
+ 'frame.label': '#fcaca3',
+ 'dialog.body label': '#fd8bb6',
+ })
+).run()
\ No newline at end of file
diff --git a/mock/mock_app/main.py b/mock/mock_app/main.py
index 1305567..745baf9 100644
--- a/mock/mock_app/main.py
+++ b/mock/mock_app/main.py
@@ -1,10 +1,13 @@
+from prompt_toolkit import HTML
+
from argenta import App, Orchestrator
-from argenta.app import PredefinedMessages
+from argenta.app import PredefinedMessages, StaticDividingLine, AutoCompleter
from argenta.app.dividing_line.models import DynamicDividingLine
from mock.mock_app.routers import work_router
app: App = App(
- dividing_line=DynamicDividingLine('^'),
+ dividing_line=StaticDividingLine('~'),
+ prompt=HTML('\n')
)
orchestrator: Orchestrator = Orchestrator()
diff --git a/mock/mock_app/routers.py b/mock/mock_app/routers.py
index a6d4123..3aafb75 100644
--- a/mock/mock_app/routers.py
+++ b/mock/mock_app/routers.py
@@ -1,7 +1,8 @@
from argenta import Command, Response, Router
from argenta.command import Flag, Flags
+from argenta.command.flag import ValidationStatus
-work_router: Router = Router(title="Base points:", disable_redirect_stdout=True)
+work_router: Router = Router(title="Base points:")
@work_router.command(
@@ -13,5 +14,5 @@ work_router: Router = Router(title="Base points:", disable_redirect_stdout=True)
description="Hello, world!")
)
def command_help(response: Response):
- c = input("Enter your name: ")
- print(f"Hello, {c}!")
+ n = input('sfgdheth')
+ print(f"Hello,{n} {response.input_flags.get_flag_by_name('test', with_status=ValidationStatus.VALID)}")
diff --git a/src/argenta/app/autocompleter/entity.py b/src/argenta/app/autocompleter/entity.py
index 6c92982..bdddf0c 100644
--- a/src/argenta/app/autocompleter/entity.py
+++ b/src/argenta/app/autocompleter/entity.py
@@ -6,6 +6,7 @@ from typing import Callable, Iterable
from prompt_toolkit import PromptSession, HTML
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.completion import Completer, Completion, CompleteEvent, ThreadedCompleter
+from prompt_toolkit.cursor_shapes import CursorShape
from prompt_toolkit.document import Document
from prompt_toolkit.formatted_text import StyleAndTextTuples
from prompt_toolkit.history import History, ThreadedHistory, FileHistory, InMemoryHistory
@@ -136,5 +137,6 @@ class AutoCompleter:
if self._session is None:
raise RuntimeError("Call initial_setup() before using prompt()")
return self._session.prompt(
- HTML(prompt_text) if isinstance(prompt_text, str) else prompt_text
+ HTML(prompt_text) if isinstance(prompt_text, str) else prompt_text,
+ cursor=CursorShape.BLINKING_BEAM
)
\ No newline at end of file
diff --git a/src/argenta/app/models.py b/src/argenta/app/models.py
index ec1b4c4..f4169bd 100644
--- a/src/argenta/app/models.py
+++ b/src/argenta/app/models.py
@@ -163,45 +163,23 @@ class BaseApp:
:param text: framed text
:return: None
"""
- if isinstance(self._dividing_line, DynamicDividingLine):
- clear_text = _ANSI_ESCAPE_RE.sub("", text)
- max_length_line = max([len(line) for line in clear_text.split("\n")])
- max_length_line = (
- max_length_line
- if 10 <= max_length_line <= 100
- else 100
- if max_length_line > 100
- else 10
- )
-
- self._print_func(
- self._dividing_line.get_full_dynamic_line(
- length=max_length_line, is_override=self._override_system_messages
+ match self._dividing_line:
+ case (StaticDividingLine() as dividing_line) | (DynamicDividingLine() as dividing_line):
+ self._print_func(
+ StaticDividingLine(dividing_line.get_unit_part()).get_full_static_line(
+ is_override=self._override_system_messages
+ )
)
- )
- print(text.strip("\n"))
- self._print_func(
- self._dividing_line.get_full_dynamic_line(
- length=max_length_line, is_override=self._override_system_messages
+ print(text.strip("\n"))
+ self._print_func(
+ StaticDividingLine(dividing_line.get_unit_part()).get_full_static_line(
+ is_override=self._override_system_messages
+ )
)
- )
-
- elif isinstance(self._dividing_line, StaticDividingLine):
- self._print_func(
- self._dividing_line.get_full_static_line(
- is_override=self._override_system_messages
- )
- )
- print(text.strip("\n"))
- self._print_func(
- self._dividing_line.get_full_static_line(
- is_override=self._override_system_messages
- )
- )
- elif self._dividing_line is None:
- print('\n' + text.strip("\n") + '\n')
- else:
- raise NotImplementedError
+ case None:
+ print('\n' + text.strip("\n") + '\n')
+ case _:
+ raise NotImplementedError(f'Dividing line with type {self._dividing_line} is not implemented')
def _is_exit_command(self, command: InputCommand) -> bool:
"""
@@ -307,7 +285,8 @@ class BaseApp:
Private. Sets up default app view
:return: None
"""
- self._prompt = f"\n{self._prompt}"
+ if isinstance(self._prompt, str):
+ self._prompt = f"\n{self._prompt}"
self._initial_message = (
"\n" + f"[bold red]{text2art(self._initial_message, font='tarty1')}"
)
@@ -354,15 +333,11 @@ class BaseApp:
"""
self._setup_system_router()
self._validate_routers_for_collisions()
-
self._autocompleter.initial_setup(self.registered_routers.get_triggers())
self._print_func(self._initial_message)
+ self._print_func('\n'.join(self._messages_on_startup))
- for message in self._messages_on_startup:
- self._print_func(message)
- if self._messages_on_startup:
- print("\n")
if not self._repeat_command_groups_printing:
self._print_command_group_description()
@@ -372,13 +347,48 @@ class BaseApp:
if not processing_router:
raise RuntimeError(f"Router for '{input_command.trigger}' not found. Panic!")
- if processing_router.disable_redirect_stdout:
- processing_router.finds_appropriate_handler(input_command)
- else:
- stdout_result = self._capture_stdout(
- lambda: processing_router.finds_appropriate_handler(input_command)
- )
- self._print_framed_text(stdout_result)
+ match (self._dividing_line, processing_router.disable_redirect_stdout):
+ case (DynamicDividingLine(), False):
+ stdout_result = self._capture_stdout(
+ lambda: processing_router.finds_appropriate_handler(input_command)
+ )
+ clear_text = _ANSI_ESCAPE_RE.sub("", stdout_result)
+ max_length_line = max([len(line) for line in clear_text.split("\n")])
+ max_length_line = (
+ max_length_line
+ if 10 <= max_length_line <= 100
+ else 100
+ if max_length_line > 100
+ else 10
+ )
+
+ self._print_func(
+ self._dividing_line.get_full_dynamic_line(
+ length=max_length_line, is_override=self._override_system_messages
+ )
+ )
+ print(clear_text.strip("\n"))
+ self._print_func(
+ self._dividing_line.get_full_dynamic_line(
+ length=max_length_line, is_override=self._override_system_messages
+ )
+ )
+ case (StaticDividingLine() as dividing_line, bool()) | (DynamicDividingLine() as dividing_line, True):
+ self._print_func(
+ StaticDividingLine(dividing_line.get_unit_part()).get_full_static_line(
+ is_override=self._override_system_messages
+ )
+ )
+ processing_router.finds_appropriate_handler(input_command)
+ self._print_func(
+ StaticDividingLine(dividing_line.get_unit_part()).get_full_static_line(
+ is_override=self._override_system_messages
+ )
+ )
+ case (None, bool()):
+ processing_router.finds_appropriate_handler(input_command)
+ case _:
+ raise NotImplementedError(f'Dividing line with type {self._dividing_line} is not implemented')
AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine
diff --git a/src/argenta/command/models.py b/src/argenta/command/models.py
index 7996c22..7f56c19 100644
--- a/src/argenta/command/models.py
+++ b/src/argenta/command/models.py
@@ -90,7 +90,14 @@ class InputCommand:
:param raw_command: raw input command
:return: model of the input command, after parsing as InputCommand
"""
- tokens = shlex.split(raw_command)
+ lexer = shlex.shlex(raw_command, posix=True)
+ lexer.whitespace_split = True
+ lexer.commenters = ""
+
+ try:
+ tokens = list(lexer)
+ except ValueError as e:
+ raise UnprocessedInputFlagException from e
if not tokens:
raise EmptyInputCommandException