From ffd32dfe8a5d9ca89554552d11cb9fa0f3904bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saugat=20Pachhai=20=28=E0=A4=B8=E0=A5=8C=E0=A4=97=E0=A4=BE?= =?UTF-8?q?=E0=A4=A4=29?= Date: Mon, 6 Oct 2025 20:38:53 +0545 Subject: [PATCH] completion: support fish completion Fixes #10879. Upstream PR: https://github.com/iterative/shtab/pull/195. --- dvc/cli/completion.py | 81 +++++++++++++++++++++++++++++++++++--- dvc/commands/completion.py | 2 +- pyproject.toml | 3 +- 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/dvc/cli/completion.py b/dvc/cli/completion.py index b257bc20b..36568f13b 100644 --- a/dvc/cli/completion.py +++ b/dvc/cli/completion.py @@ -74,22 +74,72 @@ _dvc_compadd_config_vars() { } """ +FISH_PREAMBLE = """ +function __fish_complete_dvc_files + __fish_complete_path | string match -re '\\*?.dvc|Dvcfile|dvc\\.yaml' +end + +function __fish_complete_dvc_stages + for line in (dvc stage list -q) + set -l parts (string split -m1 ' ' -- $line) + set -l name $parts[1] + set -l desc (string trim $parts[2]) + echo -e "$name $desc" + end +end + +function __fish_complete_dvc_stages_and_files + __fish_complete_dvc_stages + __fish_complete_dvc_files +end + +function __fish_complete_dvc_experiments + dvc exp list -q --all-commits --names-only +end + +function __fish_complete_dvc_remotes + dvc remote list | cut -d' ' -f1 +end +""" + PREAMBLE = { "bash": BASH_PREAMBLE, "zsh": ZSH_PREAMBLE, + "fish": FISH_PREAMBLE, } FILE = shtab.FILE DIR = shtab.DIRECTORY -DVC_FILE = {"bash": "_dvc_compgen_DVCFiles", "zsh": "_dvc_compadd_DVCFiles"} -STAGE = {"bash": "_dvc_compgen_stages", "zsh": "_dvc_compadd_stages"} +DVC_FILE = { + "bash": "_dvc_compgen_DVCFiles", + "zsh": "_dvc_compadd_DVCFiles", + "fish": "__fish_complete_dvc_files", +} +STAGE = { + "bash": "_dvc_compgen_stages", + "zsh": "_dvc_compadd_stages", + "fish": "__fish_complete_dvc_stages", +} DVCFILES_AND_STAGE = { "bash": "_dvc_compgen_stages_and_files", "zsh": "_dvc_compadd_stages_and_files", + "fish": "__fish_complete_dvc_stages_and_files", +} +EXPERIMENT = { + "bash": "_dvc_compgen_exps", + "zsh": "_dvc_compadd_exps", + "fish": "__fish_complete_dvc_experiments", +} +REMOTE = { + "bash": "_dvc_compgen_remotes", + "zsh": "_dvc_compadd_remotes", + "fish": "__fish_complete_dvc_remotes", +} +CONFIG_VARS = { + "bash": "_dvc_compgen_config_vars", + "zsh": "_dvc_compadd_config_vars", + "fish": "__fish_complete_dvc_config_vars", } -EXPERIMENT = {"bash": "_dvc_compgen_exps", "zsh": "_dvc_compadd_exps"} -REMOTE = {"bash": "_dvc_compgen_remotes", "zsh": "_dvc_compadd_remotes"} -CONFIG_VARS = {"bash": "_dvc_compgen_config_vars", "zsh": "_dvc_compadd_config_vars"} def get_preamble() -> dict[str, str]: @@ -103,7 +153,26 @@ def get_preamble() -> dict[str, str]: _dvc_config_vars=( {nl.join(config_vars)} ) +""" + indent = "\t\t".expandtabs(4) # 8 spaces + lines = ( + "\n".join( + f"{indent}{c} \\" + for c in config_vars[:-1] # all but last + ) + + "\n" + + f"{indent}{config_vars[-1]}" + ) # last line without backslash + config_vars_arr_fish = f""" +function __fish_complete_dvc_config_vars + set -l _dvc_config_vars \\ +{lines} + printf %s\\n $_dvc_config_vars +end """ for shell, preamble in PREAMBLE.items(): - ret[shell] = config_vars_arr + preamble + if shell != "fish": + ret[shell] = config_vars_arr + preamble + else: + ret[shell] = config_vars_arr_fish + preamble return ret diff --git a/dvc/commands/completion.py b/dvc/commands/completion.py index ca492df39..0efec6137 100644 --- a/dvc/commands/completion.py +++ b/dvc/commands/completion.py @@ -8,7 +8,7 @@ from dvc.ui import ui logger = logger.getChild(__name__) -SUPPORTED_SHELLS = ["bash", "zsh"] +SUPPORTED_SHELLS = ["bash", "zsh", "fish"] class CmdCompletion(CmdBaseNoRepo): diff --git a/pyproject.toml b/pyproject.toml index 48454abd8..03a017ebf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,7 +69,8 @@ dependencies = [ "ruamel.yaml>=0.17.11", "scmrepo>=3.5.2,<4", "shortuuid>=0.5", - "shtab<2,>=1.3.4", + # "shtab<2,>=1.3.4", + "shtab @ git+https://github.com/skshetry/shtab.git@fish-shell-v2", "tabulate>=0.8.7", "tomlkit>=0.11.1", "tqdm<5,>=4.63.1",