2021-10-06 01:14:52 +02:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
cfg = config.programs.nnn;
|
|
|
|
|
|
|
|
renderSetting = key: value: "${key}:${value}";
|
|
|
|
|
|
|
|
renderSettings = settings:
|
|
|
|
concatStringsSep ";" (mapAttrsToList renderSetting settings);
|
|
|
|
|
|
|
|
pluginModule = types.submodule ({ ... }: {
|
|
|
|
options = {
|
|
|
|
src = mkOption {
|
|
|
|
type = with types; nullOr path;
|
2021-10-09 11:14:08 +02:00
|
|
|
example = literalExpression ''
|
2021-10-06 01:14:52 +02:00
|
|
|
(pkgs.fetchFromGitHub {
|
|
|
|
owner = "jarun";
|
|
|
|
repo = "nnn";
|
|
|
|
rev = "v4.0";
|
|
|
|
sha256 = "sha256-Hpc8YaJeAzJoEi7aJ6DntH2VLkoR6ToP6tPYn3llR7k=";
|
|
|
|
}) + "/plugins";
|
|
|
|
'';
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2021-10-06 01:14:52 +02:00
|
|
|
Path to the plugin folder.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
mappings = mkOption {
|
|
|
|
type = with types; attrsOf str;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2021-10-06 01:14:52 +02:00
|
|
|
Key mappings to the plugins.
|
|
|
|
'';
|
|
|
|
default = { };
|
2021-10-09 11:14:08 +02:00
|
|
|
example = literalExpression ''
|
2021-10-06 01:14:52 +02:00
|
|
|
{
|
|
|
|
c = "fzcd";
|
|
|
|
f = "finder";
|
|
|
|
v = "imgview";
|
|
|
|
};
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
});
|
|
|
|
in {
|
|
|
|
meta.maintainers = with maintainers; [ thiagokokada ];
|
|
|
|
|
|
|
|
options = {
|
|
|
|
programs.nnn = {
|
2023-07-02 01:45:18 +02:00
|
|
|
enable = mkEnableOption "nnn";
|
2021-10-06 01:14:52 +02:00
|
|
|
|
|
|
|
package = mkOption {
|
|
|
|
type = types.package;
|
|
|
|
default = pkgs.nnn;
|
2021-10-09 11:14:08 +02:00
|
|
|
defaultText = literalExpression "pkgs.nnn";
|
2021-10-06 01:14:52 +02:00
|
|
|
example =
|
2021-10-09 11:14:08 +02:00
|
|
|
literalExpression "pkgs.nnn.override ({ withNerdIcons = true; });";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 01:30:13 +02:00
|
|
|
Package containing the {command}`nnn` program.
|
2021-10-06 01:14:52 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
finalPackage = mkOption {
|
|
|
|
type = types.package;
|
|
|
|
readOnly = true;
|
|
|
|
visible = false;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2021-10-06 01:14:52 +02:00
|
|
|
Resulting nnn package.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
bookmarks = mkOption {
|
|
|
|
type = with types; attrsOf str;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2021-10-06 01:14:52 +02:00
|
|
|
Directory bookmarks.
|
|
|
|
'';
|
2021-10-09 11:14:08 +02:00
|
|
|
example = literalExpression ''
|
2021-10-06 01:14:52 +02:00
|
|
|
{
|
|
|
|
d = "~/Documents";
|
|
|
|
D = "~/Downloads";
|
|
|
|
p = "~/Pictures";
|
|
|
|
v = "~/Videos";
|
|
|
|
};
|
|
|
|
'';
|
|
|
|
default = { };
|
|
|
|
};
|
|
|
|
|
|
|
|
extraPackages = mkOption {
|
|
|
|
type = with types; listOf package;
|
|
|
|
example =
|
2021-10-09 11:14:08 +02:00
|
|
|
literalExpression "with pkgs; [ ffmpegthumbnailer mediainfo sxiv ]";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2021-10-06 01:14:52 +02:00
|
|
|
Extra packages available to nnn.
|
|
|
|
'';
|
|
|
|
default = [ ];
|
|
|
|
};
|
|
|
|
|
|
|
|
plugins = mkOption {
|
|
|
|
type = pluginModule;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2021-10-06 01:14:52 +02:00
|
|
|
Manage nnn plugins.
|
|
|
|
'';
|
|
|
|
default = { };
|
|
|
|
};
|
2024-07-15 17:21:46 +02:00
|
|
|
|
|
|
|
enableBashIntegration = mkOption {
|
|
|
|
default = true;
|
|
|
|
type = types.bool;
|
|
|
|
description = ''
|
|
|
|
Whether to enable Bash integration.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
enableZshIntegration = mkOption {
|
|
|
|
default = true;
|
|
|
|
type = types.bool;
|
|
|
|
description = ''
|
|
|
|
Whether to enable Zsh integration.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
enableFishIntegration = mkOption {
|
|
|
|
default = true;
|
|
|
|
type = types.bool;
|
|
|
|
description = ''
|
|
|
|
Whether to enable Fish integration.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
enableNushellIntegration = mkOption {
|
|
|
|
default = true;
|
|
|
|
type = types.bool;
|
|
|
|
description = ''
|
|
|
|
Whether to enable Nushell integration.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
quitcd = mkOption {
|
|
|
|
default = false;
|
|
|
|
type = types.bool;
|
|
|
|
description = ''
|
|
|
|
Whether to enable cd on quit.
|
|
|
|
'';
|
|
|
|
};
|
2021-10-06 01:14:52 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = let
|
|
|
|
nnnPackage = cfg.package.overrideAttrs (oldAttrs: {
|
|
|
|
nativeBuildInputs = (oldAttrs.nativeBuildInputs or [ ])
|
|
|
|
++ [ pkgs.makeWrapper ];
|
|
|
|
postInstall = ''
|
|
|
|
${oldAttrs.postInstall or ""}
|
|
|
|
|
|
|
|
wrapProgram $out/bin/nnn \
|
|
|
|
--prefix PATH : "${makeBinPath cfg.extraPackages}" \
|
|
|
|
--prefix NNN_BMS : "${renderSettings cfg.bookmarks}" \
|
|
|
|
--prefix NNN_PLUG : "${renderSettings cfg.plugins.mappings}"
|
|
|
|
'';
|
|
|
|
});
|
2024-07-15 17:21:46 +02:00
|
|
|
|
|
|
|
quitcd = {
|
|
|
|
bash_sh_zsh = ''
|
|
|
|
n ()
|
|
|
|
{
|
|
|
|
# Block nesting of nnn in subshells
|
|
|
|
[ "''${NNNLVL:-0}" -eq 0 ] || {
|
|
|
|
echo "nnn is already running"
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
# The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
|
|
|
|
# If NNN_TMPFILE is set to a custom path, it must be exported for nnn to
|
|
|
|
# see. To cd on quit only on ^G, remove the "export" and make sure not to
|
|
|
|
# use a custom path, i.e. set NNN_TMPFILE *exactly* as follows:
|
|
|
|
# NNN_TMPFILE="''${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
|
|
|
|
export NNN_TMPFILE="''${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
|
|
|
|
|
|
|
|
# Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
|
|
|
|
# stty start undef
|
|
|
|
# stty stop undef
|
|
|
|
# stty lwrap undef
|
|
|
|
# stty lnext undef
|
|
|
|
|
|
|
|
# The command builtin allows one to alias nnn to n, if desired, without
|
|
|
|
# making an infinitely recursive alias
|
|
|
|
command nnn "$@"
|
|
|
|
|
|
|
|
[ ! -f "$NNN_TMPFILE" ] || {
|
|
|
|
. "$NNN_TMPFILE"
|
|
|
|
rm -f -- "$NNN_TMPFILE" > /dev/null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
fish = ''
|
|
|
|
function n --wraps nnn --description 'support nnn quit and change directory'
|
|
|
|
# Block nesting of nnn in subshells
|
|
|
|
if test -n "$NNNLVL" -a "$NNNLVL" -ge 1
|
|
|
|
echo "nnn is already running"
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
# The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
|
|
|
|
# If NNN_TMPFILE is set to a custom path, it must be exported for nnn to
|
|
|
|
# see. To cd on quit only on ^G, remove the "-x" from both lines below,
|
|
|
|
# without changing the paths.
|
|
|
|
if test -n "$XDG_CONFIG_HOME"
|
|
|
|
set -x NNN_TMPFILE "$XDG_CONFIG_HOME/nnn/.lastd"
|
|
|
|
else
|
|
|
|
set -x NNN_TMPFILE "$HOME/.config/nnn/.lastd"
|
|
|
|
end
|
|
|
|
|
|
|
|
# Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
|
|
|
|
# stty start undef
|
|
|
|
# stty stop undef
|
|
|
|
# stty lwrap undef
|
|
|
|
# stty lnext undef
|
|
|
|
|
|
|
|
# The command function allows one to alias this function to `nnn` without
|
|
|
|
# making an infinitely recursive alias
|
|
|
|
command nnn $argv
|
|
|
|
|
|
|
|
if test -e $NNN_TMPFILE
|
|
|
|
source $NNN_TMPFILE
|
|
|
|
rm -- $NNN_TMPFILE
|
|
|
|
end
|
|
|
|
end'';
|
|
|
|
nu = ''
|
|
|
|
# Run nnn with dynamic changing directory to the environment.
|
|
|
|
#
|
|
|
|
# $env.XDG_CONFIG_HOME sets the home folder for `nnn` folder and its $env.NNN_TMPFILE variable.
|
|
|
|
# See manual NNN(1) for more information.
|
|
|
|
#
|
|
|
|
# Import module using `use quitcd.nu n` to have `n` command in your context.
|
|
|
|
export def --env n [
|
|
|
|
...args : string # Extra flags to launch nnn with.
|
|
|
|
--selective = false # Change directory only when exiting via ^G.
|
|
|
|
] -> nothing {
|
|
|
|
|
|
|
|
# The behaviour is set to cd on quit (nnn checks if $env.NNN_TMPFILE is set).
|
|
|
|
# Hard-coded to its respective behaviour in `nnn` source-code.
|
|
|
|
let nnn_tmpfile = $env
|
|
|
|
| default '~/.config/' 'XDG_CONFIG_HOME'
|
|
|
|
| get 'XDG_CONFIG_HOME'
|
|
|
|
| path join 'nnn/.lastd'
|
|
|
|
| path expand
|
|
|
|
|
|
|
|
# Launch nnn. Add desired flags after `^nnn`, ex: `^nnn -eda ...$args`,
|
|
|
|
# or make an alias `alias n = n -eda`.
|
|
|
|
if $selective {
|
|
|
|
^nnn ...$args
|
|
|
|
} else {
|
|
|
|
NNN_TMPFILE=$nnn_tmpfile ^nnn ...$args
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($nnn_tmpfile | path exists) {
|
|
|
|
# Remove <cd '> from the first part of the string and the last single quote <'>.
|
|
|
|
# Fix post-processing of nnn's given path that escapes its single quotes with POSIX syntax.
|
|
|
|
let path = open $nnn_tmpfile
|
|
|
|
| str replace --all --regex `^cd '|'$` ``
|
|
|
|
| str replace --all `'\''''` `'`
|
|
|
|
|
|
|
|
^rm -- $nnn_tmpfile
|
|
|
|
|
|
|
|
cd $path
|
|
|
|
}
|
|
|
|
}'';
|
|
|
|
};
|
2021-10-06 01:14:52 +02:00
|
|
|
in mkIf cfg.enable {
|
|
|
|
programs.nnn.finalPackage = nnnPackage;
|
|
|
|
home.packages = [ nnnPackage ];
|
|
|
|
xdg.configFile."nnn/plugins" =
|
|
|
|
mkIf (cfg.plugins.src != null) { source = cfg.plugins.src; };
|
2024-07-15 17:21:46 +02:00
|
|
|
|
|
|
|
programs.bash.initExtra =
|
|
|
|
mkIf cfg.enableBashIntegration (mkAfter quitcd.bash_sh_zsh);
|
|
|
|
programs.zsh.initExtra =
|
|
|
|
mkIf cfg.enableZshIntegration (mkAfter quitcd.bash_sh_zsh);
|
|
|
|
programs.fish.interactiveShellInit =
|
|
|
|
mkIf cfg.enableFishIntegration (mkAfter quitcd.fish);
|
|
|
|
programs.nushell.extraConfig =
|
|
|
|
mkIf cfg.enableNushellIntegration (mkAfter quitcd.nu);
|
2021-10-06 01:14:52 +02:00
|
|
|
};
|
|
|
|
}
|