placeholderNuShell命令补全指南

NuShell命令补全指南

Nushell 是一款基于 Rust 构建的现代 Shell。相比 Fish(仅在 UNIX 平台可用),它天然跨平台(Windows / Linux / macOS),在不同系统间共享一套配置极其方便,社区活跃且迭代迅速。

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

我全都要.webp

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

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

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

整体架构

completions.nu 中,我们将补全系统拆分为三个模块:

  1. 桥接(Bridge):连接外部补全系统(Fish / Carapace)
  2. 别名解析(Normalization):将 alias 还原为真实命令
  3. 分发调度(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 中补全最完整(如 gitbun
  • 其他工具则更适合 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}

还可以进一步配置 menukeybindings 以获得更丝滑的体验,参考我的配置仓库 Efterklang/dotfiles

效果演示

配置完成后,输入 sshTab 即可自动列出 ~/.ssh/config 中的远程主机,git 补全也一应俱全:

nu_completion

NuShell命令补全指南

https://vluv.space/nu_completion/

Author

GnixAij

Posted

2025-02-11

Updated

2026-03-16

License