{ config, pkgs, lib, ... }: let inherit (lib) mkEnableOption mkPackageOption mkIf pipe fileContents splitString; cfg = config.programs.carapace; bin = cfg.package + "/bin/carapace"; in { meta.maintainers = with lib.maintainers; [ weathercold bobvanderlinden ]; options.programs.carapace = { enable = mkEnableOption "carapace, a multi-shell multi-command argument completer"; package = mkPackageOption pkgs "carapace" { }; enableBashIntegration = mkEnableOption "Bash integration" // { default = true; }; enableZshIntegration = mkEnableOption "Zsh integration" // { default = true; }; enableFishIntegration = mkEnableOption "Fish integration" // { default = true; }; enableNushellIntegration = mkEnableOption "Nushell integration" // { default = true; }; }; config = mkIf cfg.enable { home.packages = [ cfg.package ]; programs = { bash.initExtra = mkIf cfg.enableBashIntegration '' source <(${bin} _carapace bash) ''; zsh.initExtra = mkIf cfg.enableZshIntegration '' source <(${bin} _carapace zsh) ''; fish.interactiveShellInit = mkIf cfg.enableFishIntegration '' ${bin} _carapace fish | source ''; nushell = mkIf cfg.enableNushellIntegration { # Note, the ${"$"} below is a work-around because xgettext otherwise # interpret it as a Bash i18n string. extraEnv = '' let carapace_cache = "${config.xdg.cacheHome}/carapace" if not ($carapace_cache | path exists) { mkdir $carapace_cache } ${bin} _carapace nushell | save -f ${"$"}"($carapace_cache)/init.nu" ''; extraConfig = '' source ${config.xdg.cacheHome}/carapace/init.nu ''; }; }; xdg.configFile = mkIf (config.programs.fish.enable && cfg.enableFishIntegration) ( # Convert the entries from `carapace --list` to empty # xdg.configFile."fish/completions/NAME.fish" entries. # # This is to disable fish builtin completion for each of the # carapace-supported completions It is in line with the instructions from # carapace-bin: # # carapace --list | awk '{print $1}' | xargs -I{} touch ~/.config/fish/completions/{}.fish # # See https://github.com/rsteube/carapace-bin#getting-started let carapaceListFile = pkgs.runCommandLocal "carapace-list" { buildInputs = [ cfg.package ]; } '' ${bin} --list > $out ''; in pipe carapaceListFile [ fileContents (splitString "\n") (map (builtins.match "^([a-z0-9-]+) .*")) (builtins.filter (match: match != null && (builtins.length match) > 0)) (map (match: builtins.head match)) (map (name: { name = "fish/completions/${name}.fish"; value = { text = ""; }; })) builtins.listToAttrs ]); }; }