Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add better bash_completion with the argcomplete package #672

Merged
merged 1 commit into from
Feb 20, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 52 additions & 5 deletions fusesoc/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# PYTHON_ARGCOMPLETE_OK
# Copyright FuseSoC contributors
# Licensed under the 2-Clause BSD License, see LICENSE for details.
# SPDX-License-Identifier: BSD-2-Clause
@@ -11,6 +12,8 @@
import warnings
from pathlib import Path

import argcomplete

try:
from fusesoc.version import version as __version__
except ImportError:
@@ -397,6 +400,41 @@ def update(fs, args):
fs.update_libraries(args.libraries)


class CoreCompleter:
def __call__(self, parsed_args, **kwargs):
config = Config(parsed_args.config)
args_to_config(parsed_args, config)
fs = Fusesoc(config)
cores = fs.get_cores()
return cores


class ToolCompleter:
def __call__(self, parsed_args, **kwargs):
from edalize.edatool import get_edatool, walk_tool_packages

_tp = list(walk_tool_packages())
tools = []
for tool_name in _tp:
try:
tool_class = get_edatool(tool_name)
if tool_class.get_doc(0)["description"]:
tools += [tool_name]
# Ignore any misbehaving backends
except Exception:
pass
return tools


class GenCompleter:
def __call__(self, parsed_args, **kwargs):
config = Config(parsed_args.config)
args_to_config(parsed_args, config)
fs = Fusesoc(config)
cores = fs.get_generators()
return cores


def get_parser():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
@@ -448,7 +486,9 @@ def get_parser():
parser_core_show = core_subparsers.add_parser(
"show", help="Show information about a core"
)
parser_core_show.add_argument("core", help="Name of the core to show")
parser_core_show.add_argument(
"core", help="Name of the core to show"
).completer = CoreCompleter()
parser_core_show.set_defaults(func=core_info)

# tool subparser
@@ -470,7 +510,7 @@ def get_parser():
parser_core_info = subparsers.add_parser(
"core-info", help="Display details about a core"
)
parser_core_info.add_argument("core")
parser_core_info.add_argument("core").completer = CoreCompleter()
parser_core_info.set_defaults(func=core_info)

# gen subparser
@@ -490,7 +530,9 @@ def get_parser():
parser_gen_show = gen_subparsers.add_parser(
"show", help="Show information about a generator"
)
parser_gen_show.add_argument("generator", help="Name of the generator to show")
parser_gen_show.add_argument(
"generator", help="Name of the generator to show"
).completer = GenCompleter()
parser_gen_show.set_defaults(func=gen_show)

# gen clean subparser
@@ -596,7 +638,9 @@ def get_parser():
parser_run.add_argument("--build", action="store_true", help="Execute build stage")
parser_run.add_argument("--run", action="store_true", help="Execute run stage")
parser_run.add_argument("--target", help="Override default target")
parser_run.add_argument("--tool", help="Override default tool for target")
parser_run.add_argument(
"--tool", help="Override default tool for target"
).completer = ToolCompleter()
parser_run.add_argument(
"--flag",
help="Set custom use flags. Can be specified multiple times",
@@ -616,7 +660,9 @@ def get_parser():
action="store_true",
help="Allow additional properties in core files",
)
parser_run.add_argument("system", help="Select a system to operate on")
parser_run.add_argument(
"system", help="Select a system to operate on"
).completer = CoreCompleter()
parser_run.add_argument(
"backendargs", nargs=argparse.REMAINDER, help="arguments to be sent to backend"
)
@@ -639,6 +685,7 @@ def get_parser():
def parse_args(argv):
parser = get_parser()

argcomplete.autocomplete(parser, always_complete_options=False)
args = parser.parse_args(argv)

if hasattr(args, "func"):
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@ dependencies = [
"simplesat>=0.9.1",
"fastjsonschema",
"jsonschema2md",
"argcomplete",
]
requires-python = ">=3.6, <4"