Skip to content

Commit 3f199b5

Browse files
committed
feat: shell completions
1 parent fa81e0e commit 3f199b5

4 files changed

Lines changed: 50 additions & 0 deletions

File tree

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,21 @@ CLI outputs:
3636
- Optional per-image skeleton outputs (default: `.npy`)
3737
- Optional per-image branch tables when `output.write_branch_csv=true`
3838

39+
### Shell completions
40+
41+
```sh
42+
# zsh
43+
eval "$(vesskel completions zsh)"
44+
45+
# bash
46+
eval "$(vesskel completions bash)"
47+
48+
# PowerShell
49+
vesskel completions powershell | Out-String | Invoke-Expression
50+
```
51+
52+
Add the appropriate line to your shell rc for persistent tab-completion.
53+
3954
## Tests
4055

4156
```sh

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ description = "2D and 3D Skeletonization and Graph-based Analysis"
66
readme = "README.md"
77
requires-python = ">=3.13"
88
dependencies = [
9+
"argcomplete>=3.6.0",
910
"numba>=0.65.0",
1011
"numpy>=2.4.4",
1112
"pillow>=12.2.0",

uv.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vesskel/cli.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from typing import Iterable
1111

1212
import numpy as np
13+
from argcomplete import autocomplete, shellcode
1314
from PIL import Image
1415

1516
from vesskel.config import (
@@ -76,6 +77,20 @@ def _parse_args() -> argparse.Namespace:
7677
)
7778
validate_parser.add_argument("--config", required=True, help="Config JSON path.")
7879

80+
completions_parser = subparsers.add_parser(
81+
"completions",
82+
help="Print shell completion script to stdout.",
83+
)
84+
completions_parser.add_argument(
85+
"shell",
86+
choices=("bash", "zsh", "powershell"),
87+
help="Target shell.",
88+
)
89+
90+
try:
91+
autocomplete(parser)
92+
except ImportError:
93+
pass
7994
return parser.parse_args()
8095

8196

@@ -244,6 +259,12 @@ def _validate_config(args: argparse.Namespace) -> int:
244259
return 0
245260

246261

262+
def _completions(args: argparse.Namespace) -> int:
263+
264+
print(shellcode(["vesskel"], shell=args.shell))
265+
return 0
266+
267+
247268
def main() -> int:
248269
args = _parse_args()
249270
if args.command == "run":
@@ -252,6 +273,8 @@ def main() -> int:
252273
return _config_init(args)
253274
if args.command == "validate-config":
254275
return _validate_config(args)
276+
if args.command == "completions":
277+
return _completions(args)
255278
raise ValueError(f"Unknown command: {args.command}")
256279

257280

0 commit comments

Comments
 (0)