carapace-sh / carapace-bin

multi-shell multi-command argument completer
https://carapace.sh
MIT License
783 stars 45 forks source link

In Nushell external commands are not completed (but their options are) #1897

Closed tad-lispy closed 9 months ago

tad-lispy commented 9 months ago

Current Behavior

When trying to complete an external command command, for example grep, I get no suggestions

/home/tad| gre<tab>                                                                 10/09/2023 09:10:48 AM
NO RECORDS FOUND

Expected Behavior

Carapace should complete if there is only one candidate (as in the case of gre<tab>) or show me the list of matching commands.

Steps To Reproduce

  1. With Nushell on NixOS
  2. Type gre and <tab>.
  3. See NO RECORDS FOUND

Version

0.27.0

OS

Shell

Anything else?

Carapace is awesome :-) Thanks for sharing it with us.

The built in Nushell commands are completed correctly:

/home/tad| gr<tab>                                                                  10/09/2023 09:19:39 AM
grid      Renders the output to a textual terminal grid.
group     Groups input into groups of `group_size`.
group-by  Splits a list or table into groups, and returns a record containing those groups.

Once I type the command, the options are completed correctly:

/home/tad| grep --<tab>                                                             10/09/2023 09:20:47 AM
--after-context           print NUM lines of trailing context
--basic-regexp            PATTERNS are basic regular expressions
--before-context          print NUM lines of leading context
--binary                  do not strip CR characters at EOL (MSDOS/Windows)
--binary-files            assume that binary files are TYPE;
--byte-offset             print the byte offset with output lines
--color
--colour                  use markers to highlight the matching strings;

My configuration: https://gitlab.com/tad-lispy/nixos-configuration/-/blob/70b3fcd2c161bd8026b56ef7002defdaa61830a7/tad.nix#L39-51

I did try to remove all other custom completion. There was no change.

I also tried it with ^gre<tab> to hint that it's an external command. No difference.

It is the same for every external command I tried, not only grep.

rsteube commented 9 months ago

Not too firm with the nix configuration myself, but the commands there should be completed by Nushell and not passed to the external completer :thinking: . So

Does it work without carapace?

tad-lispy commented 9 months ago

Thanks @rsteube. What you say makes sense. Nevertheless disabling Carapace brings back command completion.

~| gr<tab>                                                             10/10/23 07:21:11 AM
grid       Renders the output to a textual terminal grid.
grep
group      Groups input into groups of `group_size`.
grpck
groups
grpconv

Somehow integrating Carapace breaks this Nushell completion. Here is how my config looks after enabling Carapace:


~/.config/nushell/env.nu

let carapace_cache = "/home/tad/.cache/carapace"
if not ($carapace_cache | path exists) {
  mkdir $carapace_cache
}
/nix/store/ps2yrik3grrc5xyc8r57ffvsgrisxggd-carapace-0.27.0/bin/carapace _carapace nushell | save -f $"($carapace_cache)/init.nu"

~/.config/nushell/config.nu

source /home/tad/.cache/carapace/init.nu

$env.config = ($env | default {} config).config
$env.config = ($env.config | default {} hooks)
$env.config = ($env.config | update hooks ($env.config.hooks | default [] pre_prompt))
$env.config = ($env.config | update hooks.pre_prompt ($env.config.hooks.pre_prompt | append {
  code: "
    let direnv = (/nix/store/bkay3lb41czmhka6isvggbdc5lk47yzx-direnv-2.32.3/bin/direnv export json | from json)
    let direnv = if not ($direnv | is-empty) { $direnv } else { {} }
    $direnv | load-env
    "
}))

~/.cache/carapace/init.nu

$env.PATH = ($env.PATH | prepend "/home/tad/.config/carapace/bin")

let carapace_completer = {|spans| 
  carapace $spans.0 nushell $spans | from json
}

mut current = (($env | default {} config).config | default {} completions)
$current.completions = ($current.completions | default {} external)
$current.completions.external = ($current.completions.external 
    | default true enable
    | default $carapace_completer completer)

$env.config = $current

I've noticed that there is no bin/ directory in ~/.config/carapace/. Not sure if it's relevant.

╭───┬──────────────────────────────┬──────┬──────────┬──────────────╮
│ # │             name             │ type │   size   │   modified   │
├───┼──────────────────────────────┼──────┼──────────┼──────────────┤
│ 0 │ .config/carapace/overlays    │ dir  │  4.0 KiB │ 2 days ago   │
│ 1 │ .config/carapace/schema.json │ file │ 15.9 KiB │ 53 years ago │
│ 2 │ .config/carapace/specs       │ dir  │  4.0 KiB │ 2 days ago   │
╰───┴──────────────────────────────┴──────┴──────────┴──────────────╯
rsteube commented 9 months ago

Seems ok on the first look though. The ~/.config/carapace/bin directory is created on demand by carapace (might be good to do that by default though).

rsteube commented 9 months ago

Tried it in the nixos/nix docker container and so far can't reproduce it. Btw. are the nushell configs generated? Hardcoding the full path instead of using what is provided by $PATH seems a bit weird. (carapace just invokes carapace from $PATH anyway)

tad-lispy commented 9 months ago

TLDR: I got it to work and the problem is somewhere between Nushell and Home Manager. Here is my workaround: https://gitlab.com/tad-lispy/nixos-configuration/-/commit/3370a505fe40212f52e65ecfe4d42c732a8e3953


Yes, the files are generated by Home Manager (a Nix tool), and the problem seems to be related to how they are generated. Basically it seems that command completion depends on the code from default env.nu file (the $env.ENV_CONVERSIONS = ... bit). If the env.nu file doesn't exist then Nushell prompts to create it with the default value. Enabling Carapace integration made Nix (Home Manager) generate the env.nu file, but only with Carapace specific logic, and without all the defaults. That's why command completion worked without Carapace and stopped with it.

You helped me understand the problem and find a solution. Thank you. Feel free to close this issue.