completion: support fish completion

Fixes #10879.
Upstream PR: https://github.com/iterative/shtab/pull/195.
This commit is contained in:
Saugat Pachhai (सौगात)
2025-10-06 20:38:53 +05:45
parent 2b19c724c5
commit ffd32dfe8a
3 changed files with 78 additions and 8 deletions
+75 -6
View File
@@ -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 = { PREAMBLE = {
"bash": BASH_PREAMBLE, "bash": BASH_PREAMBLE,
"zsh": ZSH_PREAMBLE, "zsh": ZSH_PREAMBLE,
"fish": FISH_PREAMBLE,
} }
FILE = shtab.FILE FILE = shtab.FILE
DIR = shtab.DIRECTORY DIR = shtab.DIRECTORY
DVC_FILE = {"bash": "_dvc_compgen_DVCFiles", "zsh": "_dvc_compadd_DVCFiles"} DVC_FILE = {
STAGE = {"bash": "_dvc_compgen_stages", "zsh": "_dvc_compadd_stages"} "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 = { DVCFILES_AND_STAGE = {
"bash": "_dvc_compgen_stages_and_files", "bash": "_dvc_compgen_stages_and_files",
"zsh": "_dvc_compadd_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]: def get_preamble() -> dict[str, str]:
@@ -103,7 +153,26 @@ def get_preamble() -> dict[str, str]:
_dvc_config_vars=( _dvc_config_vars=(
{nl.join(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(): 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 return ret
+1 -1
View File
@@ -8,7 +8,7 @@ from dvc.ui import ui
logger = logger.getChild(__name__) logger = logger.getChild(__name__)
SUPPORTED_SHELLS = ["bash", "zsh"] SUPPORTED_SHELLS = ["bash", "zsh", "fish"]
class CmdCompletion(CmdBaseNoRepo): class CmdCompletion(CmdBaseNoRepo):
+2 -1
View File
@@ -69,7 +69,8 @@ dependencies = [
"ruamel.yaml>=0.17.11", "ruamel.yaml>=0.17.11",
"scmrepo>=3.5.2,<4", "scmrepo>=3.5.2,<4",
"shortuuid>=0.5", "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", "tabulate>=0.8.7",
"tomlkit>=0.11.1", "tomlkit>=0.11.1",
"tqdm<5,>=4.63.1", "tqdm<5,>=4.63.1",