diff --git a/kosmorro/__main__.py b/kosmorro/__main__.py index ccc24b8..13c8eb0 100644 --- a/kosmorro/__main__.py +++ b/kosmorro/__main__.py @@ -17,7 +17,7 @@ # along with this program. If not, see . import argparse -import datetime +import argcomplete import sys import os.path @@ -27,8 +27,6 @@ from kosmorrolib import Position, get_ephemerides, get_events, get_moon_phase from kosmorrolib.exceptions import OutOfRangeDateError from datetime import date -from pytz import timezone - from . import dumper, environment, debug from .date import parse_date from .geolocation import get_position @@ -57,6 +55,9 @@ def run(): set_colors_activated(args.colors) + if args.completion is not None: + return 0 if output_completion(args.completion) else 1 + if args.special_action is not None: return 0 if args.special_action() else 1 @@ -352,8 +353,28 @@ def get_args(output_formats: [str]): help=_("Show debugging messages"), ) + argcomplete.autocomplete(parser) + + parser.add_argument( + "--completion", + type=str, + help=_("Print a script allowing completion for your shell"), + ) + return parser.parse_args() +def output_completion(shell: str) -> bool: + shellcode = argcomplete.shellcode([sys.argv[0]], shell=shell) + if shellcode == "": + print_stderr( + colored(_("No completion script available for this shell."), "red") + ) + return False + + print(shellcode) + return True + + def main(): sys.exit(run()) diff --git a/kosmorro/locales/messages.pot b/kosmorro/locales/messages.pot index 22df864..4f56d1a 100644 --- a/kosmorro/locales/messages.pot +++ b/kosmorro/locales/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2025-09-22 17:24+0200\n" +"POT-Creation-Date: 2025-10-05 10:30+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,80 +17,80 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.17.0\n" -#: kosmorro/__main__.py:89 +#: kosmorro/__main__.py:90 msgid "" "Output file will not contain the ephemerides, because you didn't provide " "the observation coordinates." msgstr "" -#: kosmorro/__main__.py:107 +#: kosmorro/__main__.py:108 msgid "" "Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, " "which is more standard." msgstr "" -#: kosmorro/__main__.py:116 +#: kosmorro/__main__.py:117 #, python-brace-format msgid "Unknown timezone: {timezone}" msgstr "" -#: kosmorro/__main__.py:159 +#: kosmorro/__main__.py:160 #, python-brace-format msgid "The file could not be saved in \"{path}\": {error}" msgstr "" -#: kosmorro/__main__.py:173 +#: kosmorro/__main__.py:174 msgid "Please provide a file path to export in this format (--output)." msgstr "" -#: kosmorro/__main__.py:205 +#: kosmorro/__main__.py:206 #, python-brace-format msgid "Moon phase can only be computed between {min_date} and {max_date}" msgstr "" -#: kosmorro/__main__.py:252 +#: kosmorro/__main__.py:253 #, python-brace-format msgid "Running on Python {python_version} with Kosmorrolib v{kosmorrolib_version}" msgstr "" -#: kosmorro/__main__.py:265 +#: kosmorro/__main__.py:266 msgid "" "Compute the ephemerides and the events for a given date and a given " "position on Earth." msgstr "" -#: kosmorro/__main__.py:268 +#: kosmorro/__main__.py:269 msgid "" "By default, only the events will be computed for today.\n" "To compute also the ephemerides, latitude and longitude arguments are " "needed." msgstr "" -#: kosmorro/__main__.py:280 +#: kosmorro/__main__.py:281 msgid "Show the program version" msgstr "" -#: kosmorro/__main__.py:289 +#: kosmorro/__main__.py:290 msgid "" "The format to output the information to. If not provided, the output " "format will be inferred from the file extension of the output file." msgstr "" -#: kosmorro/__main__.py:299 +#: kosmorro/__main__.py:300 #, python-brace-format msgid "" "The observer's position on Earth, in the \"{latitude},{longitude}\" " "format. Can also be set in the KOSMORRO_POSITION environment variable." msgstr "" -#: kosmorro/__main__.py:309 +#: kosmorro/__main__.py:310 msgid "" "The date for which the ephemerides must be calculated. Can be in the " "YYYY-MM-DD format or an interval in the \"[+-]YyMmDd\" format (with Y, M," " and D numbers). Defaults to current date." msgstr "" -#: kosmorro/__main__.py:320 +#: kosmorro/__main__.py:321 msgid "" "The timezone to use to display the hours. It can be either a number (e.g." " 1 for UTC+1) or a timezone name (e.g. Europe/Paris). See " @@ -98,24 +98,32 @@ msgid "" " timezone. Can also be set in the TZ environment variable." msgstr "" -#: kosmorro/__main__.py:329 +#: kosmorro/__main__.py:330 msgid "Disable the colors in the console." msgstr "" -#: kosmorro/__main__.py:337 +#: kosmorro/__main__.py:338 msgid "A file to export the output to. If not given, the standard output is used." msgstr "" -#: kosmorro/__main__.py:345 +#: kosmorro/__main__.py:346 msgid "" "Do not generate a graph to represent the rise and set times in the LaTeX " "file." msgstr "" -#: kosmorro/__main__.py:352 +#: kosmorro/__main__.py:353 msgid "Show debugging messages" msgstr "" +#: kosmorro/__main__.py:361 +msgid "Print a script allowing completion for your shell" +msgstr "" + +#: kosmorro/__main__.py:371 +msgid "No completion script available for this shell." +msgstr "" + #: kosmorro/date.py:17 #, python-brace-format msgid "The date {date} is not valid: {error}" diff --git a/manpage/kosmorro.1.md b/manpage/kosmorro.1.md index 3f25024..3a5db54 100644 --- a/manpage/kosmorro.1.md +++ b/manpage/kosmorro.1.md @@ -39,6 +39,9 @@ `--no-graph` present the ephemerides in a table instead of a graph; LaTeX output format only +`--completion [SHELL]` + generate completion scripts for the specified shell (bash, zsh, fish, powershell) + ## ENVIRONMENT VARIABLES The environment variable listed below may be used instead of the options. diff --git a/poetry.lock b/poetry.lock index 6ceb6e5..4e38c8d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,19 @@ -# This file is automatically @generated by Poetry 2.2.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. + +[[package]] +name = "argcomplete" +version = "3.6.2" +description = "Bash tab completion for argparse" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "argcomplete-3.6.2-py3-none-any.whl", hash = "sha256:65b3133a29ad53fb42c48cf5114752c7ab66c1c38544fdf6460f450c09b42591"}, + {file = "argcomplete-3.6.2.tar.gz", hash = "sha256:d0519b1bc867f5f4f4713c41ad0aba73a4a5f007449716b16f385f2166dc6adf"}, +] + +[package.extras] +test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] [[package]] name = "aurornis" @@ -541,4 +556,4 @@ tests = ["pytest", "pytest-cov"] [metadata] lock-version = "2.1" python-versions = "^3.12" -content-hash = "12bf9cdda9cfaf9616bf3d899450e105991f788267601a41a79fed1b5cbd73a9" +content-hash = "a020653a41707f2ae483abe05ce06b55d09c8a3ddbe4b4c4fc60c9ccd34380ed" diff --git a/pyproject.toml b/pyproject.toml index 9ccdc97..4347210 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,6 +23,7 @@ python-dateutil = "^2.8" Babel = "^2.9" openlocationcode = "^1.0" pytz = "^2025.2" +argcomplete = "^3.6.2" [tool.poetry.group.dev.dependencies] black = "^24.4" diff --git a/tests/completion.py b/tests/completion.py new file mode 100644 index 0000000..383c88f --- /dev/null +++ b/tests/completion.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +from .utils import execute + + +def test_completion_script_is_generated(): + for shell in ["bash", "zsh", "fish", "powershell"]: + result = execute(["kosmorro", f"--completion={shell}"]) + + assert result.successful + assert result.stdout != "" + assert result.stderr == "" + + +def test_completion_script_returns_error_for_unsupported_shell(): + result = execute(["kosmorro", "--completion=deuchshell"]) + + assert not result.successful + assert result.stderr == "No completion script available for this shell.\n" + assert result.stdout == "" diff --git a/tests/general.py b/tests/general.py index d12ace7..6716f7b 100644 --- a/tests/general.py +++ b/tests/general.py @@ -42,6 +42,7 @@ def test_help_message(): == """usage: kosmorro [-h] [--version] [--format {txt,json,tex}] [--position POSITION] [--date DATE] [--timezone TIMEZONE] [--no-colors] [--output OUTPUT] [--no-graph] [--debug] + [--completion COMPLETION] Compute the ephemerides and the events for a given date and a given position on Earth. @@ -74,6 +75,8 @@ options: --no-graph Do not generate a graph to represent the rise and set times in the LaTeX file. --debug Show debugging messages + --completion COMPLETION + Print a script allowing completion for your shell By default, only the events will be computed for today. To compute also the ephemerides, latitude and longitude arguments are needed. @@ -85,6 +88,7 @@ ephemerides, latitude and longitude arguments are needed. == """usage: kosmorro [-h] [--version] [--format {txt,json,tex}] [--position POSITION] [--date DATE] [--timezone TIMEZONE] [--no-colors] [--output OUTPUT] [--no-graph] [--debug] + [--completion COMPLETION] Compute the ephemerides and the events for a given date and a given position on Earth. @@ -116,6 +120,8 @@ options: --no-graph Do not generate a graph to represent the rise and set times in the LaTeX file. --debug Show debugging messages + --completion COMPLETION + Print a script allowing completion for your shell By default, only the events will be computed for today. To compute also the ephemerides, latitude and longitude arguments are needed.