From f9fb3522ee99e7b2db05f8f5d5a4ace0b326a0d0 Mon Sep 17 00:00:00 2001 From: Pol Febrer Date: Wed, 2 Apr 2025 19:09:39 +0200 Subject: [PATCH] Added Rich formatting to CLIs --- src/sisl/_core/geometry.py | 3 ++- src/sisl/_core/grid.py | 3 ++- src/sisl/_lib/_argparse.py | 11 +++++++++++ src/sisl/utils/_sisl_cmd.py | 4 +++- src/sisl_toolbox/cli/_cli.py | 8 ++++++-- src/sisl_toolbox/siesta/atom/_atom.py | 6 +++--- src/sisl_toolbox/transiesta/poisson/fftpoisson_fix.py | 6 +++--- 7 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 src/sisl/_lib/_argparse.py diff --git a/src/sisl/_core/geometry.py b/src/sisl/_core/geometry.py index 57808e6532..a14dd4e210 100644 --- a/src/sisl/_core/geometry.py +++ b/src/sisl/_core/geometry.py @@ -45,6 +45,7 @@ list_index_le, ) from sisl._internal import set_module +from sisl._lib._argparse import SislHelpFormatter from sisl._math_small import cross3, is_ascending, xyz_to_spherical_cos_phi from sisl._namedindex import NamedIndex from sisl.messages import SislError, deprecate_argument, deprecation, info, warn @@ -4783,7 +4784,7 @@ def sgeom(geometry=None, argv=None, ret_geometry=False): p = argparse.ArgumentParser( exe, - formatter_class=argparse.RawDescriptionHelpFormatter, + formatter_class=SislHelpFormatter, description=description, ) diff --git a/src/sisl/_core/grid.py b/src/sisl/_core/grid.py index a9b75416b5..34c8d47685 100644 --- a/src/sisl/_core/grid.py +++ b/src/sisl/_core/grid.py @@ -20,6 +20,7 @@ from sisl._dispatcher import AbstractDispatch, ClassDispatcher, TypeDispatcher from sisl._help import dtype_complex_to_real, wrap_filterwarnings from sisl._internal import set_module +from sisl._lib._argparse import SislHelpFormatter from sisl.messages import deprecate_argument, deprecation from sisl.shape import Shape from sisl.utils import ( @@ -1747,7 +1748,7 @@ def sgrid(grid=None, argv=None, ret_grid=False): p = argparse.ArgumentParser( exe, - formatter_class=argparse.RawDescriptionHelpFormatter, + formatter_class=SislHelpFormatter, description=description, ) diff --git a/src/sisl/_lib/_argparse.py b/src/sisl/_lib/_argparse.py new file mode 100644 index 0000000000..110efed924 --- /dev/null +++ b/src/sisl/_lib/_argparse.py @@ -0,0 +1,11 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. +try: + from rich_argparse import RichHelpFormatter + + SislHelpFormatter = RichHelpFormatter +except ImportError: + import argparse + + SislHelpFormatter = argparse.RawDescriptionHelpFormatter diff --git a/src/sisl/utils/_sisl_cmd.py b/src/sisl/utils/_sisl_cmd.py index fa42df8a09..893c9c45d2 100644 --- a/src/sisl/utils/_sisl_cmd.py +++ b/src/sisl/utils/_sisl_cmd.py @@ -9,6 +9,8 @@ """ import argparse +from sisl._lib._argparse import SislHelpFormatter + __all__ = ["sisl_cmd"] @@ -99,7 +101,7 @@ def sisl_cmd(argv=None, sile=None): p = argparse.ArgumentParser( exe, - formatter_class=argparse.RawDescriptionHelpFormatter, + formatter_class=SislHelpFormatter, description=description, conflict_handler="resolve", ) diff --git a/src/sisl_toolbox/cli/_cli.py b/src/sisl_toolbox/cli/_cli.py index f5345872c6..a6984cf39a 100644 --- a/src/sisl_toolbox/cli/_cli.py +++ b/src/sisl_toolbox/cli/_cli.py @@ -14,6 +14,8 @@ from collections.abc import Callable from pathlib import Path +from sisl._lib._argparse import SislHelpFormatter + class SToolBoxCLI: """Run the CLI `stoolbox`""" @@ -47,7 +49,9 @@ def __call__(self, argv=None): # Create command-line cmd = Path(sys.argv[0]) p = argparse.ArgumentParser( - f"{cmd.name}", description="Specific toolboxes to aid sisl users" + f"{cmd.name}", + description="Specific toolboxes to aid sisl users", + formatter_class=SislHelpFormatter, ) info = { @@ -64,7 +68,7 @@ def __call__(self, argv=None): subp = p.add_subparsers(**info) for cmd in self._cmds: - cmd(subp) + cmd(subp, parser_kwargs=dict(formatter_class=p.formatter_class)) args = p.parse_args(argv) args.runner(args) diff --git a/src/sisl_toolbox/siesta/atom/_atom.py b/src/sisl_toolbox/siesta/atom/_atom.py index b886c5e290..807a32b4be 100644 --- a/src/sisl_toolbox/siesta/atom/_atom.py +++ b/src/sisl_toolbox/siesta/atom/_atom.py @@ -803,7 +803,7 @@ def next_rc(ir, ic, nrows, ncols): return fig, axs -def atom_plot_cli(subp=None): +def atom_plot_cli(subp=None, parser_kwargs={}): """Run plotting command for the output of atom""" is_sub = not subp is None @@ -812,11 +812,11 @@ def atom_plot_cli(subp=None): if is_sub: global _script _script = f"{_script} atom-plot" - p = subp.add_parser("atom-plot", description=title, help=title) + p = subp.add_parser("atom-plot", description=title, help=title, **parser_kwargs) else: import argparse - p = argparse.ArgumentParser(title) + p = argparse.ArgumentParser(title, **parser_kwargs) p.add_argument( "--plot", diff --git a/src/sisl_toolbox/transiesta/poisson/fftpoisson_fix.py b/src/sisl_toolbox/transiesta/poisson/fftpoisson_fix.py index 04600cbd3a..8aefad3fff 100644 --- a/src/sisl_toolbox/transiesta/poisson/fftpoisson_fix.py +++ b/src/sisl_toolbox/transiesta/poisson/fftpoisson_fix.py @@ -344,16 +344,16 @@ def sl2idx(grid, sl): return grid -def fftpoisson_fix_cli(subp=None): +def fftpoisson_fix_cli(subp=None, parser_kwargs={}): is_sub = not subp is None title = "FFT Poisson corrections for TranSiesta calculations for arbitrary number of electrodes." if is_sub: global _script _script = f"{_script} ts-fft" - p = subp.add_parser("ts-fft", description=title, help=title) + p = subp.add_parser("ts-fft", description=title, help=title, **parser_kwargs) else: - p = argp.ArgumentParser(title) + p = argp.ArgumentParser(title, **parser_kwargs) tuning = p.add_argument_group( "tuning", "Tuning fine details of the Poisson calculation."