From b18d302d44268fb131033c1157d2978baf9e2207 Mon Sep 17 00:00:00 2001 From: Jonas Holst Damtoft Date: Sat, 23 Mar 2019 21:09:03 +0100 Subject: [PATCH 01/21] fish: add plugin functionality --- modules/programs/fish.nix | 84 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 87a17b85..5a076e2c 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -14,6 +14,39 @@ let mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases ); + fileType = types.submodule ( + { name, config, ... }: { + options = { + body = mkOption { + default = null; + type = types.nullOr types.lines; + description = "Body of the function."; + }; + + source = mkOption { + type = types.path; + description = '' + Path of the source file. The file name must not start + with a period. + ''; + }; + }; + + config = { + source = mkIf (config.body != null) ( + mkDefault (pkgs.writeTextFile { + inherit name; + text = '' + function ${name} + ${config.body} + end + ''; + executable = true; + }) + ); + }; + } + ); in { @@ -80,9 +113,27 @@ in type = types.lines; }; }; + + programs.fish.plugins = mkOption { + type = types.listOf types.package; + default = []; + description = '' + The plugins to add to fish. + Built with buildFishPlugin. + Overrides manually installed ones. + ''; + }; + + programs.fish.functions = mkOption { + type = types.attrsOf fileType; + default = {}; + description = '' + Functions to add to fish. + ''; + }; }; - config = mkIf cfg.enable { + config = mkIf cfg.enable (mkMerge [{ home.packages = [ cfg.package ]; xdg.dataFile."fish/home-manager_generated_completions".source = @@ -187,5 +238,34 @@ in set -g __fish_interactive_config_sourced 1 end ''; - }; + } { + xdg.configFile = map (n: { target = "fish/functions/${n}.fish"; source = cfg.functions.${n}.source; }) (attrNames cfg.functions); + } ( + let + wrappedPkgVersion = lib.getVersion pkgs.fish; + wrappedPkgName = lib.removeSuffix "-${wrappedPkgVersion}" pkgs.fish.name; + dependencies = concatMap (p: p.dependencies) cfg.plugins; + combinedPluginDrv = pkgs.buildEnv { + name = "${wrappedPkgName}-plugins-${wrappedPkgVersion}"; + paths = cfg.plugins; + postBuild = '' + touch $out/setup.fish + + if [ -d $out/functions ]; then + echo "set fish_function_path \$fish_function_path[1] $out/functions \$fish_function_path[2..-1]" >> $out/setup.fish + fi + + if [ -d $out/completions ]; then + echo "set fish_complete_path \$fish_complete_path[1] $out/completions \$fish_complete_path[2..-1]" >> $out/setup.fish + fi + + if [ -d $out/conf.d ]; then + echo "source $out/conf.d/*.fish" >> $out/setup.fish + fi + ''; + }; + in mkIf (length cfg.plugins > 0) { + xdg.configFile."fish/conf.d/99plugins.fish".source = "${combinedPluginDrv}/setup.fish"; + home.packages = dependencies; + })]); } From c22f3e1d2932a6e12ea739750e3f057a44d00c79 Mon Sep 17 00:00:00 2001 From: Jonas Holst Damtoft Date: Fri, 12 Apr 2019 12:33:51 +0200 Subject: [PATCH 02/21] fish: basic completions support --- modules/programs/fish.nix | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 5a076e2c..8e06dda5 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -14,13 +14,13 @@ let mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases ); - fileType = types.submodule ( + fileType = textGen: types.submodule ( { name, config, ... }: { options = { body = mkOption { default = null; type = types.nullOr types.lines; - description = "Body of the function."; + description = "Body of the file."; }; source = mkOption { @@ -36,11 +36,7 @@ let source = mkIf (config.body != null) ( mkDefault (pkgs.writeTextFile { inherit name; - text = '' - function ${name} - ${config.body} - end - ''; + text = textGen name config.body; executable = true; }) ); @@ -125,12 +121,24 @@ in }; programs.fish.functions = mkOption { - type = types.attrsOf fileType; + type = types.attrsOf (fileType (name: body: '' + function ${name} + ${body} + end + '')); default = {}; description = '' Functions to add to fish. ''; }; + + programs.fish.completions = mkOption { + type = types.attrsOf (fileType (name: body: body)); + default = {}; + description = '' + Completions to add to fish. + ''; + }; }; config = mkIf cfg.enable (mkMerge [{ From 2eb1cb077d00f1668ad997e892b719856c7c9b93 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Sun, 22 Sep 2019 23:53:08 -0700 Subject: [PATCH 03/21] fish: move type declarations to top of mkOptions A closer match to the style of the definitions in the bash program. --- modules/programs/fish.nix | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 8e06dda5..bdd0c870 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -51,62 +51,62 @@ in enable = mkEnableOption "fish friendly interactive shell"; package = mkOption { + type = types.package; default = pkgs.fish; defaultText = literalExample "pkgs.fish"; description = '' The fish package to install. May be used to change the version. ''; - type = types.package; }; shellAliases = mkOption { + type = types.attrs; default = {}; description = '' Set of aliases for fish shell. See for an option format description. ''; - type = types.attrs; }; shellAbbrs = mkOption { + type = types.attrs; default = {}; description = '' Set of abbreviations for fish shell. ''; - type = types.attrs; }; shellInit = mkOption { + type = types.lines; default = ""; description = '' Shell script code called during fish shell initialisation. ''; - type = types.lines; }; loginShellInit = mkOption { + type = types.lines; default = ""; description = '' Shell script code called during fish login shell initialisation. ''; - type = types.lines; }; interactiveShellInit = mkOption { + type = types.lines; default = ""; description = '' Shell script code called during interactive fish shell initialisation. ''; - type = types.lines; }; promptInit = mkOption { + type = types.lines; default = ""; description = '' Shell script code used to initialise fish prompt. ''; - type = types.lines; }; }; From 665766f8bb1e36ea873ed7dd3ac06cef6045b78f Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Sun, 22 Sep 2019 23:54:08 -0700 Subject: [PATCH 04/21] fish: add examples for shellAliases, shellAbbrs --- modules/programs/fish.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index bdd0c870..b5bf77f9 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -62,6 +62,7 @@ in shellAliases = mkOption { type = types.attrs; default = {}; + example = { ".." = "cd .."; ll = "ls -l"; }; description = '' Set of aliases for fish shell. See for an option @@ -72,6 +73,7 @@ in shellAbbrs = mkOption { type = types.attrs; default = {}; + example = { l = "less"; gco = "git checkout"; }; description = '' Set of abbreviations for fish shell. ''; From 3de8102e7fd25c51b2b2af899dcff16fd3a035c3 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Mon, 23 Sep 2019 00:01:09 -0700 Subject: [PATCH 05/21] fish: revamp descriptions to match bash style --- modules/programs/fish.nix | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index b5bf77f9..abc1bfea 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -64,9 +64,8 @@ in default = {}; example = { ".." = "cd .."; ll = "ls -l"; }; description = '' - Set of aliases for fish shell. See - for an option - format description. + An attribute set that maps aliases (the top level attribute names + in this option) to command strings or directly to build outputs. ''; }; @@ -75,7 +74,9 @@ in default = {}; example = { l = "less"; gco = "git checkout"; }; description = '' - Set of abbreviations for fish shell. + An attribute set that maps aliases (the top level attribute names + in this option) to abbreviations. Abbreviations are expanded with + the longer phrase after they are entered. ''; }; @@ -83,7 +84,8 @@ in type = types.lines; default = ""; description = '' - Shell script code called during fish shell initialisation. + Shell script code called during fish shell + initialisation. ''; }; @@ -91,7 +93,8 @@ in type = types.lines; default = ""; description = '' - Shell script code called during fish login shell initialisation. + Shell script code called during fish login shell + initialisation. ''; }; @@ -99,7 +102,8 @@ in type = types.lines; default = ""; description = '' - Shell script code called during interactive fish shell initialisation. + Shell script code called during interactive fish shell + initialisation. ''; }; From d45e1c4adc68dcda504cfc13ea894b308e552807 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Mon, 23 Sep 2019 22:00:23 -0700 Subject: [PATCH 06/21] fish: functions type to attrsOf lines, load by text Functions in fish are now defined in terms of adding the appropriate files and `files.text` sets to `xdg.configFile`. --- modules/programs/fish.nix | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index abc1bfea..9ae350c2 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -127,14 +127,12 @@ in }; programs.fish.functions = mkOption { - type = types.attrsOf (fileType (name: body: '' - function ${name} - ${body} - end - '')); + type = types.attrsOf types.lines; default = {}; + example = { gitignore = "curl -sL https://www.gitignore.io/api/$argv"; }; description = '' - Functions to add to fish. + Basic functions to add to fish. For more information see + . ''; }; @@ -253,7 +251,14 @@ in end ''; } { - xdg.configFile = map (n: { target = "fish/functions/${n}.fish"; source = cfg.functions.${n}.source; }) (attrNames cfg.functions); + xdg.configFile = mapAttrs' (f_name: f_body: { + name = "fish/functions/${f_name}.fish"; + value = {"text" = '' + function ${f_name} + ${f_body} + end + '';}; + }) cfg.functions; } ( let wrappedPkgVersion = lib.getVersion pkgs.fish; From 4833a8b532e92bad14f5e8867c27488e72eac955 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Mon, 23 Sep 2019 22:11:58 -0700 Subject: [PATCH 07/21] fish: add section headers to generated config The section headers help show where each section came from when looking at the generated config. Added a note about how the config was generated in the generated file. --- modules/programs/fish.nix | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 9ae350c2..50cee2c0 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -212,9 +212,12 @@ in ''; xdg.configFile."fish/config.fish".text = '' - # ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated automatically. + # ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated + # automatically by home-manager. + # if we haven't sourced the general config, do it if not set -q __fish_general_config_sourced + set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path fenv source ${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh > /dev/null set -e fish_function_path[1] @@ -223,31 +226,43 @@ in # and leave a note so we don't source this config section again from # this very shell (children will source the general config anew) set -g __fish_general_config_sourced 1 + end + # if we haven't sourced the login config, do it status --is-login; and not set -q __fish_login_config_sourced and begin + # Login shell initialisation ${cfg.loginShellInit} + # and leave a note so we don't source this config section again from # this very shell (children will source the general config anew) set -g __fish_login_config_sourced 1 + end + # if we haven't sourced the interactive config, do it status --is-interactive; and not set -q __fish_interactive_config_sourced and begin - # Abbrs + + # Abbreviations ${abbrsStr} # Aliases ${aliasesStr} + # Prompt initialisation ${cfg.promptInit} + + # Interactive shell intialisation ${cfg.interactiveShellInit} + # and leave a note so we don't source this config section again from # this very shell (children will source the general config anew, # allowing configuration changes in, e.g, aliases, to propagate) set -g __fish_interactive_config_sourced 1 + end ''; } { From 642bd6712640274a59b0a4ba882f46c4aee84e03 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Mon, 23 Sep 2019 22:13:02 -0700 Subject: [PATCH 08/21] fish: add comma to program slogan Matches what is on the fish website --- modules/programs/fish.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 50cee2c0..e528f500 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -48,7 +48,7 @@ in { options = { programs.fish = { - enable = mkEnableOption "fish friendly interactive shell"; + enable = mkEnableOption "fish, the friendly interactive shell"; package = mkOption { type = types.package; From 490f5fc5851bbed95a491b38e57890840ca64296 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Mon, 23 Sep 2019 22:07:51 -0700 Subject: [PATCH 09/21] fish: remove completions They are not currently handled in the code, hence they are removed for now. --- modules/programs/fish.nix | 7 ------- 1 file changed, 7 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index e528f500..3cfbfa4b 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -136,13 +136,6 @@ in ''; }; - programs.fish.completions = mkOption { - type = types.attrsOf (fileType (name: body: body)); - default = {}; - description = '' - Completions to add to fish. - ''; - }; }; config = mkIf cfg.enable (mkMerge [{ From 0740c257b11de90ba04860a04c80ddfd2d81f111 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Mon, 23 Sep 2019 22:14:32 -0700 Subject: [PATCH 10/21] fish: remove fileType function Replaced by types that are more common. This additionally reflects in the manpages, which should have types the reader is familiar with. --- modules/programs/fish.nix | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 3cfbfa4b..52ea9189 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -14,35 +14,6 @@ let mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases ); - fileType = textGen: types.submodule ( - { name, config, ... }: { - options = { - body = mkOption { - default = null; - type = types.nullOr types.lines; - description = "Body of the file."; - }; - - source = mkOption { - type = types.path; - description = '' - Path of the source file. The file name must not start - with a period. - ''; - }; - }; - - config = { - source = mkIf (config.body != null) ( - mkDefault (pkgs.writeTextFile { - inherit name; - text = textGen name config.body; - executable = true; - }) - ); - }; - } - ); in { From 4f532948f7d12d4f7c36817173c83be9138b7abd Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Mon, 23 Sep 2019 22:05:21 -0700 Subject: [PATCH 11/21] fish: shell{Abbrs,Aliases} has more specific type Converted attrs to attrsOf str. --- modules/programs/fish.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 52ea9189..57c6409f 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -31,7 +31,7 @@ in }; shellAliases = mkOption { - type = types.attrs; + type = with types; attrsOf str; default = {}; example = { ".." = "cd .."; ll = "ls -l"; }; description = '' @@ -41,7 +41,7 @@ in }; shellAbbrs = mkOption { - type = types.attrs; + type = with types; attrsOf str; default = {}; example = { l = "less"; gco = "git checkout"; }; description = '' From 2f51b9e418092d1866584547e5b83622b326b3dd Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Tue, 24 Sep 2019 01:16:49 -0700 Subject: [PATCH 12/21] fish: add pluginModule type Similar to zsh's `pluginModule` type, but without an initialization file. --- modules/programs/fish.nix | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 57c6409f..12f33304 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -6,6 +6,29 @@ let cfg = config.programs.fish; + pluginModule = types.submodule ({ config, ... }: { + options = { + src = mkOption { + type = types.path; + description = '' + Path to the plugin folder. + + Relevant pieces will be added to the fish function path and + the completion path. The init.fish and + key_binding.fish files are sourced if + they exist. + ''; + }; + + name = mkOption { + type = types.str; + description = '' + The name of the plugin. + ''; + }; + }; + }); + abbrsStr = concatStringsSep "\n" ( mapAttrsToList (k: v: "abbr --add --global ${k} '${v}'") cfg.shellAbbrs ); From 0522c7c1f6c57f3f4676a766de449a4b752145e0 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Tue, 24 Sep 2019 01:19:35 -0700 Subject: [PATCH 13/21] fish: plugins uses pluginModule type, add example --- modules/programs/fish.nix | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 12f33304..ca5f1108 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -111,12 +111,36 @@ in }; programs.fish.plugins = mkOption { - type = types.listOf types.package; + type = types.listOf pluginModule; default = []; + example = literalExample '' + [ + { + name = "z"; + src = pkgs.fetchFromGitHub { + owner = "jethrokuan"; + repo = "z"; + rev = "ddeb28a7b6a1f0ec6dae40c636e5ca4908ad160a"; + sha256 = "0c5i7sdrsp0q3vbziqzdyqn4fmp235ax4mn4zslrswvn8g3fvdyh"; + }; + } + + # oh-my-fish plugins are stored in their own repositories, which + # makes them simple to import into home-manager. + { + name = "fasd"; + src = pkgs.fetchFromGitHub { + owner = "oh-my-fish"; + repo = "plugin-fasd"; + rev = "38a5b6b6011106092009549e52249c6d6f501fba"; + sha256 = "06v37hqy5yrv5a6ssd1p3cjd9y3hnp19d3ab7dag56fs1qmgyhbs"; + }; + } + ] + ''; description = '' - The plugins to add to fish. - Built with buildFishPlugin. - Overrides manually installed ones. + The plugins to source in + conf.d/99plugins.fish. ''; }; From f5b24635b6a7670c83455374589f0570d82a5357 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Tue, 24 Sep 2019 01:20:44 -0700 Subject: [PATCH 14/21] fish: whitespace and style fixes (camel case) --- modules/programs/fish.nix | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index ca5f1108..a3aafa65 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -157,6 +157,7 @@ in }; config = mkIf cfg.enable (mkMerge [{ + home.packages = [ cfg.package ]; xdg.dataFile."fish/home-manager_generated_completions".source = @@ -276,12 +277,14 @@ in end ''; + } { - xdg.configFile = mapAttrs' (f_name: f_body: { - name = "fish/functions/${f_name}.fish"; + + xdg.configFile = mapAttrs' (fName: fBody: { + name = "fish/functions/${fName}.fish"; value = {"text" = '' - function ${f_name} - ${f_body} + function ${fName} + ${fBody} end '';}; }) cfg.functions; From 639f6fea8c7dc0f10b068b7edcb5f75f2e95a892 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Tue, 24 Sep 2019 01:21:34 -0700 Subject: [PATCH 15/21] fish: plugins concated to 99plugins.fish This change allows the entire repo to be imported directly. Some plugins (such as oh-my-fish's vi-mode) have extra files that are referenced by the plugin itself. This means we cannot create a generic plugin file structure out of the plugins that exist currently. --- modules/programs/fish.nix | 55 +++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index a3aafa65..0d0364b7 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -288,32 +288,37 @@ in end '';}; }) cfg.functions; - } ( - let - wrappedPkgVersion = lib.getVersion pkgs.fish; - wrappedPkgName = lib.removeSuffix "-${wrappedPkgVersion}" pkgs.fish.name; - dependencies = concatMap (p: p.dependencies) cfg.plugins; - combinedPluginDrv = pkgs.buildEnv { - name = "${wrappedPkgName}-plugins-${wrappedPkgVersion}"; - paths = cfg.plugins; - postBuild = '' - touch $out/setup.fish - if [ -d $out/functions ]; then - echo "set fish_function_path \$fish_function_path[1] $out/functions \$fish_function_path[2..-1]" >> $out/setup.fish - fi + } - if [ -d $out/completions ]; then - echo "set fish_complete_path \$fish_complete_path[1] $out/completions \$fish_complete_path[2..-1]" >> $out/setup.fish - fi + # Plugins are all sources together in a conf.d file as this allows + # the original source to be undisturbed. + (mkIf (length cfg.plugins > 0) { + xdg.configFile."fish/conf.d/99plugins.fish".text = concatStrings + (map (plugin: '' + # Plugin ${plugin.name} + if test -d ${plugin.src}/functions + set fish_function_path $fish_function_path[1] ${plugin.src}/functions $fish_function_path[2..-1] + end - if [ -d $out/conf.d ]; then - echo "source $out/conf.d/*.fish" >> $out/setup.fish - fi - ''; - }; - in mkIf (length cfg.plugins > 0) { - xdg.configFile."fish/conf.d/99plugins.fish".source = "${combinedPluginDrv}/setup.fish"; - home.packages = dependencies; - })]); + if test -d ${plugin.src}/completions + set fish_complete_path $fish_function_path[1] ${plugin.src}/completions $fish_complete_path[2..-1] + end + + if test -d ${plugin.src}/conf.d + source ${plugin.src}/conf.d/*.fish + end + + if test -f ${plugin.src}/key_bindings.fish + source ${plugin.src}/key_bindings.fish + end + + if test -f ${plugin.src}/init.fish + source ${plugin.src}/init.fish + end + + '' + ) cfg.plugins); + }) + ]); } From 108259925a68a4c8c36e3fdf43c39a6ae55b11a7 Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Tue, 24 Sep 2019 23:20:53 -0700 Subject: [PATCH 16/21] fish: plugins separated into conf.d files This was done to make it easier for the generated files to be understood. --- modules/programs/fish.nix | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 0d0364b7..a45b0e2f 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -291,34 +291,37 @@ in } - # Plugins are all sources together in a conf.d file as this allows - # the original source to be undisturbed. + # Each plugin gets a corresponding conf.d/plugin-NAME.fish file to load + # in the paths and any initialization scripts. (mkIf (length cfg.plugins > 0) { - xdg.configFile."fish/conf.d/99plugins.fish".text = concatStrings - (map (plugin: '' + xdg.configFile = mkMerge ( + (map (plugin: { "fish/conf.d/plugin-${plugin.name}.fish".text = '' # Plugin ${plugin.name} - if test -d ${plugin.src}/functions - set fish_function_path $fish_function_path[1] ${plugin.src}/functions $fish_function_path[2..-1] + set -l plugin_dir ${plugin.src} + + # Set paths to import plugin components + if test -d $plugin_dir"/functions" + set fish_function_path $fish_function_path[1] $plugin_dir"/functions" $fish_function_path[2..-1] end - if test -d ${plugin.src}/completions - set fish_complete_path $fish_function_path[1] ${plugin.src}/completions $fish_complete_path[2..-1] + if test -d $plugin_dir"/completions" + set fish_complete_path $fish_function_path[1] $plugin_dir"/completions" $fish_complete_path[2..-1] end - if test -d ${plugin.src}/conf.d - source ${plugin.src}/conf.d/*.fish + # Source initialization code if it exists. + if test -d $plugin_dir"/conf.d" + source $plugin_dir"/conf.d/*.fish" end - if test -f ${plugin.src}/key_bindings.fish - source ${plugin.src}/key_bindings.fish + if test -f $plugin_dir"/key_bindings.fish" + source $plugin_dir"/key_bindings.fish" end - if test -f ${plugin.src}/init.fish - source ${plugin.src}/init.fish + if test -f $plugin_dir"/init.fish" + source $plugin_dir"/init.fish" end - - '' - ) cfg.plugins); + ''; + }) cfg.plugins)); }) ]); } From 111011b2c29243a41363e9f71ce29c93cd74c20f Mon Sep 17 00:00:00 2001 From: Ryan Orendorff Date: Mon, 30 Sep 2019 00:11:36 -0700 Subject: [PATCH 17/21] fish: add some tests - If a function is defined, check that the function file exists and that the contents matches a given string. - If no functions exists, the functions folder should not exist. - Verify plugin functionality. --- tests/default.nix | 1 + tests/modules/programs/fish/default.nix | 5 ++ tests/modules/programs/fish/functions.nix | 32 +++++++++++ tests/modules/programs/fish/no-functions.nix | 22 ++++++++ tests/modules/programs/fish/plugins.nix | 58 ++++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 tests/modules/programs/fish/default.nix create mode 100644 tests/modules/programs/fish/functions.nix create mode 100644 tests/modules/programs/fish/no-functions.nix create mode 100644 tests/modules/programs/fish/plugins.nix diff --git a/tests/default.nix b/tests/default.nix index 49c27239..df69dc22 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -29,6 +29,7 @@ import nmt { ./modules/programs/alacritty ./modules/programs/bash ./modules/programs/browserpass + ./modules/programs/fish ./modules/programs/git ./modules/programs/gpg ./modules/programs/mbsync diff --git a/tests/modules/programs/fish/default.nix b/tests/modules/programs/fish/default.nix new file mode 100644 index 00000000..99fe8136 --- /dev/null +++ b/tests/modules/programs/fish/default.nix @@ -0,0 +1,5 @@ +{ + fish-functions = ./functions.nix; + fish-no-functions = ./no-functions.nix; + fish-plugins = ./plugins.nix; +} diff --git a/tests/modules/programs/fish/functions.nix b/tests/modules/programs/fish/functions.nix new file mode 100644 index 00000000..b939a208 --- /dev/null +++ b/tests/modules/programs/fish/functions.nix @@ -0,0 +1,32 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + func = pkgs.writeText "func.fish" '' + function func + echo "Hello" + end + ''; + +in { + config = { + programs.fish = { + enable = true; + + functions = { func = ''echo "Hello"''; }; + }; + + nmt = { + description = + "if fish.function is set, check file exists and contents match"; + script = '' + assertFileExists home-files/.config/fish/functions/func.fish + echo ${func} + assertFileContent home-files/.config/fish/functions/func.fish ${func} + ''; + + }; + }; +} diff --git a/tests/modules/programs/fish/no-functions.nix b/tests/modules/programs/fish/no-functions.nix new file mode 100644 index 00000000..c817b388 --- /dev/null +++ b/tests/modules/programs/fish/no-functions.nix @@ -0,0 +1,22 @@ +{ config, lib, ... }: + +with lib; + +{ + config = { + programs.fish = { + enable = true; + + functions = { }; + }; + + nmt = { + description = + "if fish.functions is blank, the functions folder should not exist."; + script = '' + assertPathNotExists home-files/.config/fish/functions + ''; + + }; + }; +} diff --git a/tests/modules/programs/fish/plugins.nix b/tests/modules/programs/fish/plugins.nix new file mode 100644 index 00000000..cd675f8b --- /dev/null +++ b/tests/modules/programs/fish/plugins.nix @@ -0,0 +1,58 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + fooPluginSrc = pkgs.writeText "fooPluginSrc" ""; + + generatedConfdFile = pkgs.writeText "plugin-foo.fish" '' + # Plugin foo + set -l plugin_dir ${fooPluginSrc} + + # Set paths to import plugin components + if test -d $plugin_dir"/functions" + set fish_function_path $fish_function_path[1] $plugin_dir"/functions" $fish_function_path[2..-1] + end + + if test -d $plugin_dir"/completions" + set fish_complete_path $fish_function_path[1] $plugin_dir"/completions" $fish_complete_path[2..-1] + end + + # Source initialization code if it exists. + if test -d $plugin_dir"/conf.d" + source $plugin_dir"/conf.d/*.fish" + end + + if test -f $plugin_dir"/key_bindings.fish" + source $plugin_dir"/key_bindings.fish" + end + + if test -f $plugin_dir"/init.fish" + source $plugin_dir"/init.fish" + end + ''; + +in { + config = { + programs.fish = { + enable = true; + + plugins = [{ + name = "foo"; + src = fooPluginSrc; + }]; + }; + + nmt = { + description = + "if fish.plugins set, check conf.d file exists and contents match"; + script = '' + assertDirectoryExists home-files/.config/fish/conf.d + assertFileExists home-files/.config/fish/conf.d/plugin-foo.fish + assertFileContent home-files/.config/fish/conf.d/plugin-foo.fish ${generatedConfdFile} + ''; + + }; + }; +} From 9a258edc107f127a256fbfb2451bf779fa74f054 Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Fri, 7 Feb 2020 16:15:11 -0800 Subject: [PATCH 18/21] fish: fix sourcing of .fish files Turns out, the quotes were messing things up. --- modules/programs/fish.nix | 2 +- tests/modules/programs/fish/plugins.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index a45b0e2f..476e9c09 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -310,7 +310,7 @@ in # Source initialization code if it exists. if test -d $plugin_dir"/conf.d" - source $plugin_dir"/conf.d/*.fish" + source $plugin_dir/conf.d/*.fish end if test -f $plugin_dir"/key_bindings.fish" diff --git a/tests/modules/programs/fish/plugins.nix b/tests/modules/programs/fish/plugins.nix index cd675f8b..845ccb11 100644 --- a/tests/modules/programs/fish/plugins.nix +++ b/tests/modules/programs/fish/plugins.nix @@ -21,7 +21,7 @@ let # Source initialization code if it exists. if test -d $plugin_dir"/conf.d" - source $plugin_dir"/conf.d/*.fish" + source $plugin_dir/conf.d/*.fish end if test -f $plugin_dir"/key_bindings.fish" From a08dabf015081666f50ad1538f85d69e2217585e Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Fri, 14 Feb 2020 13:36:44 -0800 Subject: [PATCH 19/21] fish: escape abbrs and aliases Some of my aliases have apostrophes in them, so shell-escaping them is a must. --- modules/programs/fish.nix | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 476e9c09..dd58abca 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -29,13 +29,12 @@ let }; }); - abbrsStr = concatStringsSep "\n" ( - mapAttrsToList (k: v: "abbr --add --global ${k} '${v}'") cfg.shellAbbrs - ); + abbrsStr = concatStringsSep "\n" + (mapAttrsToList (k: v: "abbr --add --global -- ${k} ${escapeShellArg v}") + cfg.shellAbbrs); - aliasesStr = concatStringsSep "\n" ( - mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases - ); + aliasesStr = concatStringsSep "\n" + (mapAttrsToList (k: v: "alias ${k} ${escapeShellArg v}") cfg.shellAliases); in From 89239d554d3d1cdf3c865449c75c3bbdbaaf45f1 Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Fri, 14 Feb 2020 14:25:45 -0800 Subject: [PATCH 20/21] fish: prepend fenv functions dir Instead of concatenating the `fish_function_path` with the fenv functions path, just prepend it. Functionally the same, but looks cleaner (IMO). --- modules/programs/fish.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index dd58abca..8e323f2a 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -229,7 +229,7 @@ in # if we haven't sourced the general config, do it if not set -q __fish_general_config_sourced - set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path + set -p fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions fenv source ${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh > /dev/null set -e fish_function_path[1] From 5ca224f75b9b83b5b0886fae73a9320aedbbbce1 Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Sat, 15 Feb 2020 09:10:11 -0800 Subject: [PATCH 21/21] fish: consistency is key and other style changes I like my empty sets with spaces between them. --- modules/programs/fish.nix | 31 ++++++++++++++----------- tests/modules/programs/fish/plugins.nix | 18 +++++++------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 8e323f2a..38a51c74 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -54,7 +54,7 @@ in shellAliases = mkOption { type = with types; attrsOf str; - default = {}; + default = { }; example = { ".." = "cd .."; ll = "ls -l"; }; description = '' An attribute set that maps aliases (the top level attribute names @@ -64,8 +64,11 @@ in shellAbbrs = mkOption { type = with types; attrsOf str; - default = {}; - example = { l = "less"; gco = "git checkout"; }; + default = { }; + example = { + l = "less"; + gco = "git checkout"; + }; description = '' An attribute set that maps aliases (the top level attribute names in this option) to abbreviations. Abbreviations are expanded with @@ -111,7 +114,7 @@ in programs.fish.plugins = mkOption { type = types.listOf pluginModule; - default = []; + default = [ ]; example = literalExample '' [ { @@ -145,7 +148,7 @@ in programs.fish.functions = mkOption { type = types.attrsOf types.lines; - default = {}; + default = { }; example = { gitignore = "curl -sL https://www.gitignore.io/api/$argv"; }; description = '' Basic functions to add to fish. For more information see @@ -299,25 +302,25 @@ in set -l plugin_dir ${plugin.src} # Set paths to import plugin components - if test -d $plugin_dir"/functions" - set fish_function_path $fish_function_path[1] $plugin_dir"/functions" $fish_function_path[2..-1] + if test -d $plugin_dir/functions + set fish_function_path $fish_function_path[1] $plugin_dir/functions $fish_function_path[2..-1] end - if test -d $plugin_dir"/completions" - set fish_complete_path $fish_function_path[1] $plugin_dir"/completions" $fish_complete_path[2..-1] + if test -d $plugin_dir/completions + set fish_complete_path $fish_function_path[1] $plugin_dir/completions $fish_complete_path[2..-1] end # Source initialization code if it exists. - if test -d $plugin_dir"/conf.d" + if test -d $plugin_dir/conf.d source $plugin_dir/conf.d/*.fish end - if test -f $plugin_dir"/key_bindings.fish" - source $plugin_dir"/key_bindings.fish" + if test -f $plugin_dir/key_bindings.fish + source $plugin_dir/key_bindings.fish end - if test -f $plugin_dir"/init.fish" - source $plugin_dir"/init.fish" + if test -f $plugin_dir/init.fish + source $plugin_dir/init.fish end ''; }) cfg.plugins)); diff --git a/tests/modules/programs/fish/plugins.nix b/tests/modules/programs/fish/plugins.nix index 845ccb11..cb7d7104 100644 --- a/tests/modules/programs/fish/plugins.nix +++ b/tests/modules/programs/fish/plugins.nix @@ -11,25 +11,25 @@ let set -l plugin_dir ${fooPluginSrc} # Set paths to import plugin components - if test -d $plugin_dir"/functions" - set fish_function_path $fish_function_path[1] $plugin_dir"/functions" $fish_function_path[2..-1] + if test -d $plugin_dir/functions + set fish_function_path $fish_function_path[1] $plugin_dir/functions $fish_function_path[2..-1] end - if test -d $plugin_dir"/completions" - set fish_complete_path $fish_function_path[1] $plugin_dir"/completions" $fish_complete_path[2..-1] + if test -d $plugin_dir/completions + set fish_complete_path $fish_function_path[1] $plugin_dir/completions $fish_complete_path[2..-1] end # Source initialization code if it exists. - if test -d $plugin_dir"/conf.d" + if test -d $plugin_dir/conf.d source $plugin_dir/conf.d/*.fish end - if test -f $plugin_dir"/key_bindings.fish" - source $plugin_dir"/key_bindings.fish" + if test -f $plugin_dir/key_bindings.fish + source $plugin_dir/key_bindings.fish end - if test -f $plugin_dir"/init.fish" - source $plugin_dir"/init.fish" + if test -f $plugin_dir/init.fish + source $plugin_dir/init.fish end '';