Skip to content

Commit

Permalink
Tab complete for paths in bash
Browse files Browse the repository at this point in the history
  • Loading branch information
brentyi committed Sep 23, 2022
1 parent 11930b5 commit 0f54c13
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 7 deletions.
21 changes: 19 additions & 2 deletions dcargs/_arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import functools
import itertools
import shlex
from pathlib import Path
from typing import (
Any,
Dict,
Expand All @@ -21,7 +22,9 @@
Union,
)

from . import _fields, _instantiators, _resolver, _strings
from . import _fields, _instantiators, _resolver
from . import _shtab as shtab
from . import _strings
from .conf import _markers

try:
Expand Down Expand Up @@ -77,7 +80,21 @@ def add_argument(
kwargs["choices"] = _PatchedList(kwargs["choices"])

# Note that the name must be passed in as a position argument.
parser.add_argument(name_or_flag, **kwargs)
arg = parser.add_argument(name_or_flag, **kwargs)

# Do our best to tab complete paths.
# There will be false positives here, but if choices is unset they should be
# harmless.
if "choices" not in kwargs:
if "dir" in self.field.name:
arg.complete = shtab.DIRECTORY # type: ignore
elif (
# Catch types like Path, List[Path], Tuple[Path, ...] etc.
"Path" in str(self.field.typ)
or "path" in self.field.name
or "file" in self.field.name
):
arg.complete = shtab.FILE # type: ignore

@cached_property
def lowered(self) -> LoweredArgumentDefinition:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "dcargs"
version = "0.3.8"
version = "0.3.9"
description = "Strongly typed, zero-effort CLI interfaces"
authors = ["brentyi <[email protected]>"]
include = ["./dcargs/**/*"]
Expand Down
19 changes: 15 additions & 4 deletions tests/test_dcargs.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class InitFalseDataclass:
i: int
s: str
f: float
p: pathlib.Path
dir: pathlib.Path
ignored: str = dataclasses.field(default="hello", init=False)

assert dcargs.cli(
Expand All @@ -111,15 +111,26 @@ class InitFalseDataclass:
"5",
"--f",
"5",
"--p",
"--dir",
"~",
],
) == InitFalseDataclass(i=5, s="5", f=5.0, p=pathlib.Path("~"))
) == InitFalseDataclass(i=5, s="5", f=5.0, dir=pathlib.Path("~"))

with pytest.raises(SystemExit):
dcargs.cli(
InitFalseDataclass,
args=["--i", "5", "--s", "5", "--f", "5", "--p", "~", "--ignored", "blah"],
args=[
"--i",
"5",
"--s",
"5",
"--f",
"5",
"--dir",
"~",
"--ignored",
"blah",
],
)


Expand Down

0 comments on commit 0f54c13

Please sign in to comment.