From f07543360c5a294733ce354cd835aae2cdaa057d Mon Sep 17 00:00:00 2001 From: naokihaba <59875779+naokihaba@users.noreply.github.com> Date: Thu, 29 Oct 2026 19:28:21 +0900 Subject: [PATCH 1/3] fix(env): fall back to file completion in Nushell without fish The env.nu completers for vp and vpr call fish to get completions. Nushell 0.116 shows no suggestions when a parameter completer fails, so without fish on PATH, Tab after `vp ` shows nothing. Return null when fish is missing so that Nushell runs file completion, as in 0.115. Closes #3272 --- .../assert_without_fish.nu | 20 +++++++++++++++++++ .../command_env_nushell/snapshots.toml | 11 ++++++++++ .../command_env_nushell_without_fish.md | 15 ++++++++++++++ .../shell_integration_cwd_templates.md | 3 +++ .../vp_global_cli/src/commands/env/setup.rs | 5 +++++ 5 files changed, 54 insertions(+) create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/assert_without_fish.nu create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/snapshots/command_env_nushell_without_fish.md diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/assert_without_fish.nu b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/assert_without_fish.nu new file mode 100644 index 0000000000..917838aac2 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/assert_without_fish.nu @@ -0,0 +1,20 @@ +# Nushell 0.116 shows no suggestions when a parameter completer fails. Without fish, the +# completers must return null so that file completion answers instead (#3272). +let lines = ["vp ", "vpr "] +let path = $env.PATH | where { not ($in | path join fish | path exists) } +let script = $"source env.nu +($lines | to nuon) | each {|line| $line | commandline complete } | to json --raw" +let result = with-env { PATH: $path } { ^$nu.current-exe -n -c $script | complete } +if $result.exit_code != 0 { + error make { msg: $"completion failed: ($result.stderr)" } +} + +let completions = $result.stdout | from json +for index in [0 1] { + let values = $completions | get $index + if "env.nu" not-in $values { + error make { msg: $"`($lines | get $index)` did not fall back to file completion without fish, got: ($values)" } + } +} + +print "Nushell completer checks without fish passed" diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/snapshots.toml index babf9401fe..3cf4a06852 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/snapshots.toml @@ -42,3 +42,14 @@ steps = [ { argv = ["vpt", "cp", "assert_completion.nu", "home/assert_completion.nu"], snapshot = false }, { argv = ["nu", "assert_completion.nu"], cwd = "home", comment = "env.nu completers complete `vp` after a pipeline and do not use the positional input that Nushell 0.116 deprecates (#3127)", envs = [["VP_HOME", "${workspace}/home"]] }, ] + +[[case]] +name = "command_env_nushell_without_fish" +vp = "global" +skip-platforms = ["windows"] +requires = ["nu"] +steps = [ + { argv = ["vp", "env", "setup", "--refresh"], envs = [["VP_HOME", "${workspace}/home"]], snapshot = false }, + { argv = ["vpt", "cp", "assert_without_fish.nu", "home/assert_without_fish.nu"], snapshot = false }, + { argv = ["nu", "assert_without_fish.nu"], cwd = "home", comment = "without fish on PATH, env.nu completers return null so Nushell 0.116 falls back to file completion (#3272)", envs = [["VP_HOME", "${workspace}/home"]] }, +] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/snapshots/command_env_nushell_without_fish.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/snapshots/command_env_nushell_without_fish.md new file mode 100644 index 0000000000..126de3a9e9 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/snapshots/command_env_nushell_without_fish.md @@ -0,0 +1,15 @@ +# command_env_nushell_without_fish + +## `VP_HOME=${workspace}/home vp env setup --refresh` + + +## `vpt cp assert_without_fish.nu home/assert_without_fish.nu` + + +## `cd home && VP_HOME=${workspace}/home nu assert_without_fish.nu` + +without fish on PATH, env.nu completers return null so Nushell 0.116 falls back to file completion (#3272) + +``` +Nushell completer checks without fish passed +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/shell_integration_cwd_templates/snapshots/shell_integration_cwd_templates.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/shell_integration_cwd_templates/snapshots/shell_integration_cwd_templates.md index 4ffc1c657a..abf6a6f5cc 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/shell_integration_cwd_templates/snapshots/shell_integration_cwd_templates.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/shell_integration_cwd_templates/snapshots/shell_integration_cwd_templates.md @@ -258,7 +258,10 @@ def "nu-complete vp current-command" [buffer: string, place: any] { if (($place | %describe) starts-with "record") { $place.command | %str join ' ' } else { $buffer } } # Fish gets the command as an argument, so quotes in it cannot end a fish string. +# Without fish, return null so Nushell falls back to file completion. Nushell 0.116+ shows no +# suggestions when a parameter completer fails (#3272). def "nu-complete vp fish" [command: string] { + if (%which fish | %is-empty) { return null } let fish_script = 'VP_COMPLETE=fish command vp | source; complete --do-complete=$argv[1]' ^fish --command $fish_script $command | %from tsv --flexible --noheaders --no-infer | %rename value description | %update value {|row| let value = $row.value diff --git a/crates/vp_global_cli/src/commands/env/setup.rs b/crates/vp_global_cli/src/commands/env/setup.rs index 90339f898f..cac19a77c8 100644 --- a/crates/vp_global_cli/src/commands/env/setup.rs +++ b/crates/vp_global_cli/src/commands/env/setup.rs @@ -1019,7 +1019,10 @@ def "nu-complete vp current-command" [buffer: string, place: any] { if (($place | %describe) starts-with "record") { $place.command | %str join ' ' } else { $buffer } } # Fish gets the command as an argument, so quotes in it cannot end a fish string. +# Without fish, return null so Nushell falls back to file completion. Nushell 0.116+ shows no +# suggestions when a parameter completer fails (#3272). def "nu-complete vp fish" [command: string] { + if (%which fish | %is-empty) { return null } let fish_script = 'VP_COMPLETE=fish command vp | source; complete --do-complete=$argv[1]' ^fish --command $fish_script $command | %from tsv --flexible --noheaders --no-infer | %rename value description | %update value {|row| let value = $row.value @@ -1982,6 +1985,8 @@ mod tests { let legacy = render_env_content(EnvShell::Nu, &config, NuSyntax::Legacy); assert!(legacy.contains("| update value {|row|"), "got: {legacy}"); assert!(legacy.contains("^fish --command"), "got: {legacy}"); + // CI runs only a newer Nushell, so check the legacy fish guard here (#3272). + assert!(legacy.contains("if (which fish | is-empty) { return null }")); assert_eq!( legacy.replace("/tmp/vp%home", "").matches('%').count(), 0, From 57045b72156a89143a32bfe42ae7c95edcfdb6ed Mon Sep 17 00:00:00 2001 From: naokihaba <59875779+naokihaba@users.noreply.github.com> Date: Fri, 30 Oct 2026 01:06:56 +0900 Subject: [PATCH 2/3] test(env): shadow which and is-empty in the Nushell builtins test --- .../fixtures/command_env_nushell/assert_shadowed.nu | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/assert_shadowed.nu b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/assert_shadowed.nu index bafb52d94d..af0b1f037f 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/assert_shadowed.nu +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_env_nushell/assert_shadowed.nu @@ -25,6 +25,8 @@ def "path exists" [] { } def "from tsv" [] { } def rename [] { } def any [] { } +def which [] { } +def is-empty [] { } def fish [] { } source env.nu From 93bf0bf36841edae49e507b54ebbba46075faabd Mon Sep 17 00:00:00 2001 From: naokihaba <59875779+naokihaba@users.noreply.github.com> Date: Fri, 30 Oct 2026 12:27:22 +0900 Subject: [PATCH 3/3] chore: retrigger CI