···

NuShell命令补全指南

Nushell配置Carapace与Fish实现命令智能补全,支持Git、Docker等常用工具,大幅提升终端操作效率
跳至正文

📢 Update

Nushell 0.116 版本重构了 Completion API。在最新版本中,外部 Completer 已原生支持别名(Alias)解析,不再需要手动编写逻辑来展开或补全 Alias

本文已同步更新:

  • 更新了 Completion API 的配置写法;
  • 删除了原文章中针对 Alias 逻辑的冗余处理章节。

Nushell 是一款基于 Rust 构建的现代 Shell。相比仅支持 UNIX 平台的 Fish,它天然跨平台,在不同系统间工作时无需来回切换Shell,且 Nushell 有着活跃的社区。

但 Fish 有着更成熟的补全生态,例如它原生支持对 Claude Code 进行补全,Nushell 社区对其的支持则稍晚一些。

好消息是,在 Nushell 中我们可以通过两种方案实现补全,且二者完美共存:

  1. Custom Completions:手写补全脚本,可参考 Nushell 社区脚本库
  2. External Completers:桥接外部补全工具(如 Fish、Carapace、Zoxide)

本文主要介绍第二种方式——让你在 Nushell 里也能复用 Fish 的补全能力。

整体架构

在 completions.nu 中,我们将补全系统拆分为两个核心模块:

  1. 桥接(bridge):连接外部补全系统(fish / carapace)
  2. 分发调度(dispatcher):根据命令类型选择最合适的补全器
内置 / 原生补全器外部桥接 Bridge原生/特定命令其他命令行工具用户输入分发调度 Dispatcher根据命令类型匹配最佳补全器返回补全候选词列表Nu Native Completer自定义逻辑 / 复杂规则Fish Shell CompleterCarapace Completer

Step 1. 桥接 Fish 与 Carapace

Fish 作为一款成熟的 Shell,在拥有丰富补全生态的同时,也提供了一个 complete --do-complete 接口,允许我们通过命令行直接调用其内部的补全逻辑:

# 调用 Fish 的补全逻辑,获取 `git switch or` 的候选补全项$ fish --command "complete --do-complete 'git switch or'"origin/HEAD    Remote Branchorigin/dev     Remote Branchorigin/main    Remote Branch

Carapace 则是另一个通用的跨平台补全引擎,能够为多种 Shell 统一提供补全能力。它的接口调用方式为 carapace <command> <shell> <args...>,并且能够直接输出 JSON 格式的补全数据:

# 调用 Carapace 获取 `git switch or` 在 Nushell 下的 JSON 结构化补全输出# Carapace 输出的 JSON 默认是 one-line 的,为了美观,此处使用 jq 进行格式化$ carapace git nushell git switch or | jq[  {    "value": "origin/head ",    "display": "origin/head",    "description": "remote branch"  },  {    "value": "origin/dev ",    "display": "origin/dev",    "description": "remote branch"  },  {    "value": "origin/main ",    "display": "origin/main",    "description": "remote branch"  }]

借助 Nushell 提供的 External Completer API,我们可以将这些能力整合进 Nushell:

let fish_completer = {|place|    fish --command $"complete '--do-complete=($place.command | 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 = {|place|    CARAPACE_LENIENT=1 carapace $place.command.0 nushell ...$place.command | from json}

Step 2. 分发调度

不同补全器的质量因工具而异:

  • 某些工具在 Fish 中补全最完整(如 git、bun)
  • 其他工具则更适合 Carapace

因此采用 分发策略:指定命令走 Fish,其余走 Carapace。

得益于 Nushell 0.116 的升级,我们在分发逻辑中可以直接接受原始 spans,无需再手动编写别名查找和展开的代码:

let external_completer = {|place|    match $place.command.0 {        nu | tv | bun | git | rclone => $fish_completer        _ => $carapace_completer    } | do $in $place}

Step 3. 启用 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 补全也一应俱全:

nu_completion
nu_completion