diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d13da75c..5fe2ec95 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -85,6 +85,8 @@ /modules/programs/pidgin.nix @rycee +/modules/programs/powerline-go.nix @DamienCassou + /modules/programs/rtorrent.nix @marsam /modules/programs/ssh.nix @rycee diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 819afdd4..b0cdb0bd 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1560,6 +1560,14 @@ in A new module is available: 'services.clipmenu' ''; } + + { + time = "2020-06-12T07:08:09+00:00"; + condition = config.programs.bash.enable; + message = '' + A new module is available: 'programs.powerline-go' + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index c89f4d50..ae09e39f 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -99,6 +99,7 @@ let (loadModule ./programs/password-store.nix { }) (loadModule ./programs/pazi.nix { }) (loadModule ./programs/pidgin.nix { }) + (loadModule ./programs/powerline-go.nix { }) (loadModule ./programs/qutebrowser.nix { }) (loadModule ./programs/readline.nix { }) (loadModule ./programs/rofi.nix { }) diff --git a/modules/programs/powerline-go.nix b/modules/programs/powerline-go.nix new file mode 100644 index 00000000..0727a69c --- /dev/null +++ b/modules/programs/powerline-go.nix @@ -0,0 +1,123 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.powerline-go; + + # Convert an option value to a string to be passed as argument to + # powerline-go: + valueToString = value: + if builtins.isList value then + builtins.concatStringsSep "," (builtins.map valueToString value) + else if builtins.isAttrs value then + valueToString + (mapAttrsToList (key: val: "${valueToString key}=${valueToString val}") + value) + else + builtins.toString value; + + modulesArgument = optionalString (cfg.modules != null) + "-modules ${valueToString cfg.modules}"; + + newlineArgument = optionalString cfg.newline "-newline"; + + pathAliasesArgument = optionalString (cfg.pathAliases != null) + "-path-aliases ${valueToString cfg.pathAliases}"; + + otherSettingPairArgument = name: value: + if value == true then "-${name}" else "-${name} ${valueToString value}"; + + otherSettingsArgument = optionalString (cfg.settings != { }) + (concatStringsSep " " + (mapAttrsToList otherSettingPairArgument cfg.settings)); + + commandLineArguments = '' + ${modulesArgument} ${newlineArgument} ${pathAliasesArgument} ${otherSettingsArgument} + ''; + +in { + meta.maintainers = [ maintainers.DamienCassou ]; + + options = { + programs.powerline-go = { + enable = mkEnableOption + "Powerline-go, a beautiful and useful low-latency prompt for your shell"; + + modules = mkOption { + default = null; + type = types.nullOr (types.listOf types.str); + description = '' + List of module names to load. The list of all available + modules as well as the choice of default ones are at + . + ''; + example = [ "host" "ssh" "cwd" "gitlite" "jobs" "exit" ]; + }; + + newline = mkOption { + default = false; + type = types.bool; + description = '' + Set to true if the prompt should be on a line of its own. + ''; + example = true; + }; + + pathAliases = mkOption { + default = null; + type = types.nullOr (types.attrsOf types.str); + description = '' + Pairs of full-path and corresponding desired short name. You + may use '~' to represent your home directory but you should + protect it to avoid shell substitution. + ''; + example = literalExample '' + { "\\~/projects/home-manager" = "prj:home-manager"; } + ''; + }; + + settings = mkOption { + default = { }; + type = with types; attrsOf (oneOf [ bool int str (listOf str) ]); + description = '' + This can be any key/value pair as described in + . + ''; + example = literalExample '' + { + hostname-only-if-ssh = true; + numeric-exit-codes = true; + cwd-max-depth = 7; + ignore-repos = [ "/home/me/big-project" "/home/me/huge-project" ]; + } + ''; + }; + + extraUpdatePS1 = mkOption { + default = ""; + description = "Shell code to execute after the prompt is set."; + example = '' + PS1=$PS1"NixOS> "; + ''; + type = types.str; + }; + }; + }; + + config = mkIf (cfg.enable && config.programs.bash.enable) { + programs.bash.initExtra = '' + function _update_ps1() { + local old_exit_status=$? + PS1="$(${pkgs.powerline-go}/bin/powerline-go -error $? ${commandLineArguments})" + ${cfg.extraUpdatePS1} + return $old_exit_status + } + + if [ "$TERM" != "linux" ]; then + PROMPT_COMMAND="_update_ps1;$PROMPT_COMMAND" + fi + ''; + }; +} diff --git a/tests/default.nix b/tests/default.nix index af915992..6cc79413 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -57,6 +57,7 @@ import nmt { ./modules/programs/newsboat ./modules/programs/qutebrowser ./modules/programs/readline + ./modules/programs/powerline-go ./modules/programs/ssh ./modules/programs/starship ./modules/programs/texlive diff --git a/tests/modules/programs/powerline-go/default.nix b/tests/modules/programs/powerline-go/default.nix new file mode 100644 index 00000000..50febefb --- /dev/null +++ b/tests/modules/programs/powerline-go/default.nix @@ -0,0 +1 @@ +{ powerline-go-standard = ./standard.nix; } diff --git a/tests/modules/programs/powerline-go/standard.nix b/tests/modules/programs/powerline-go/standard.nix new file mode 100644 index 00000000..9788ce7d --- /dev/null +++ b/tests/modules/programs/powerline-go/standard.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs = { + bash.enable = true; + + powerline-go = { + enable = true; + newline = true; + modules = [ "nix-shell" ]; + pathAliases = { "\\~/project/foo" = "prj-foo"; }; + settings = { + ignore-repos = [ "/home/me/project1" "/home/me/project2" ]; + }; + }; + }; + + nmt.script = '' + assertFileExists home-files/.bashrc + assertFileContains \ + home-files/.bashrc \ + '/bin/powerline-go -error $? -modules nix-shell -newline -path-aliases \~/project/foo=prj-foo -ignore-repos /home/me/project1,/home/me/project2' + ''; + }; +}