NuShell命令补全指南
Nushell 是一款基于 Rust 构建的现代 Shell。相比 Fish(仅在 UNIX 平台可用),它天然跨平台(Windows / Linux / macOS),在不同系统间共享一套配置极其方便,社区活跃且迭代迅速。
但代价呢?Fish 有着更成熟的补全生态,例如它原生支持对 Claude Code 进行补全,Nushell 社区对其的支持则稍晚一些。
我全都要.webp
好消息是,在 Nushell 中我们可以通过两种方案实现补全,且二者完美共存:
- Custom Completions:手写补全脚本,可参考 Nushell 社区脚本库
- External Completers:桥接外部补全工具(如 Fish、Carapace、Zoxide)
本文主要介绍第二种方式——让你在 Nushell 里也能复用 Fish 的补全能力。
整体架构
在 completions.nu 中,我们将补全系统拆分为三个模块:
- 桥接(Bridge):连接外部补全系统(Fish / Carapace)
- 别名解析(Normalization):将 alias 还原为真实命令
- 分发调度(Dispatcher):根据命令类型选择最合适的补全器
Step 1. 桥接 Fish 与 Carapace
许多成熟的命令行工具已经为其他 Shell 提供了高质量补全:
- Fish 的
complete --do-complete - Carapace 的跨 Shell 补全接口
$ fish --command "complete --do-complete 'git switch or'"origin/HEAD Remote Branchorigin/dev Remote Branchorigin/main Remote Branch$ carapace git nushell git switch ''[{"value":"switch ","display":"switch","description":"Switch branches","style":{"fg":"blue"}}]借助 Nushell 提供的 External Completer API,我们可以将这些能力整合进 Nushell:let fish_completer = {|spans| fish --command $"complete '--do-complete=($spans | str replace --all "'" "\\'" | str join ' ')'" | from tsv --flexible --noheaders --no-infer | rename value description | update value {|row| let value = $row.value let need_quote = ['\' ',' '[' ']' '(' ')' ' ' '\t' "'" '"' "`"] | any {$in in $value} if ($need_quote and ($value | path exists)) { let expanded_path = if ($value starts-with ~) {$value | path expand --no-symlink} else {$value} $'"($expanded_path | str replace --all "\"" "\\\"")"' } else {$value} }}let carapace_completer = {|spans: list<string>| CARAPACE_LENIENT=1 carapace $spans.0 nushell ...$spans | from json}
Step 2. 处理别名
假设你定义了:alias g = git
大多数补全器无法识别 g,因此不会触发 Git 补全。我们可以通过 scope aliases 查询当前命令是否为别名,如果是,则还原为真实命令后再交给补全器处理。
例如 g switch 会被转换为 git switch,再执行补全。具体实现见下一步的 dispatcher。
Step 3. 分发调度
不同补全器的质量因工具而异:
- 某些工具在 Fish 中补全最完整(如
git、bun) - 其他工具则更适合 Carapace
因此采用 分发策略:指定命令走 Fish,其余走 Carapace。
下面的 dispatcher 同时完成了 Step 2 的别名解析和 Step 3 的分发逻辑:let external_completer = {|spans| let expanded_alias = scope aliases | where name == $spans.0 | get -o 0.expansion let spans = if $expanded_alias != null { $spans | skip 1 | prepend ($expanded_alias | split row ' ' | take 1) } else { $spans } match $spans.0 { nu | tv | bun | git | rclone => $fish_completer _ => $carapace_completer } | do $in $spans}
Step 4. 启用 External Completer
最后在 Nushell 配置中启用外部补全即可:$env.config.completions = { case_sensitive: false quick: true partial: true algorithm: "prefix" external: { enable: true completer: $external_completer } use_ls_colors: true}
还可以进一步配置 menu 和 keybindings 以获得更丝滑的体验,参考我的配置仓库 Efterklang/dotfiles。
效果演示
配置完成后,输入 ssh 按 Tab 即可自动列出 ~/.ssh/config 中的远程主机,git 补全也一应俱全:

NuShell命令补全指南

