Commit d95ee68

HPCesia <me@hpcesia.com>
2026-10-12 11:41:52
carapace: patch nix completion for flake
Assisted-by: crush:glm-5.3
1 parent abcc540
Changed files (2)
modules/core/shell/carapace-bin-2913.patch
@@ -0,0 +1,109 @@
+diff --git a/pkg/actions/tools/nix/flake.go b/pkg/actions/tools/nix/flake.go
+index 1c17533c..f730677b 100644
+--- a/pkg/actions/tools/nix/flake.go
++++ b/pkg/actions/tools/nix/flake.go
+@@ -3,8 +3,6 @@ package nix
+ import (
+ 	"bytes"
+ 	"fmt"
+-	"os"
+-	"slices"
+ 	"strings"
+ 
+ 	"github.com/carapace-sh/carapace"
+@@ -50,11 +48,11 @@ func styleForRegistry(s string) string {
+ //	packages.x86_64-linux.hello
+ func ActionFlakeAttributes(flake string) carapace.Action {
+ 	return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
+-		// Get completions from the flake registry
++		// Get completions using the nix cli
+ 		c.Setenv("NIX_GET_COMPLETIONS", "2")
+ 
+ 		var stdout, stderr bytes.Buffer
+-		cmd := c.Command("nix", "build", flake)
++		cmd := c.Command("nix", "build", fmt.Sprintf("%v#%v", flake, c.Value))
+ 		cmd.Stdout = &stdout
+ 		cmd.Stderr = &stderr
+ 
+@@ -62,37 +60,11 @@ func ActionFlakeAttributes(flake string) carapace.Action {
+ 			return carapace.ActionValues()
+ 		}
+ 
+-		// Check if the given flake is in the registry or is a local path
++		// Remove \r for consistency with line endings
+ 		// For some reason, nix adds \b to completion items
+ 		rawLines := strings.ReplaceAll(stdout.String(), "\r\b", "")
+ 		lines := strings.Split(rawLines, "\n")
+ 
+-		flakeInRegistry := slices.ContainsFunc(lines[1:], func(s string) bool {
+-			return strings.Trim(s, " \t") == flake
+-		})
+-		flakeIsLocal := directoryExists(flake)
+-
+-		if !flakeInRegistry && !flakeIsLocal {
+-			return carapace.ActionValues()
+-		}
+-
+-		// Get completions using the nix cli
+-		stdout.Reset()
+-		stderr.Reset()
+-
+-		cmd = c.Command("nix", "build", fmt.Sprintf("%v#%v", flake, c.Value))
+-		cmd.Stdout = &stdout
+-		cmd.Stderr = &stderr
+-
+-		if err := cmd.Run(); err != nil {
+-			return carapace.ActionValues()
+-		}
+-
+-		// Remove \r for consistency with line endings
+-		// For some reason, nix adds \b to completion items
+-		rawLines = strings.ReplaceAll(stdout.String(), "\r\b", "")
+-		lines = strings.Split(rawLines, "\n")
+-
+ 		// The first line is always "attrs"
+ 		completionResults := lines[1:]
+ 
+@@ -106,15 +78,6 @@ func ActionFlakeAttributes(flake string) carapace.Action {
+ 	})
+ }
+ 
+-func directoryExists(path string) bool {
+-	info, err := os.Stat(path)
+-	if err != nil {
+-		return false
+-	}
+-
+-	return info.IsDir()
+-}
+-
+ // ActionFlakeRefs completes a full flake reference
+ // It will only complete attributes for local flakes or flakes in the flake registry.
+ //
+diff --git a/pkg/actions/tools/nix/installables.go b/pkg/actions/tools/nix/installables.go
+index 0cbc7b87..a2996eb4 100644
+--- a/pkg/actions/tools/nix/installables.go
++++ b/pkg/actions/tools/nix/installables.go
+@@ -1,8 +1,6 @@
+ package nix
+ 
+ import (
+-	"strings"
+-
+ 	"github.com/carapace-sh/carapace"
+ )
+ 
+@@ -35,12 +33,7 @@ func ActionInstallables() carapace.Action {
+ 			).ToA()
+ 
+ 		case 1:
+-			switch c.Parts[0] {
+-			case ".":
+-				return ActionFlakeAttributes(".")
+-			default:
+-				return ActionPackages(strings.SplitN(c.Parts[0], "/", 2)[0])
+-			}
++			return ActionFlakeAttributes(c.Parts[0])
+ 
+ 		default:
+ 			return carapace.ActionValues()
modules/core/shell/nushell.nix
@@ -19,7 +19,7 @@
         lib,
         ...
       }: let
-        carapace = pkgs.carapace.overrideAttrs {
+        carapace = pkgs.carapace.overrideAttrs (prev: {
           version = "1.8.0";
           src = pkgs.fetchFromGitHub {
             owner = "carapace-sh";
@@ -28,7 +28,10 @@
             hash = "sha256-KO+fD81PyIK8gcNQfeyQgn6YMGSSvndyU4Efu5ZQZxE=";
           };
           vendorHash = "sha256-6Pm1lsRGiY3tfEV9T17SX5ZEssIyRWyrjgKlOlUzcZQ=";
-        };
+          # Complete installable attributes through the Nix itself.
+          # https://github.com/carapace-sh/carapace-bin/issues/2913
+          patches = (prev.patches or []) ++ [./carapace-bin-2913.patch];
+        });
 
         carapace-wrapped = pkgs.symlinkJoin {
           name = "carapace-wrapped";